Propagating prior merge from 'llvm.org/release_40'.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ff1ff21..7333a2e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -185,6 +185,8 @@
   set(CLANG_HAVE_LIBXML 1)
 endif()
 
+find_package(Z3 4.5)
+
 include(CheckIncludeFile)
 check_include_file(sys/resource.h CLANG_HAVE_RLIMITS)
 
@@ -329,10 +331,6 @@
   endif()
 endif()
 
-configure_file(
-  ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake
-  ${CLANG_BINARY_DIR}/include/clang/Config/config.h)
-
 include(CMakeParseArguments)
 include(AddClang)
 
@@ -381,8 +379,19 @@
   set(ENABLE_CLANG_STATIC_ANALYZER "0")
 endif()
 
-if (NOT CLANG_ENABLE_STATIC_ANALYZER AND CLANG_ENABLE_ARCMT)
-  message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT")
+option(CLANG_ANALYZER_BUILD_Z3
+  "Build the static analyzer with the Z3 constraint manager." OFF)
+
+if(NOT CLANG_ENABLE_STATIC_ANALYZER AND (CLANG_ENABLE_ARCMT OR CLANG_ANALYZER_BUILD_Z3))
+  message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT or Z3")
+endif()
+
+if(CLANG_ANALYZER_BUILD_Z3)
+  if(Z3_FOUND)
+    set(CLANG_ANALYZER_WITH_Z3 1)
+  else()
+    message(FATAL_ERROR "Cannot find Z3 header file or shared library")
+  endif()
 endif()
 
 if(CLANG_ENABLE_ARCMT)
@@ -700,3 +709,7 @@
 if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION)
   add_subdirectory(utils/ClangVisualizers)
 endif()
+
+configure_file(
+  ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake
+  ${CLANG_BINARY_DIR}/include/clang/Config/config.h)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..a0c1644
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,14 @@
+By submitting a pull request, you represent that you have the right to license
+your contribution to Apple and the community, and agree by submitting the patch
+that your contributions are licensed under the [Swift
+license](https://swift.org/LICENSE.txt).
+
+---
+
+Changes to this repository follow special considerations as described on
+Swift.org under "[LLVM and Swift](https://swift.org/contributing/#llvm-and-swift)".
+Please make sure your change is appropriate for this repository.
+
+Before submitting a pull request, please make sure you have tested your
+changes and that they follow the Swift project [guidelines for contributing
+code](https://swift.org/contributing/#contributing-code).
diff --git a/cmake/modules/FindZ3.cmake b/cmake/modules/FindZ3.cmake
new file mode 100644
index 0000000..d95f073
--- /dev/null
+++ b/cmake/modules/FindZ3.cmake
@@ -0,0 +1,28 @@
+find_path(Z3_INCLUDE_DIR NAMES z3.h
+   PATH_SUFFIXES libz3
+   )
+
+find_library(Z3_LIBRARIES NAMES z3 libz3
+   )
+
+find_program(Z3_EXECUTABLE z3)
+
+if(Z3_INCLUDE_DIR AND Z3_EXECUTABLE)
+    execute_process (COMMAND ${Z3_EXECUTABLE} -version
+      OUTPUT_VARIABLE libz3_version_str
+      ERROR_QUIET
+      OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    string(REGEX REPLACE "^Z3 version ([0-9.]+)" "\\1"
+           Z3_VERSION_STRING "${libz3_version_str}")
+    unset(libz3_version_str)
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set Z3_FOUND to TRUE if
+# all listed variables are TRUE
+include(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(Z3
+                                  REQUIRED_VARS Z3_LIBRARIES Z3_INCLUDE_DIR
+                                  VERSION_VAR Z3_VERSION_STRING)
+
+mark_as_advanced(Z3_INCLUDE_DIR Z3_LIBRARIES)
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index 885ad57..bd448ef 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -2312,3 +2312,211 @@
 proven safe to vectorize. To identify and diagnose optimization issues use
 `-Rpass`, `-Rpass-missed`, and `-Rpass-analysis` command line options. See the
 user guide for details.
+
+Extensions to specify floating-point flags
+====================================================
+
+The ``#pragma clang fp`` pragma allows floating-point options to be specified
+for a section of the source code. This pragma can only appear at file scope or
+at the start of a compound statement (excluding comments). When using within a
+compound statement, the pragma is active within the scope of the compound
+statement.
+
+Currently, only FP contraction can be controlled with the pragma. ``#pragma
+clang fp contract`` specifies whether the compiler should contract a multiply
+and an addition (or subtraction) into a fused FMA operation when supported by
+the target.
+
+The pragma can take three values: ``on``, ``fast`` and ``off``.  The ``on``
+option is identical to using ``#pragma STDC FP_CONTRACT(ON)`` and it allows
+fusion as specified the language standard.  The ``fast`` option allows fusiong
+in cases when the language standard does not make this possible (e.g. across
+statements in C)
+
+.. code-block:: c++
+
+  for(...) {
+    #pragma clang fp contract(fast)
+    a = b[i] * c[i];
+    d[i] += a;
+  }
+
+
+The pragma can also be used with ``off`` which turns FP contraction off for a
+section of the code. This can be useful when fast contraction is otherwise
+enabled for the translation unit with the ``-ffp-contract=fast`` flag.
+
+Specifying an attribute for multiple declarations (#pragma clang attribute)
+===========================================================================
+
+The ``#pragma clang attribute`` directive can be used to apply an attribute to
+multiple declarations. The ``#pragma clang attribute push`` variation of the
+directive pushes a new attribute to the attribute stack. The declarations that
+follow the pragma receive the attributes that are on the attribute stack, until
+the stack is cleared using a ``#pragma clang attribute pop`` directive. Multiple
+push directives can be nested inside each other.
+
+The attributes that are used in the ``#pragma clang attribute`` directives
+can be written using the GNU-style syntax:
+
+.. code-block:: c++
+
+  #pragma clang attribute push(__attribute__((annotate("custom"))), apply_to = function)
+
+  void function(); // The function now has the annotate("custom") attribute
+
+  #pragma clang attribute pop
+
+The attributes can also be written using the C++11 style syntax:
+
+.. code-block:: c++
+
+  #pragma clang attribute push([[noreturn]], apply_to = function)
+
+  void function(); // The function now has the [[noreturn]] attribute
+
+  #pragma clang attribute pop
+
+The ``__declspec`` style syntax is also supported:
+
+.. code-block:: c++
+
+  #pragma clang attribute push(__declspec(dllexport), apply_to = function)
+
+  void function(); // The function now has the __declspec(dllexport) attribute
+
+  #pragma clang attribute pop
+
+A single push directive accepts only one attribute regardless of the syntax
+used.
+
+Subject Match Rules
+-------------------
+
+The set of declarations that receive a single attribute from the attribute stack
+depends on the subject match rules that were specified in the pragma. Subject
+match rules are specified after the attribute. The compiler expects an
+identifier that corresponds to the subject set specifier. The ``apply_to``
+specifier is currently the only supported subject set specifier. It allows you
+to specify match rules that form a subset of the attribute's allowed subject
+set, i.e. the compiler doesn't require all of the attribute's subjects. For
+example, an attribute like ``[[nodiscard]]`` whose subject set includes
+``enum``, ``record`` and ``hasType(functionType)``, requires the presence of at
+least one of these rules after ``apply_to``:
+
+.. code-block:: c++
+
+  #pragma clang attribute push([[nodiscard]], apply_to = enum)
+
+  enum Enum1 { A1, B1 }; // The enum will receive [[nodiscard]]
+
+  struct Record1 { }; // The struct will *not* receive [[nodiscard]]
+
+  #pragma clang attribute pop
+
+  #pragma clang attribute push([[nodiscard]], apply_to = any(record, enum))
+
+  enum Enum2 { A2, B2 }; // The enum will receive [[nodiscard]]
+
+  struct Record2 { }; // The struct *will* receive [[nodiscard]]
+
+  #pragma clang attribute pop
+
+  // This is an error, since [[nodiscard]] can't be applied to namespaces:
+  #pragma clang attribute push([[nodiscard]], apply_to = any(record, namespace))
+
+  #pragma clang attribute pop
+
+Multiple match rules can be specified using the ``any`` match rule, as shown
+in the example above. The ``any`` rule applies attributes to all declarations
+that are matched by at least one of the rules in the ``any``. It doesn't nest
+and can't be used inside the other match rules. Redundant match rules or rules
+that conflict with one another should not be used inside of ``any``.
+
+Clang supports the following match rules:
+
+- ``function``: Can be used to apply attributes to functions. This includes C++
+  member functions, static functions, operators, and constructors/destructors.
+
+- ``function(is_member)``: Can be used to apply attributes to C++ member
+  functions. This includes members like static functions, operators, and
+  constructors/destructors.
+
+- ``hasType(functionType)``: Can be used to apply attributes to functions, C++
+  member functions, and variables/fields whose type is a function pointer. It
+  does not apply attributes to Objective-C methods or blocks.
+
+- ``type_alias``: Can be used to apply attributes to ``typedef`` declarations
+  and C++11 type aliases.
+
+- ``record``: Can be used to apply attributes to ``struct``, ``class``, and
+  ``union`` declarations.
+
+- ``record(unless(is_union))``: Can be used to apply attributes only to
+  ``struct`` and ``class`` declarations.
+
+- ``enum``: Can be be used to apply attributes to enumeration declarations.
+
+- ``enum_constant``: Can be used to apply attributes to enumerators.
+
+- ``variable``: Can be used to apply attributes to variables, including
+  local variables, parameters, global variables, and static member variables.
+  It does not apply attributes to instance member variables or Objective-C
+  ivars.
+
+- ``variable(is_thread_local)``: Can be used to apply attributes to thread-local
+  variables only.
+
+- ``variable(is_global)``: Can be used to apply attributes to global variables
+  only.
+
+- ``variable(is_parameter)``: Can be used to apply attributes to parameters
+  only.
+
+- ``variable(unless(is_parameter))``: Can be used to apply attributes to all
+  the variables that are not parameters.
+
+- ``field``: Can be used to apply attributes to non-static member variables
+  in a record. This includes Objective-C ivars.
+
+- ``namespace``: Can be used to apply attributes to ``namespace`` declarations.
+
+- ``objc_interface``: Can be used to apply attributes to ``@interface``
+  declarations.
+
+- ``objc_protocol``: Can be used to apply attributes to ``@protocol``
+  declarations.
+
+- ``objc_category``: Can be used to apply attributes to category declarations,
+  including class extensions.
+
+- ``objc_method``: Can be used to apply attributes to Objective-C methods,
+  including instance and class methods. Implicit methods like implicit property
+  getters and setters do not receive the attribute.
+
+- ``objc_method(is_instance)``: Can be used to apply attributes to Objective-C
+  instance methods.
+
+- ``objc_property``: Can be used to apply attributes to ``@property``
+  declarations.
+
+- ``block``: Can be used to apply attributes to block declarations. This does
+  not include variables/fields of block pointer type.
+
+The use of ``unless`` in match rules is currently restricted to a strict set of
+sub-rules that are used by the supported attributes. That means that even though
+``variable(unless(is_parameter))`` is a valid match rule,
+``variable(unless(is_thread_local))`` is not.
+
+Supported Attributes
+--------------------
+
+Not all attributes can be used with the ``#pragma clang attribute`` directive.
+Notably, statement attributes like ``[[fallthrough]]`` or type attributes
+like ``address_space`` aren't supported by this directive. You can determine
+whether or not an attribute is supported by the pragma by referring to the
+:doc:`individual documentation for that attribute <AttributeReference>`.
+
+The attributes are applied to all matching declarations individually, even when
+the attribute is semantically incorrect. The attributes that aren't applied to
+any declaration are not verified semantically.
diff --git a/docs/Modules.rst b/docs/Modules.rst
index 141d3b8..2b1bde2 100644
--- a/docs/Modules.rst
+++ b/docs/Modules.rst
@@ -360,6 +360,7 @@
   Name.framework/
     Modules/module.modulemap  Module map for the framework
     Headers/                  Subdirectory containing framework headers
+    PrivateHeaders/           Subdirectory containing framework private headers
     Frameworks/               Subdirectory containing embedded frameworks
     Resources/                Subdirectory containing additional resources
     Name                      Symbolic link to the shared library for the framework
@@ -842,6 +843,16 @@
 easier to split a library's public and private APIs along header
 boundaries.
 
+When writing a private module as part of a *framework*, it's recommended that:
+
+* Headers for this module are present in the ``PrivateHeaders``
+  framework subdirectory.
+* The private module is defined as a *submodule* of the public framework (if
+  there's one), similar to how ``Foo.Private`` is defined in the example above.
+* The ``explicit`` keyword should be used to guarantee that its content will
+  only be available when the submodule itself is explicitly named (through a
+  ``@import`` for example).
+
 Modularizing a Platform
 =======================
 To get any benefit out of modules, one needs to introduce module maps for software libraries starting at the bottom of the stack. This typically means introducing a module map covering the operating system's headers and the C standard library headers (in ``/usr/include``, for a Unix system). 
diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst
index 09ee78f..f4ea232 100644
--- a/docs/UndefinedBehaviorSanitizer.rst
+++ b/docs/UndefinedBehaviorSanitizer.rst
@@ -92,6 +92,12 @@
      parameter which is declared to never be null.
   -  ``-fsanitize=null``: Use of a null pointer or creation of a null
      reference.
+  -  ``-fsanitize=nullability-arg``: Passing null as a function parameter
+     which is annotated with ``_Nonnull``.
+  -  ``-fsanitize=nullability-assign``: Assigning null to an lvalue which
+     is annotated with ``_Nonnull``.
+  -  ``-fsanitize=nullability-return``: Returning null from a function with
+     a return type annotated with ``_Nonnull``.
   -  ``-fsanitize=object-size``: An attempt to potentially use bytes which
      the optimizer can determine are not part of the object being accessed.
      This will also detect some types of undefined behavior that may not
@@ -128,11 +134,15 @@
 
 You can also use the following check groups:
   -  ``-fsanitize=undefined``: All of the checks listed above other than
-     ``unsigned-integer-overflow``.
+     ``unsigned-integer-overflow`` and the ``nullability-*`` checks.
   -  ``-fsanitize=undefined-trap``: Deprecated alias of
      ``-fsanitize=undefined``.
   -  ``-fsanitize=integer``: Checks for undefined or suspicious integer
      behavior (e.g. unsigned integer overflow).
+  -  ``-fsanitize=nullability``: Enables ``nullability-arg``,
+     ``nullability-assign``, and ``nullability-return``. While violating
+     nullability does not have undefined behavior, it is often unintentional,
+     so UBSan offers to catch it.
 
 Stack traces and report symbolization
 =====================================
diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst
index 6c83557..603c76c 100644
--- a/docs/UsersManual.rst
+++ b/docs/UsersManual.rst
@@ -562,6 +562,16 @@
 The -fno-crash-diagnostics flag can be helpful for speeding the process
 of generating a delta reduced test case.
 
+Clang is also capable of generating preprocessed source file(s) and associated
+run script(s) even without a crash. This is specially useful when trying to
+generate a reproducer for warnings or errors while using modules.
+
+.. option:: -gen-reproducer
+
+  Generates preprocessed source files, a reproducer script and if relevant, a
+  cache containing: built module pcm's and all headers needed to rebuilt the
+  same modules.
+
 .. _rpass:
 
 Options to Emit Optimization Reports
diff --git a/docs/analyzer/DebugChecks.rst b/docs/analyzer/DebugChecks.rst
index ecf11ca..880dcfc 100644
--- a/docs/analyzer/DebugChecks.rst
+++ b/docs/analyzer/DebugChecks.rst
@@ -178,15 +178,21 @@
   This function explains the value of its argument in a human-readable manner
   in the warning message. You can make as many overrides of its prototype
   in the test code as necessary to explain various integral, pointer,
-  or even record-type values.
+  or even record-type values. To simplify usage in C code (where overloading
+  the function declaration is not allowed), you may append an arbitrary suffix
+  to the function name, without affecting functionality.
 
   Example usage::
 
     void clang_analyzer_explain(int);
     void clang_analyzer_explain(void *);
 
+    // Useful in C code
+    void clang_analyzer_explain_int(int);
+
     void foo(int param, void *ptr) {
       clang_analyzer_explain(param); // expected-warning{{argument 'param'}}
+      clang_analyzer_explain_int(param); // expected-warning{{argument 'param'}}
       if (!ptr)
         clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}
     }
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 15fde19..2bd25b5 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -3436,6 +3436,16 @@
 CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T);
 
 /**
+ * \brief Determine if a typedef is 'transparent' tag.
+ *
+ * A typedef is considered 'transparent' if it shares a name and spelling
+ * location with its underlying tag type, as is the case with the NS_ENUM macro.
+ *
+ * \returns non-zero if transparent and zero otherwise.
+ */
+CINDEX_LINKAGE unsigned clang_Type_isTransparentTagTypedef(CXType T);
+
+/**
  * \brief List the possible error codes for \c clang_Type_getSizeOf,
  *   \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
  *   \c clang_Cursor_getOffsetOf.
@@ -3964,8 +3974,8 @@
 CINDEX_LINKAGE int clang_Cursor_isDynamicCall(CXCursor C);
 
 /**
- * \brief Given a cursor pointing to an Objective-C message, returns the CXType
- * of the receiver.
+ * \brief Given a cursor pointing to an Objective-C message or property
+ * reference, or C++ method call, returns the CXType of the receiver.
  */
 CINDEX_LINKAGE CXType clang_Cursor_getReceiverType(CXCursor C);
 
@@ -4023,8 +4033,8 @@
 
 /**
  * \brief Given a cursor that represents an Objective-C method or property
- * declaration, return non-zero if the declaration was affected by "@optional".
- * Returns zero if the cursor is not such a declaration or it is "@required".
+ * declaration, return non-zero if the declaration was affected by "\@optional".
+ * Returns zero if the cursor is not such a declaration or it is "\@required".
  */
 CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C);
 
@@ -4034,6 +4044,23 @@
 CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C);
 
 /**
+ * \brief Returns non-zero if the given cursor points to a symbol marked with
+ * external_source_symbol attribute.
+ *
+ * \param language If non-NULL, and the attribute is present, will be set to
+ * the 'language' string from the attribute.
+ *
+ * \param definedIn If non-NULL, and the attribute is present, will be set to
+ * the 'definedIn' string from the attribute.
+ *
+ * \param isGenerated If non-NULL, and the attribute is present, will be set to
+ * non-zero if the 'generated_declaration' is set in the attribute.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isExternalSymbol(CXCursor C,
+                                       CXString *language, CXString *definedIn,
+                                       unsigned *isGenerated);
+
+/**
  * \brief Given a cursor that represents a declaration, return the associated
  * comment's source range.  The range may include multiple consecutive comments
  * with whitespace in between.
@@ -4700,7 +4727,7 @@
    */
   CXCompletionChunk_HorizontalSpace,
   /**
-   * Vertical space ('\n'), after which it is generally a good idea to
+   * Vertical space ('\\n'), after which it is generally a good idea to
    * perform indentation.
    */
   CXCompletionChunk_VerticalSpace
@@ -5589,7 +5616,8 @@
   CXIdxEntityLang_None = 0,
   CXIdxEntityLang_C    = 1,
   CXIdxEntityLang_ObjC = 2,
-  CXIdxEntityLang_CXX  = 3
+  CXIdxEntityLang_CXX  = 3,
+  CXIdxEntityLang_Swift  = 4
 } CXIdxEntityLanguage;
 
 /**
diff --git a/include/clang/APINotes/APINotesManager.h b/include/clang/APINotes/APINotesManager.h
new file mode 100644
index 0000000..2adc29c
--- /dev/null
+++ b/include/clang/APINotes/APINotesManager.h
@@ -0,0 +1,147 @@
+//===--- APINotesManager.h - Manage API Notes Files -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the APINotesManager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_APINOTES_APINOTESMANAGER_H
+#define LLVM_CLANG_APINOTES_APINOTESMANAGER_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/Module.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+#include <string>
+
+namespace clang {
+
+class DirectoryEntry;
+class FileEntry;
+class LangOptions;
+class SourceManager;
+
+namespace api_notes {
+
+class APINotesReader;
+
+/// The API notes manager helps find API notes associated with declarations.
+///
+/// API notes are externally-provided annotations for declarations that can
+/// introduce new attributes (covering availability, nullability of
+/// parameters/results, and so on) for specific declarations without directly
+/// modifying the headers that contain those declarations.
+///
+/// The API notes manager is responsible for finding and loading the
+/// external API notes files that correspond to a given header. Its primary
+/// operation is \c findAPINotes(), which finds the API notes reader that
+/// provides information about the declarations at that location.
+class APINotesManager {
+  typedef llvm::PointerUnion<const DirectoryEntry *, APINotesReader *>
+    ReaderEntry;
+
+  SourceManager &SourceMgr;
+
+  /// Whether to implicitly search for API notes files based on the
+  /// source file from which an entity was declared.
+  bool ImplicitAPINotes;
+
+  /// The Swift version to use when interpreting versioned API notes.
+  VersionTuple SwiftVersion;
+
+  /// API notes readers for the current module.
+  ///
+  /// There can be up to two of these, one for public headers and one
+  /// for private headers.
+  APINotesReader *CurrentModuleReaders[2] = { nullptr, nullptr };
+
+  /// Whether we have already pruned the API notes cache.
+  bool PrunedCache;
+
+  /// A mapping from header file directories to the API notes reader for
+  /// that directory, or a redirection to another directory entry that may
+  /// have more information, or NULL to indicate that there is no API notes
+  /// reader for this directory.
+  llvm::DenseMap<const DirectoryEntry *, ReaderEntry> Readers;
+
+  /// Load the API notes associated with the given file, whether it is
+  /// the binary or source form of API notes.
+  ///
+  /// \returns the API notes reader for this file, or null if there is
+  /// a failure.
+  std::unique_ptr<APINotesReader> loadAPINotes(const FileEntry *apiNotesFile);
+
+  /// Load the given API notes file for the given header directory.
+  ///
+  /// \param HeaderDir The directory at which we
+  ///
+  /// \returns true if an error occurred.
+  bool loadAPINotes(const DirectoryEntry *HeaderDir,
+                    const FileEntry *APINotesFile);
+
+  /// Look for API notes in the given directory.
+  ///
+  /// This might find either a binary or source API notes.
+  const FileEntry *findAPINotesFile(const DirectoryEntry *directory,
+                                    StringRef filename,
+                                    bool wantPublic = true);
+
+  /// Attempt to load API notes for the given framework.
+  ///
+  /// \param FrameworkPath The path to the framework.
+  /// \param Public Whether to load the public API notes. Otherwise, attempt
+  /// to load the private API notes.
+  ///
+  /// \returns the header directory entry (e.g., for Headers or PrivateHeaders)
+  /// for which the API notes were successfully loaded, or NULL if API notes
+  /// could not be loaded for any reason.
+  const DirectoryEntry *loadFrameworkAPINotes(llvm::StringRef FrameworkPath,
+                                              llvm::StringRef FrameworkName,
+                                              bool Public);
+
+public:
+  APINotesManager(SourceManager &sourceMgr, const LangOptions &langOpts);
+  ~APINotesManager();
+
+  /// Set the Swift version to use when filtering API notes.
+  void setSwiftVersion(VersionTuple swiftVersion) {
+    SwiftVersion = swiftVersion;
+  }
+
+  /// Load the API notes for the current module.
+  ///
+  /// \param module The current module.
+  /// \param lookInModule Whether to look inside the module itself.
+  /// \param searchPaths The paths in which we should search for API notes
+  /// for the current module.
+  ///
+  /// \returns true if API notes were successfully loaded, \c false otherwise.
+  bool loadCurrentModuleAPINotes(const Module *module,
+                                 bool lookInModule,
+                                 ArrayRef<std::string> searchPaths);
+
+  /// Retrieve the set of API notes readers for the current module.
+  ArrayRef<APINotesReader *> getCurrentModuleReaders() const {
+    unsigned numReaders = static_cast<unsigned>(CurrentModuleReaders[0] != nullptr) +
+      static_cast<unsigned>(CurrentModuleReaders[1] != nullptr);
+    return llvm::makeArrayRef(CurrentModuleReaders).slice(0, numReaders);
+  }
+
+  /// Find the API notes readers that correspond to the given source location.
+  llvm::SmallVector<APINotesReader *, 2> findAPINotes(SourceLocation Loc);
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif
diff --git a/include/clang/APINotes/APINotesOptions.h b/include/clang/APINotes/APINotesOptions.h
new file mode 100644
index 0000000..24bb913
--- /dev/null
+++ b/include/clang/APINotes/APINotesOptions.h
@@ -0,0 +1,41 @@
+//===--- APINotesOptions.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the APINotesOptions class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_APINOTES_APINOTESOPTIONS_H
+#define LLVM_CLANG_APINOTES_APINOTESOPTIONS_H
+
+#include "clang/Basic/VersionTuple.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+/// APINotesOptions - Track various options which control how API
+/// notes are found and handled.
+class APINotesOptions {
+public:
+  /// The Swift version which should be used for API notes.
+  VersionTuple SwiftVersion;
+
+  /// The set of search paths where we API notes can be found for
+  /// particular modules.
+  ///
+  /// The API notes in this directory are stored as
+  /// <ModuleName>.apinotes or <ModuleName>.apinotesc, and are only
+  /// applied when building the module <ModuleName>.
+  std::vector<std::string> ModuleSearchPaths;
+};
+
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/APINotes/APINotesReader.h b/include/clang/APINotes/APINotesReader.h
new file mode 100644
index 0000000..a71c74d
--- /dev/null
+++ b/include/clang/APINotes/APINotesReader.h
@@ -0,0 +1,269 @@
+//===--- APINotesReader.h - API Notes Reader ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the \c APINotesReader class that reads source
+// API notes data providing additional information about source code as
+// a separate input, such as the non-nil/nilable annotations for
+// method parameters.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_API_NOTES_READER_H
+#define LLVM_CLANG_API_NOTES_READER_H
+
+#include "clang/APINotes/Types.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
+
+namespace clang {
+namespace api_notes {
+
+/// A class that reads API notes data from a binary file that was written by
+/// the \c APINotesWriter.
+class APINotesReader {
+  class Implementation;
+
+  Implementation &Impl;
+
+  APINotesReader(llvm::MemoryBuffer *inputBuffer, bool ownsInputBuffer,
+                 VersionTuple swiftVersion, bool &failed);
+
+public:
+  /// Create a new API notes reader from the given member buffer, which
+  /// contains the contents of a binary API notes file.
+  ///
+  /// \returns the new API notes reader, or null if an error occurred.
+  static std::unique_ptr<APINotesReader>
+  get(std::unique_ptr<llvm::MemoryBuffer> inputBuffer,
+      VersionTuple swiftVersion);
+
+  /// Create a new API notes reader from the given member buffer, which
+  /// contains the contents of a binary API notes file.
+  ///
+  /// \returns the new API notes reader, or null if an error occurred.
+  static std::unique_ptr<APINotesReader>
+  getUnmanaged(llvm::MemoryBuffer *inputBuffer,
+               VersionTuple swiftVersion);
+
+  ~APINotesReader();
+
+  APINotesReader(const APINotesReader &) = delete;
+  APINotesReader &operator=(const APINotesReader &) = delete;
+
+  /// Retrieve the name of the module for which this reader is providing API
+  /// notes.
+  StringRef getModuleName() const;
+
+  /// Retrieve the size and modification time of the source file from
+  /// which this API notes file was created, if known.
+  Optional<std::pair<off_t, time_t>> getSourceFileSizeAndModTime() const;
+
+  /// Retrieve the module options
+  ModuleOptions getModuleOptions() const;
+
+  /// Captures the completed versioned information for a particular part of
+  /// API notes, including both unversioned API notes and each versioned API
+  /// note for that particular entity.
+  template<typename T>
+  class VersionedInfo {
+    /// The complete set of results.
+    SmallVector<std::pair<VersionTuple, T>, 1> Results;
+
+    /// The index of the result that is the "selected" set based on the desired
+    /// Swift version, or \c Results.size() if nothing matched.
+    unsigned Selected;
+
+  public:
+    /// Form an empty set of versioned information.
+    VersionedInfo(llvm::NoneType) : Selected(0) { }
+    
+    /// Form a versioned info set given the desired version and a set of
+    /// results.
+    VersionedInfo(VersionTuple version,
+                  SmallVector<std::pair<VersionTuple, T>, 1> results);
+
+    /// Determine whether there is a result that should be applied directly
+    /// to the AST.
+    explicit operator bool() const { return Selected != size(); }
+
+    /// Retrieve the information to apply directly to the AST.
+    const T& operator*() const {
+      assert(*this && "No result to apply directly");
+      return (*this)[Selected].second;
+    }
+
+    /// Retrieve the selected index in the result set.
+    Optional<unsigned> getSelected() const {
+      if (Selected == Results.size()) return None;
+      return Selected;
+    }
+
+    /// Return the number of versioned results we know about.
+    unsigned size() const { return Results.size(); }
+
+    /// Access all versioned results.
+    const std::pair<VersionTuple, T> *begin() const { return Results.begin(); }
+    const std::pair<VersionTuple, T> *end() const { return Results.end(); }
+
+    /// Access a specific versioned result.
+    const std::pair<VersionTuple, T> &operator[](unsigned index) const {
+      return Results[index];
+    }
+  };
+
+  /// Look for the context ID of the given Objective-C class.
+  ///
+  /// \param name The name of the class we're looking for.
+  ///
+  /// \returns The ID, if known.
+  Optional<ContextID> lookupObjCClassID(StringRef name);
+
+  /// Look for information regarding the given Objective-C class.
+  ///
+  /// \param name The name of the class we're looking for.
+  ///
+  /// \returns The information about the class, if known.
+  VersionedInfo<ObjCContextInfo> lookupObjCClassInfo(StringRef name);
+
+  /// Look for the context ID of the given Objective-C protocol.
+  ///
+  /// \param name The name of the protocol we're looking for.
+  ///
+  /// \returns The ID of the protocol, if known.
+  Optional<ContextID> lookupObjCProtocolID(StringRef name);
+
+  /// Look for information regarding the given Objective-C protocol.
+  ///
+  /// \param name The name of the protocol we're looking for.
+  ///
+  /// \returns The information about the protocol, if known.
+  VersionedInfo<ObjCContextInfo> lookupObjCProtocolInfo(StringRef name);
+
+  /// Look for information regarding the given Objective-C property in
+  /// the given context.
+  ///
+  /// \param contextID The ID that references the context we are looking for.
+  /// \param name The name of the property we're looking for.
+  /// \param isInstance Whether we are looking for an instance property (vs.
+  /// a class property).
+  ///
+  /// \returns Information about the property, if known.
+  VersionedInfo<ObjCPropertyInfo> lookupObjCProperty(ContextID contextID,
+                                                     StringRef name,
+                                                     bool isInstance);
+
+  /// Look for information regarding the given Objective-C method in
+  /// the given context.
+  ///
+  /// \param contextID The ID that references the context we are looking for.
+  /// \param selector The selector naming the method we're looking for.
+  /// \param isInstanceMethod Whether we are looking for an instance method.
+  ///
+  /// \returns Information about the method, if known.
+  VersionedInfo<ObjCMethodInfo> lookupObjCMethod(ContextID contextID,
+                                                 ObjCSelectorRef selector,
+                                                 bool isInstanceMethod);
+
+  /// Look for information regarding the given global variable.
+  ///
+  /// \param name The name of the global variable.
+  ///
+  /// \returns information about the global variable, if known.
+  VersionedInfo<GlobalVariableInfo> lookupGlobalVariable(StringRef name);
+
+  /// Look for information regarding the given global function.
+  ///
+  /// \param name The name of the global function.
+  ///
+  /// \returns information about the global function, if known.
+  VersionedInfo<GlobalFunctionInfo> lookupGlobalFunction(StringRef name);
+
+  /// Look for information regarding the given enumerator.
+  ///
+  /// \param name The name of the enumerator.
+  ///
+  /// \returns information about the enumerator, if known.
+  VersionedInfo<EnumConstantInfo> lookupEnumConstant(StringRef name);
+
+  /// Look for information regarding the given tag
+  /// (struct/union/enum/C++ class).
+  ///
+  /// \param name The name of the tag.
+  ///
+  /// \returns information about the tag, if known.
+  VersionedInfo<TagInfo> lookupTag(StringRef name);
+
+  /// Look for information regarding the given typedef.
+  ///
+  /// \param name The name of the typedef.
+  ///
+  /// \returns information about the typedef, if known.
+  VersionedInfo<TypedefInfo> lookupTypedef(StringRef name);
+
+  /// Visitor used when walking the contents of the API notes file.
+  class Visitor {
+  public:
+    virtual ~Visitor();
+
+    /// Visit an Objective-C class.
+    virtual void visitObjCClass(ContextID contextID, StringRef name,
+                                const ObjCContextInfo &info,
+                                VersionTuple swiftVersion);
+
+    /// Visit an Objective-C protocol.
+    virtual void visitObjCProtocol(ContextID contextID, StringRef name,
+                                   const ObjCContextInfo &info,
+                                   VersionTuple swiftVersion);
+
+    /// Visit an Objective-C method.
+    virtual void visitObjCMethod(ContextID contextID, StringRef selector,
+                                 bool isInstanceMethod,
+                                 const ObjCMethodInfo &info,
+                                 VersionTuple swiftVersion);
+
+    /// Visit an Objective-C property.
+    virtual void visitObjCProperty(ContextID contextID, StringRef name,
+                                   bool isInstance,
+                                   const ObjCPropertyInfo &info,
+                                   VersionTuple swiftVersion);
+
+    /// Visit a global variable.
+    virtual void visitGlobalVariable(StringRef name,
+                                     const GlobalVariableInfo &info,
+                                     VersionTuple swiftVersion);
+
+    /// Visit a global function.
+    virtual void visitGlobalFunction(StringRef name,
+                                     const GlobalFunctionInfo &info,
+                                     VersionTuple swiftVersion);
+
+    /// Visit an enumerator.
+    virtual void visitEnumConstant(StringRef name,
+                                   const EnumConstantInfo &info,
+                                   VersionTuple swiftVersion);
+
+    /// Visit a tag.
+    virtual void visitTag(StringRef name, const TagInfo &info,
+                          VersionTuple swiftVersion);
+
+    /// Visit a typedef.
+    virtual void visitTypedef(StringRef name, const TypedefInfo &info,
+                              VersionTuple swiftVersion);
+  };
+
+  /// Visit the contents of the API notes file, passing each entity to the
+  /// given visitor.
+  void visit(Visitor &visitor);
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif // LLVM_CLANG_API_NOTES_READER_H
diff --git a/include/clang/APINotes/APINotesWriter.h b/include/clang/APINotes/APINotesWriter.h
new file mode 100644
index 0000000..62defc1
--- /dev/null
+++ b/include/clang/APINotes/APINotesWriter.h
@@ -0,0 +1,126 @@
+//===--- APINotesWriter.h - API Notes Writer ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the \c APINotesWriter class that writes out source
+// API notes data providing additional information about source code as
+// a separate input, such as the non-nil/nilable annotations for
+// method parameters.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_API_NOTES_WRITER_H
+#define LLVM_CLANG_API_NOTES_WRITER_H
+
+#include "clang/Basic/VersionTuple.h"
+#include "clang/APINotes/Types.h"
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+
+class FileEntry;
+
+namespace api_notes {
+
+/// A class that writes API notes data to a binary representation that can be
+/// read by the \c APINotesReader.
+class APINotesWriter {
+  class Implementation;
+  Implementation &Impl;
+
+public:
+  /// Create a new API notes writer with the given module name and
+  /// (optional) source file.
+  APINotesWriter(StringRef moduleName, const FileEntry *sourceFile);
+  ~APINotesWriter();
+
+  APINotesWriter(const APINotesWriter &) = delete;
+  APINotesWriter &operator=(const APINotesWriter &) = delete;
+
+  /// Write the API notes data to the given stream.
+  void writeToStream(llvm::raw_ostream &os);
+
+  /// Add information about a specific Objective-C class or protocol.
+  ///
+  /// \param name The name of this class/protocol.
+  /// \param isClass Whether this is a class (vs. a protocol).
+  /// \param info Information about this class/protocol.
+  ///
+  /// \returns the ID of the class or protocol, which can be used to add
+  /// properties and methods to the class/protocol.
+  ContextID addObjCContext(StringRef name, bool isClass,
+                           const ObjCContextInfo &info,
+                           VersionTuple swiftVersion);
+
+  /// Add information about a specific Objective-C property.
+  ///
+  /// \param contextID The context in which this property resides.
+  /// \param name The name of this property.
+  /// \param info Information about this property.
+  void addObjCProperty(ContextID contextID, StringRef name,
+                       bool isInstanceProperty,
+                       const ObjCPropertyInfo &info,
+                       VersionTuple swiftVersion);
+
+  /// Add information about a specific Objective-C method.
+  ///
+  /// \param contextID The context in which this method resides.
+  /// \param selector The selector that names this method.
+  /// \param isInstanceMethod Whether this method is an instance method
+  /// (vs. a class method).
+  /// \param info Information about this method.
+  void addObjCMethod(ContextID contextID, ObjCSelectorRef selector,
+                     bool isInstanceMethod, const ObjCMethodInfo &info,
+                     VersionTuple swiftVersion);
+
+  /// Add information about a global variable.
+  ///
+  /// \param name The name of this global variable.
+  /// \param info Information about this global variable.
+  void addGlobalVariable(StringRef name, const GlobalVariableInfo &info,
+                         VersionTuple swiftVersion);
+
+  /// Add information about a global function.
+  ///
+  /// \param name The name of this global function.
+  /// \param info Information about this global function.
+  void addGlobalFunction(StringRef name, const GlobalFunctionInfo &info,
+                         VersionTuple swiftVersion);
+
+  /// Add information about an enumerator.
+  ///
+  /// \param name The name of this enumerator.
+  /// \param info Information about this enumerator.
+  void addEnumConstant(StringRef name, const EnumConstantInfo &info,
+                       VersionTuple swiftVersion);
+
+  /// Add information about a tag (struct/union/enum/C++ class).
+  ///
+  /// \param name The name of this tag.
+  /// \param info Information about this tag.
+  void addTag(StringRef name, const TagInfo &info,
+              VersionTuple swiftVersion);
+
+  /// Add information about a typedef.
+  ///
+  /// \param name The name of this typedef.
+  /// \param info Information about this typedef.
+  void addTypedef(StringRef name, const TypedefInfo &info,
+                  VersionTuple swiftVersion);
+
+  /// Add module options
+  void addModuleOptions(ModuleOptions opts);
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif // LLVM_CLANG_API_NOTES_WRITER_H
+
diff --git a/include/clang/APINotes/APINotesYAMLCompiler.h b/include/clang/APINotes/APINotesYAMLCompiler.h
new file mode 100644
index 0000000..508da65
--- /dev/null
+++ b/include/clang/APINotes/APINotesYAMLCompiler.h
@@ -0,0 +1,62 @@
+//=== APINotesYAMLCompiler.h - API Notes YAML to binary compiler *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file reads sidecar API notes specified in YAML format.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_API_NOTES_YAML_COMPILER_H
+#define LLVM_CLANG_API_NOTES_YAML_COMPILER_H
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SourceMgr.h"
+#include <memory>
+
+namespace llvm {
+  class raw_ostream;
+  class MemoryBuffer;
+}
+
+namespace clang {
+
+class FileEntry;
+
+namespace api_notes {
+
+  enum class ActionType {
+    None,
+    YAMLToBinary,
+    BinaryToYAML,
+    Dump,
+  };
+
+  enum class OSType {
+    OSX,
+    IOS,
+    TvOS,
+    WatchOS,
+    Absent
+  };
+
+  /// Converts API notes from YAML format to binary format.
+  bool compileAPINotes(llvm::StringRef yamlInput,
+                       const FileEntry *sourceFile,
+                       llvm::raw_ostream &os,
+                       OSType targetOS,
+                       llvm::SourceMgr::DiagHandlerTy diagHandler = nullptr,
+                       void *diagHandlerCtxt = nullptr);
+
+  bool parseAndDumpAPINotes(llvm::StringRef yamlInput);
+
+  /// Converts API notes from the compiled binary format to the YAML format.
+  bool decompileAPINotes(std::unique_ptr<llvm::MemoryBuffer> input,
+                         llvm::raw_ostream &os);
+} // end namespace api_notes
+} // end namespace clang
+
+#endif // LLVM_CLANG_API_NOTES_YAML_COMPILER_H
diff --git a/include/clang/APINotes/Types.h b/include/clang/APINotes/Types.h
new file mode 100644
index 0000000..2213bad
--- /dev/null
+++ b/include/clang/APINotes/Types.h
@@ -0,0 +1,745 @@
+//===--- Types.h - API Notes Data Types --------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines data types used in the representation of API notes data.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_API_NOTES_TYPES_H
+#define LLVM_CLANG_API_NOTES_TYPES_H
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include <cassert>
+#include <climits>
+
+namespace llvm {
+  class raw_ostream;
+}
+
+namespace clang {
+namespace api_notes {
+
+/// The file extension used for the source representation of API notes.
+static const char SOURCE_APINOTES_EXTENSION[] = "apinotes";
+
+/// The file extension used for the binary representation of API notes.
+static const char BINARY_APINOTES_EXTENSION[] = "apinotesc";
+
+using llvm::ArrayRef;
+using llvm::StringRef;
+using llvm::Optional;
+using llvm::None;
+
+/// Opaque context ID used to refer to an Objective-C class or protocol.
+class ContextID {
+public:
+  unsigned Value;
+
+  explicit ContextID(unsigned value) : Value(value) { }
+};
+
+/// Describes API notes data for any entity.
+///
+/// This is used as the base of all API notes.
+class CommonEntityInfo {
+public:
+  /// Message to use when this entity is unavailable.
+  std::string UnavailableMsg;
+
+  /// Whether this entity is marked unavailable.
+  unsigned Unavailable : 1;
+
+  /// Whether this entity is marked unavailable in Swift.
+  unsigned UnavailableInSwift : 1;
+
+private:
+  /// Whether SwiftPrivate was specified.
+  unsigned SwiftPrivateSpecified : 1;
+
+  /// Whether this entity is considered "private" to a Swift overlay.
+  unsigned SwiftPrivate : 1;
+
+public:
+  /// Swift name of this entity.
+  std::string SwiftName;
+
+  CommonEntityInfo()
+    : Unavailable(0), UnavailableInSwift(0), SwiftPrivateSpecified(0),
+      SwiftPrivate(0) { }
+
+  Optional<bool> isSwiftPrivate() const {
+    if (!SwiftPrivateSpecified) return None;
+    return SwiftPrivate;
+  }
+
+  void setSwiftPrivate(Optional<bool> swiftPrivate) {
+    if (swiftPrivate) {
+      SwiftPrivateSpecified = 1;
+      SwiftPrivate = *swiftPrivate;
+    } else {
+      SwiftPrivateSpecified = 0;
+      SwiftPrivate = 0;
+    }
+  }
+
+  friend bool operator==(const CommonEntityInfo &lhs,
+                         const CommonEntityInfo &rhs) {
+    return lhs.UnavailableMsg == rhs.UnavailableMsg &&
+           lhs.Unavailable == rhs.Unavailable &&
+           lhs.UnavailableInSwift == rhs.UnavailableInSwift &&
+           lhs.SwiftPrivateSpecified == rhs.SwiftPrivateSpecified &&
+           lhs.SwiftPrivate == rhs.SwiftPrivate &&
+           lhs.SwiftName == rhs.SwiftName;
+  }
+
+  friend bool operator!=(const CommonEntityInfo &lhs,
+                         const CommonEntityInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+  friend CommonEntityInfo &operator|=(CommonEntityInfo &lhs,
+                                      const CommonEntityInfo &rhs) {
+    // Merge unavailability.
+    if (rhs.Unavailable) {
+      lhs.Unavailable = true;
+      if (rhs.UnavailableMsg.length() != 0 &&
+          lhs.UnavailableMsg.length() == 0) {
+        lhs.UnavailableMsg = rhs.UnavailableMsg;
+      }
+    }
+
+    if (rhs.UnavailableInSwift) {
+      lhs.UnavailableInSwift = true;
+      if (rhs.UnavailableMsg.length() != 0 &&
+          lhs.UnavailableMsg.length() == 0) {
+        lhs.UnavailableMsg = rhs.UnavailableMsg;
+      }
+    }
+
+    if (rhs.SwiftPrivateSpecified && !lhs.SwiftPrivateSpecified) {
+      lhs.SwiftPrivateSpecified = 1;
+      lhs.SwiftPrivate = rhs.SwiftPrivate;
+    }
+
+    if (rhs.SwiftName.length() != 0 &&
+        lhs.SwiftName.length() == 0)
+      lhs.SwiftName = rhs.SwiftName;
+
+    return lhs;
+  }
+};
+
+/// Describes API notes for types.
+class CommonTypeInfo : public CommonEntityInfo {
+  /// The Swift type to which a given type is bridged.
+  ///
+  /// Reflects the swift_bridge attribute.
+  Optional<std::string> SwiftBridge;
+
+  /// The NS error domain for this type.
+  Optional<std::string> NSErrorDomain;
+
+public:
+  CommonTypeInfo() : CommonEntityInfo() { }
+
+  const Optional<std::string> &getSwiftBridge() const { return SwiftBridge; }
+
+  void setSwiftBridge(const Optional<std::string> &swiftType) {
+    SwiftBridge = swiftType;
+  }
+
+  void setSwiftBridge(const Optional<StringRef> &swiftType) {
+    if (swiftType)
+      SwiftBridge = *swiftType;
+    else
+      SwiftBridge = None;
+  }
+
+  const Optional<std::string> &getNSErrorDomain() const {
+    return NSErrorDomain;
+  }
+
+  void setNSErrorDomain(const Optional<std::string> &domain) {
+    NSErrorDomain = domain;
+  }
+
+  void setNSErrorDomain(const Optional<StringRef> &domain) {
+    if (domain)
+      NSErrorDomain = *domain;
+    else
+      NSErrorDomain = None;
+  }
+
+  friend CommonTypeInfo &operator|=(CommonTypeInfo &lhs,
+                                    const CommonTypeInfo &rhs) {
+    static_cast<CommonEntityInfo &>(lhs) |= rhs;
+    if (!lhs.SwiftBridge && rhs.SwiftBridge)
+      lhs.SwiftBridge = rhs.SwiftBridge;
+    if (!lhs.NSErrorDomain && rhs.NSErrorDomain)
+      lhs.NSErrorDomain = rhs.NSErrorDomain;
+    return lhs;
+  }
+
+  friend bool operator==(const CommonTypeInfo &lhs,
+                         const CommonTypeInfo &rhs) {
+    return static_cast<const CommonEntityInfo &>(lhs) == rhs &&
+      lhs.SwiftBridge == rhs.SwiftBridge &&
+      lhs.NSErrorDomain == rhs.NSErrorDomain;
+  }
+
+  friend bool operator!=(const CommonTypeInfo &lhs,
+                         const CommonTypeInfo &rhs) {
+    return !(lhs == rhs);
+  }
+};
+
+/// Describes API notes data for an Objective-C class or protocol.
+class ObjCContextInfo : public CommonTypeInfo {
+  /// Whether this class has a default nullability.
+  unsigned HasDefaultNullability : 1;
+
+  /// The default nullability.
+  unsigned DefaultNullability : 2;
+
+  /// Whether this class has designated initializers recorded.
+  unsigned HasDesignatedInits : 1;
+
+  unsigned SwiftImportAsNonGenericSpecified : 1;
+  unsigned SwiftImportAsNonGeneric : 1;
+
+  unsigned SwiftObjCMembersSpecified : 1;
+  unsigned SwiftObjCMembers : 1;
+
+public:
+  ObjCContextInfo()
+    : CommonTypeInfo(),
+      HasDefaultNullability(0),
+      DefaultNullability(0),
+      HasDesignatedInits(0),
+      SwiftImportAsNonGenericSpecified(false),
+      SwiftImportAsNonGeneric(false),
+      SwiftObjCMembersSpecified(false),
+      SwiftObjCMembers(false)
+  { }
+
+  /// Determine the default nullability for properties and methods of this
+  /// class.
+  ///
+  /// \returns the default nullability, if implied, or None if there is no
+  Optional<NullabilityKind> getDefaultNullability() const {
+    if (HasDefaultNullability)
+      return static_cast<NullabilityKind>(DefaultNullability);
+
+    return None;
+  }
+
+  /// Set the default nullability for properties and methods of this class.
+  void setDefaultNullability(NullabilityKind kind) {
+    HasDefaultNullability = true;
+    DefaultNullability = static_cast<unsigned>(kind);
+  }
+
+  bool hasDesignatedInits() const { return HasDesignatedInits; }
+  void setHasDesignatedInits(bool value) { HasDesignatedInits = value; }
+
+  Optional<bool> getSwiftImportAsNonGeneric() const {
+    if (SwiftImportAsNonGenericSpecified)
+      return SwiftImportAsNonGeneric;
+    return None;
+  }
+  void setSwiftImportAsNonGeneric(Optional<bool> value) {
+    if (value.hasValue()) {
+      SwiftImportAsNonGenericSpecified = true;
+      SwiftImportAsNonGeneric = value.getValue();
+    } else {
+      SwiftImportAsNonGenericSpecified = false;
+      SwiftImportAsNonGeneric = false;
+    }
+  }
+
+  Optional<bool> getSwiftObjCMembers() const {
+    if (SwiftObjCMembersSpecified)
+      return SwiftObjCMembers;
+    return None;
+  }
+  void setSwiftObjCMembers(Optional<bool> value) {
+    SwiftObjCMembersSpecified = value.hasValue();
+    SwiftObjCMembers = value.hasValue() ? *value : false;
+  }
+
+  /// Strip off any information within the class information structure that is
+  /// module-local, such as 'audited' flags.
+  void stripModuleLocalInfo() {
+    HasDefaultNullability = false;
+    DefaultNullability = 0;
+  }
+
+  friend bool operator==(const ObjCContextInfo &lhs, const ObjCContextInfo &rhs) {
+    return static_cast<const CommonTypeInfo &>(lhs) == rhs &&
+           lhs.getDefaultNullability() == rhs.getDefaultNullability() &&
+           lhs.HasDesignatedInits == rhs.HasDesignatedInits &&
+           lhs.getSwiftImportAsNonGeneric() ==
+             rhs.getSwiftImportAsNonGeneric() &&
+           lhs.getSwiftObjCMembers() == rhs.getSwiftObjCMembers();
+  }
+
+  friend bool operator!=(const ObjCContextInfo &lhs, const ObjCContextInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+  friend ObjCContextInfo &operator|=(ObjCContextInfo &lhs,
+                                     const ObjCContextInfo &rhs) {
+    // Merge inherited info.
+    static_cast<CommonTypeInfo &>(lhs) |= rhs;
+
+    // Merge nullability.
+    if (!lhs.getDefaultNullability()) {
+      if (auto nullable = rhs.getDefaultNullability()) {
+        lhs.setDefaultNullability(*nullable);
+      }
+    }
+
+    if (!lhs.SwiftImportAsNonGenericSpecified &&
+        rhs.SwiftImportAsNonGenericSpecified) {
+      lhs.SwiftImportAsNonGenericSpecified = true;
+      lhs.SwiftImportAsNonGeneric = rhs.SwiftImportAsNonGeneric;
+    }
+
+    if (!lhs.SwiftObjCMembersSpecified && rhs.SwiftObjCMembersSpecified) {
+      lhs.SwiftObjCMembersSpecified = true;
+      lhs.SwiftObjCMembers = rhs.SwiftObjCMembers;
+    }
+
+    lhs.HasDesignatedInits |= rhs.HasDesignatedInits;
+
+    return lhs;
+  }
+  
+  void dump(llvm::raw_ostream &os);
+};
+
+/// API notes for a variable/property.
+class VariableInfo : public CommonEntityInfo {
+  /// Whether this property has been audited for nullability.
+  unsigned NullabilityAudited : 1;
+
+  /// The kind of nullability for this property. Only valid if the nullability
+  /// has been audited.
+  unsigned Nullable : 2;
+
+  /// The C type of the variable, as a string.
+  std::string Type;
+
+public:
+  VariableInfo()
+    : CommonEntityInfo(),
+      NullabilityAudited(false),
+      Nullable(0) { }
+
+  Optional<NullabilityKind> getNullability() const {
+    if (NullabilityAudited)
+      return static_cast<NullabilityKind>(Nullable);
+
+    return None;
+  }
+
+  void setNullabilityAudited(NullabilityKind kind) {
+    NullabilityAudited = true;
+    Nullable = static_cast<unsigned>(kind);
+  }
+
+  const std::string &getType() const { return Type; }
+  void setType(const std::string &type) { Type = type; }
+
+  friend bool operator==(const VariableInfo &lhs, const VariableInfo &rhs) {
+    return static_cast<const CommonEntityInfo &>(lhs) == rhs &&
+           lhs.NullabilityAudited == rhs.NullabilityAudited &&
+           lhs.Nullable == rhs.Nullable &&
+           lhs.Type == rhs.Type;
+  }
+
+  friend bool operator!=(const VariableInfo &lhs, const VariableInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+  friend VariableInfo &operator|=(VariableInfo &lhs,
+                                  const VariableInfo &rhs) {
+    static_cast<CommonEntityInfo &>(lhs) |= rhs;
+    if (!lhs.NullabilityAudited && rhs.NullabilityAudited)
+      lhs.setNullabilityAudited(*rhs.getNullability());
+    if (lhs.Type.empty() && !rhs.Type.empty())
+      lhs.Type = rhs.Type;
+    return lhs;
+  }
+};
+
+/// Describes API notes data for an Objective-C property.
+class ObjCPropertyInfo : public VariableInfo {
+  unsigned SwiftImportAsAccessorsSpecified : 1;
+  unsigned SwiftImportAsAccessors : 1;
+
+public:
+  ObjCPropertyInfo()
+      : VariableInfo(), SwiftImportAsAccessorsSpecified(false),
+        SwiftImportAsAccessors(false) {}
+
+  /// Merge class-wide information into the given property.
+  friend ObjCPropertyInfo &operator|=(ObjCPropertyInfo &lhs,
+                                      const ObjCContextInfo &rhs) {
+    static_cast<VariableInfo &>(lhs) |= rhs;
+
+    // Merge nullability.
+    if (!lhs.getNullability()) {
+      if (auto nullable = rhs.getDefaultNullability()) {
+        lhs.setNullabilityAudited(*nullable);
+      }
+    }
+
+    return lhs;
+  }
+
+  Optional<bool> getSwiftImportAsAccessors() const {
+    if (SwiftImportAsAccessorsSpecified)
+      return SwiftImportAsAccessors;
+    return None;
+  }
+  void setSwiftImportAsAccessors(Optional<bool> value) {
+    if (value.hasValue()) {
+      SwiftImportAsAccessorsSpecified = true;
+      SwiftImportAsAccessors = value.getValue();
+    } else {
+      SwiftImportAsAccessorsSpecified = false;
+      SwiftImportAsAccessors = false;
+    }
+  }
+
+  friend ObjCPropertyInfo &operator|=(ObjCPropertyInfo &lhs,
+                                      const ObjCPropertyInfo &rhs) {
+    lhs |= static_cast<const VariableInfo &>(rhs);
+    if (!lhs.SwiftImportAsAccessorsSpecified &&
+        rhs.SwiftImportAsAccessorsSpecified) {
+      lhs.SwiftImportAsAccessorsSpecified = true;
+      lhs.SwiftImportAsAccessors = rhs.SwiftImportAsAccessors;
+    }
+    return lhs;
+  }
+
+  friend bool operator==(const ObjCPropertyInfo &lhs,
+                         const ObjCPropertyInfo &rhs) {
+    return static_cast<const VariableInfo &>(lhs) == rhs &&
+           lhs.getSwiftImportAsAccessors() == rhs.getSwiftImportAsAccessors();
+  }
+};
+
+/// Describes a function or method parameter.
+class ParamInfo : public VariableInfo {
+  /// Whether noescape was specified.
+  unsigned NoEscapeSpecified : 1;
+
+  /// Whether the this parameter has the 'noescape' attribute.
+  unsigned NoEscape : 1;
+
+public:
+  ParamInfo() : VariableInfo(), NoEscapeSpecified(false), NoEscape(false) { }
+
+  Optional<bool> isNoEscape() const {
+    if (!NoEscapeSpecified) return None;
+    return NoEscape;
+  }
+  void setNoEscape(Optional<bool> noescape) {
+    if (noescape) {
+      NoEscapeSpecified = true;
+      NoEscape = *noescape;
+    } else {
+      NoEscapeSpecified = false;
+      NoEscape = false;
+    }
+  }
+
+  friend ParamInfo &operator|=(ParamInfo &lhs, const ParamInfo &rhs) {
+    static_cast<VariableInfo &>(lhs) |= rhs;
+    if (!lhs.NoEscapeSpecified && rhs.NoEscapeSpecified) {
+      lhs.NoEscapeSpecified = true;
+      lhs.NoEscape = rhs.NoEscape;
+    }
+    return lhs;
+  }
+
+  friend bool operator==(const ParamInfo &lhs, const ParamInfo &rhs) {
+    return static_cast<const VariableInfo &>(lhs) == rhs &&
+           lhs.NoEscapeSpecified == rhs.NoEscapeSpecified &&
+           lhs.NoEscape == rhs.NoEscape;
+  }
+
+  friend bool operator!=(const ParamInfo &lhs, const ParamInfo &rhs) {
+    return !(lhs == rhs);
+  }
+};
+
+/// A temporary reference to an Objective-C selector, suitable for
+/// referencing selector data on the stack.
+///
+/// Instances of this struct do not store references to any of the
+/// data they contain; it is up to the user to ensure that the data
+/// referenced by the identifier list persists.
+struct ObjCSelectorRef {
+  unsigned NumPieces;
+  ArrayRef<StringRef> Identifiers;
+};
+
+/// API notes for a function or method.
+class FunctionInfo : public CommonEntityInfo {
+private:
+  static unsigned const NullabilityKindMask = 0x3;
+  static unsigned const NullabilityKindSize = 2;
+
+public:
+  /// Whether the signature has been audited with respect to nullability.
+  /// If yes, we consider all types to be non-nullable unless otherwise noted.
+  /// If this flag is not set, the pointer types are considered to have
+  /// unknown nullability.
+  unsigned NullabilityAudited : 1;
+
+  /// Number of types whose nullability is encoded with the NullabilityPayload.
+  unsigned NumAdjustedNullable : 8;
+
+  /// Stores the nullability of the return type and the parameters.
+  //  NullabilityKindSize bits are used to encode the nullability. The info
+  //  about the return type is stored at position 0, followed by the nullability
+  //  of the parameters.
+  uint64_t NullabilityPayload = 0;
+
+  /// The result type of this function, as a C type.
+  std::string ResultType;
+
+  /// The function parameters.
+  std::vector<ParamInfo> Params;
+
+  FunctionInfo()
+    : CommonEntityInfo(),
+      NullabilityAudited(false),
+      NumAdjustedNullable(0) { }
+
+  static unsigned getMaxNullabilityIndex() {
+    return ((sizeof(NullabilityPayload) * CHAR_BIT)/NullabilityKindSize);
+  }
+
+  void addTypeInfo(unsigned index, NullabilityKind kind) {
+    assert(index <= getMaxNullabilityIndex());
+    assert(static_cast<unsigned>(kind) < NullabilityKindMask);
+    NullabilityAudited = true;
+    if (NumAdjustedNullable < index + 1)
+      NumAdjustedNullable = index + 1;
+
+    // Mask the bits.
+    NullabilityPayload &= ~(NullabilityKindMask << (index * NullabilityKindSize));
+
+    // Set the value.
+    unsigned kindValue =
+      (static_cast<unsigned>(kind)) << (index * NullabilityKindSize);
+    NullabilityPayload |= kindValue;
+  }
+
+  /// Adds the return type info.
+  void addReturnTypeInfo(NullabilityKind kind) {
+    addTypeInfo(0, kind);
+  }
+
+  /// Adds the parameter type info.
+  void addParamTypeInfo(unsigned index, NullabilityKind kind) {
+    addTypeInfo(index + 1, kind);
+  }
+
+private:
+  NullabilityKind getTypeInfo(unsigned index) const {
+    assert(NullabilityAudited &&
+           "Checking the type adjustment on non-audited method.");
+    // If we don't have info about this parameter, return the default.
+    if (index > NumAdjustedNullable)
+      return NullabilityKind::NonNull;
+    return static_cast<NullabilityKind>(( NullabilityPayload
+                                          >> (index * NullabilityKindSize) )
+                                         & NullabilityKindMask);
+  }
+
+public:
+  NullabilityKind getParamTypeInfo(unsigned index) const {
+    return getTypeInfo(index + 1);
+  }
+  
+  NullabilityKind getReturnTypeInfo() const {
+    return getTypeInfo(0);
+  }
+
+  friend bool operator==(const FunctionInfo &lhs, const FunctionInfo &rhs) {
+    return static_cast<const CommonEntityInfo &>(lhs) == rhs &&
+           lhs.NullabilityAudited == rhs.NullabilityAudited &&
+           lhs.NumAdjustedNullable == rhs.NumAdjustedNullable &&
+           lhs.NullabilityPayload == rhs.NullabilityPayload &&
+           lhs.ResultType == rhs.ResultType &&
+           lhs.Params == rhs.Params;
+  }
+
+  friend bool operator!=(const FunctionInfo &lhs, const FunctionInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+};
+
+/// Describes API notes data for an Objective-C method.
+class ObjCMethodInfo : public FunctionInfo {
+public:
+  /// Whether this is a designated initializer of its class.
+  unsigned DesignatedInit : 1;
+
+  /// Whether this is a required initializer.
+  unsigned Required : 1;
+
+  ObjCMethodInfo()
+    : FunctionInfo(),
+      DesignatedInit(false),
+      Required(false) { }
+
+  friend bool operator==(const ObjCMethodInfo &lhs, const ObjCMethodInfo &rhs) {
+    return static_cast<const FunctionInfo &>(lhs) == rhs &&
+           lhs.DesignatedInit == rhs.DesignatedInit &&
+           lhs.Required == rhs.Required;
+  }
+
+  friend bool operator!=(const ObjCMethodInfo &lhs, const ObjCMethodInfo &rhs) {
+    return !(lhs == rhs);
+  }
+
+  void mergePropInfoIntoSetter(const ObjCPropertyInfo &pInfo);
+
+  void mergePropInfoIntoGetter(const ObjCPropertyInfo &pInfo);
+
+  /// Merge class-wide information into the given method.
+  friend ObjCMethodInfo &operator|=(ObjCMethodInfo &lhs,
+                                    const ObjCContextInfo &rhs) {
+    // Merge nullability.
+    if (!lhs.NullabilityAudited) {
+      if (auto nullable = rhs.getDefaultNullability()) {
+        lhs.NullabilityAudited = true;
+        lhs.addTypeInfo(0, *nullable);
+      }
+    }
+
+    return lhs;
+  }
+
+  void dump(llvm::raw_ostream &os);
+};
+
+/// Describes API notes data for a global variable.
+class GlobalVariableInfo : public VariableInfo {
+public:
+  GlobalVariableInfo() : VariableInfo() { }
+};
+
+/// Describes API notes data for a global function.
+class GlobalFunctionInfo : public FunctionInfo {
+public:
+  GlobalFunctionInfo() : FunctionInfo() { }
+};
+
+/// Describes API notes data for an enumerator.
+class EnumConstantInfo : public CommonEntityInfo {
+public:
+  EnumConstantInfo() : CommonEntityInfo() { }
+};
+
+/// The payload for an enum_extensibility attribute. This is a tri-state rather
+/// than just a boolean because the presence of the attribute indicates
+/// auditing.
+enum class EnumExtensibilityKind {
+  None,
+  Open,
+  Closed,
+};
+
+/// Describes API notes data for a tag.
+class TagInfo : public CommonTypeInfo {
+  unsigned HasFlagEnum : 1;
+  unsigned IsFlagEnum : 1;
+public:
+  Optional<EnumExtensibilityKind> EnumExtensibility;
+
+  Optional<bool> isFlagEnum() const {
+    if (HasFlagEnum)
+      return IsFlagEnum;
+    return None;
+  }
+  void setFlagEnum(Optional<bool> Value) {
+    if (Value.hasValue()) {
+      HasFlagEnum = true;
+      IsFlagEnum = Value.getValue();
+    } else {
+      HasFlagEnum = false;
+    }
+  }
+
+  TagInfo() : CommonTypeInfo(), HasFlagEnum(0), IsFlagEnum(0) { }
+
+  friend TagInfo &operator|=(TagInfo &lhs, const TagInfo &rhs) {
+    lhs |= static_cast<const CommonTypeInfo &>(rhs);
+    if (!lhs.HasFlagEnum && rhs.HasFlagEnum) {
+      lhs.HasFlagEnum = true;
+      lhs.IsFlagEnum = rhs.IsFlagEnum;
+    }
+    if (!lhs.EnumExtensibility.hasValue() && rhs.EnumExtensibility.hasValue())
+      lhs.EnumExtensibility = rhs.EnumExtensibility;
+    return lhs;
+  }
+
+  friend bool operator==(const TagInfo &lhs, const TagInfo &rhs) {
+    return static_cast<const CommonTypeInfo &>(lhs) == rhs &&
+           lhs.isFlagEnum() == rhs.isFlagEnum() &&
+           lhs.EnumExtensibility == rhs.EnumExtensibility;
+  }
+};
+
+/// The kind of a swift_wrapper/swift_newtype.
+enum class SwiftWrapperKind {
+  None,
+  Struct,
+  Enum
+};
+
+/// Describes API notes data for a typedef.
+class TypedefInfo : public CommonTypeInfo {
+public:
+  Optional<SwiftWrapperKind> SwiftWrapper;
+
+  TypedefInfo() : CommonTypeInfo() { }
+
+  friend TypedefInfo &operator|=(TypedefInfo &lhs, const TypedefInfo &rhs) {
+    lhs |= static_cast<const CommonTypeInfo &>(rhs);
+    if (!lhs.SwiftWrapper.hasValue() && rhs.SwiftWrapper.hasValue())
+      lhs.SwiftWrapper = rhs.SwiftWrapper;
+    return lhs;
+  }
+
+  friend bool operator==(const TypedefInfo &lhs, const TypedefInfo &rhs) {
+    return static_cast<const CommonTypeInfo &>(lhs) == rhs &&
+           lhs.SwiftWrapper == rhs.SwiftWrapper;
+  }
+};
+
+/// Descripts a series of options for a module
+struct ModuleOptions {
+  bool SwiftInferImportAsMember = false;
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+#endif // LLVM_CLANG_API_NOTES_TYPES_H
diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h
new file mode 100644
index 0000000..770bb57
--- /dev/null
+++ b/include/clang/AST/ASTStructuralEquivalence.h
@@ -0,0 +1,101 @@
+//===--- ASTStructuralEquivalence.h - ---------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines the StructuralEquivalenceContext class which checks for
+//  structural equivalence between types.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
+#define LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/Optional.h"
+#include <deque>
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class DiagnosticBuilder;
+class QualType;
+class RecordDecl;
+class SourceLocation;
+
+struct StructuralEquivalenceContext {
+  /// AST contexts for which we are checking structural equivalence.
+  ASTContext &FromCtx, &ToCtx;
+
+  /// The set of "tentative" equivalences between two canonical
+  /// declarations, mapping from a declaration in the first context to the
+  /// declaration in the second context that we believe to be equivalent.
+  llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
+
+  /// Queue of declarations in the first context whose equivalence
+  /// with a declaration in the second context still needs to be verified.
+  std::deque<Decl *> DeclsToCheck;
+
+  /// Declaration (from, to) pairs that are known not to be equivalent
+  /// (which we have already complained about).
+  llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls;
+
+  /// Whether we're being strict about the spelling of types when
+  /// unifying two types.
+  bool StrictTypeSpelling;
+
+  /// Whether warn or error on tag type mismatches.
+  bool ErrorOnTagTypeMismatch;
+
+  /// Whether to complain about failures.
+  bool Complain;
+
+  /// \c true if the last diagnostic came from ToCtx.
+  bool LastDiagFromC2;
+
+  StructuralEquivalenceContext(
+      ASTContext &FromCtx, ASTContext &ToCtx,
+      llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
+      bool StrictTypeSpelling = false, bool Complain = true)
+      : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
+        StrictTypeSpelling(StrictTypeSpelling), Complain(Complain),
+        LastDiagFromC2(false) {}
+
+  DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
+  DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
+
+  /// Determine whether the two declarations are structurally
+  /// equivalent.
+  bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
+
+  /// Determine whether the two types are structurally equivalent.
+  bool IsStructurallyEquivalent(QualType T1, QualType T2);
+
+  /// Find the index of the given anonymous struct/union within its
+  /// context.
+  ///
+  /// \returns Returns the index of this anonymous struct/union in its context,
+  /// including the next assigned index (if none of them match). Returns an
+  /// empty option if the context is not a record, i.e.. if the anonymous
+  /// struct/union is at namespace or block scope.
+  ///
+  /// FIXME: This is needed by ASTImporter and ASTStructureEquivalence. It
+  /// probably makes more sense in some other common place then here.
+  static llvm::Optional<unsigned>
+  findUntaggedStructOrUnionIndex(RecordDecl *Anon);
+
+private:
+  /// Finish checking all of the structural equivalences.
+  ///
+  /// \returns true if an error occurred, false otherwise.
+  bool Finish();
+};
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index bbe320c..58566db 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -24,6 +24,7 @@
 #include "clang/Basic/Sanitizers.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/PointerEmbeddedInt.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index fb9b049..5ef250c 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -108,6 +108,8 @@
                          specific_attr_iterator Right) {
     return !(Left == Right);
   }
+
+  Iterator getCurrent() const { return Current; }
 };
 
 template <typename SpecificAttr, typename Container>
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 3cf058f..9806085 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -127,7 +127,11 @@
   /// class subobjects for that class type. The key of the map is
   /// the cv-unqualified canonical type of the base class subobject.
   llvm::SmallDenseMap<QualType, std::pair<bool, unsigned>, 8> ClassSubobjects;
-  
+
+  /// VisitedDependentRecords - Records the dependent records that have been
+  /// already visited.
+  llvm::SmallDenseSet<const CXXRecordDecl *, 4> VisitedDependentRecords;
+
   /// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
   /// ambiguous paths while it is looking for a path from a derived
   /// type to a base type.
@@ -161,7 +165,8 @@
   void ComputeDeclsFound();
 
   bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
-                     CXXRecordDecl::BaseMatchesCallback BaseMatches);
+                     CXXRecordDecl::BaseMatchesCallback BaseMatches,
+                     bool LookupInDependent = false);
 
 public:
   typedef std::list<CXXBasePath>::iterator paths_iterator;
diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h
index 6a80383..230e527 100644
--- a/include/clang/AST/CommentSema.h
+++ b/include/clang/AST/CommentSema.h
@@ -208,6 +208,10 @@
   /// \returns \c true if declaration that this comment is attached to declares
   /// a function pointer.
   bool isFunctionPointerVarDecl();
+  /// \returns \c true if the declaration that this comment is attached to
+  /// declares a variable or a field whose type is a function or a block
+  /// pointer.
+  bool isFunctionOrBlockPointerVarLikeDecl();
   bool isFunctionOrMethodVariadic();
   bool isObjCMethodDecl();
   bool isObjCPropertyDecl();
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 8b52891..5446782 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -2635,12 +2635,17 @@
   typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
   llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
 
+  // FIXME: This can be packed into the bitfields in Decl.
+  /// If 0, we have not computed IsTransparentTag.
+  /// Otherwise, IsTransparentTag is (CacheIsTransparentTag >> 1).
+  mutable unsigned CacheIsTransparentTag : 2;
+
 protected:
   TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
                   SourceLocation StartLoc, SourceLocation IdLoc,
                   IdentifierInfo *Id, TypeSourceInfo *TInfo)
       : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
-        MaybeModedTInfo(TInfo) {}
+        MaybeModedTInfo(TInfo), CacheIsTransparentTag(0) {}
 
   typedef Redeclarable<TypedefNameDecl> redeclarable_base;
   TypedefNameDecl *getNextRedeclarationImpl() override {
@@ -2693,11 +2698,22 @@
   /// this typedef declaration.
   TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const;
 
+  /// Determines if this typedef shares a name and spelling location with its
+  /// underlying tag type, as is the case with the NS_ENUM macro.
+  bool isTransparentTag() const {
+    if (CacheIsTransparentTag)
+      return CacheIsTransparentTag & 0x2;
+    return isTransparentTagSlow();
+  }
+
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) {
     return K >= firstTypedefName && K <= lastTypedefName;
   }
+
+private:
+  bool isTransparentTagSlow() const;
 };
 
 /// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
@@ -3229,6 +3245,18 @@
     return isCompleteDefinition() || isFixed();
   }
 
+  /// Returns true if this enum is either annotated with
+  /// enum_extensibility(closed) or isn't annotated with enum_extensibility.
+  bool isClosed() const;
+
+  /// Returns true if this enum is annotated with flag_enum and isn't annotated
+  /// with enum_extensibility(open).
+  bool isClosedFlag() const;
+
+  /// Returns true if this enum is annotated with neither flag_enum nor
+  /// enum_extensibility(open).
+  bool isClosedNonFlag() const;
+
   /// \brief Retrieve the enum definition from which this enumeration could
   /// be instantiated, if it is an instantiation (rather than a non-template).
   EnumDecl *getTemplateInstantiationPattern() const;
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 5de1d05..bcc2bc0 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -34,6 +34,7 @@
 class DependentDiagnostic;
 class EnumDecl;
 class ExportDecl;
+class ExternalSourceSymbolAttr;
 class FunctionDecl;
 class FunctionType;
 enum Linkage : unsigned char;
@@ -562,6 +563,10 @@
     NextInContextAndBits.setInt(Bits);
   }
 
+  /// \brief Looks on this and related declarations for an applicable
+  /// external source symbol attribute.
+  ExternalSourceSymbolAttr *getExternalSourceSymbolAttr() const;
+
   /// \brief Whether this declaration was marked as being private to the
   /// module in which it was defined.
   bool isModulePrivate() const {
@@ -616,6 +621,14 @@
   getAvailability(std::string *Message = nullptr,
                   VersionTuple EnclosingVersion = VersionTuple()) const;
 
+  /// \brief Retrieve the version of the target platform in which this
+  /// declaration was introduced.
+  ///
+  /// \returns An empty version tuple if this declaration has no 'introduced'
+  /// availability attributes, or the version tuple that's specified in the
+  /// attribute otherwise.
+  VersionTuple getVersionIntroduced() const;
+
   /// \brief Determine whether this declaration is marked 'deprecated'.
   ///
   /// \param Message If non-NULL and the declaration is deprecated,
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 0ca08db..508990d 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1548,10 +1548,13 @@
   /// \param Paths used to record the paths from this class to its base class
   /// subobjects that match the search criteria.
   ///
+  /// \param LookupInDependent can be set to true to extend the search to
+  /// dependent base classes.
+  ///
   /// \returns true if there exists any path from this class to a base class
   /// subobject that matches the search criteria.
-  bool lookupInBases(BaseMatchesCallback BaseMatches,
-                     CXXBasePaths &Paths) const;
+  bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths,
+                     bool LookupInDependent = false) const;
 
   /// \brief Base-class lookup callback that determines whether the given
   /// base class specifier refers to a specific class declaration.
@@ -1593,6 +1596,16 @@
                                  CXXBasePath &Path, DeclarationName Name);
 
   /// \brief Base-class lookup callback that determines whether there exists
+  /// a member with the given name.
+  ///
+  /// This callback can be used with \c lookupInBases() to find members
+  /// of the given name within a C++ class hierarchy, including dependent
+  /// classes.
+  static bool
+  FindOrdinaryMemberInDependentClasses(const CXXBaseSpecifier *Specifier,
+                                       CXXBasePath &Path, DeclarationName Name);
+
+  /// \brief Base-class lookup callback that determines whether there exists
   /// an OpenMP declare reduction member with the given name.
   ///
   /// This callback can be used with \c lookupInBases() to find members
@@ -1618,6 +1631,14 @@
   /// \brief Get the indirect primary bases for this class.
   void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
 
+  /// Performs an imprecise lookup of a dependent name in this class.
+  ///
+  /// This function does not follow strict semantic rules and should be used
+  /// only when lookup rules can be relaxed, e.g. indexing.
+  std::vector<const NamedDecl *>
+  lookupDependentName(const DeclarationName &Name,
+                      llvm::function_ref<bool(const NamedDecl *ND)> Filter);
+
   /// Renders and displays an inheritance diagram
   /// for this C++ class and all of its base classes (transitively) using
   /// GraphViz.
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index f5098f0..c2a09cd 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -743,6 +743,8 @@
 
   Selector GetterName;    // getter name of NULL if no getter
   Selector SetterName;    // setter name of NULL if no setter
+  SourceLocation GetterNameLoc; // location of the getter attribute's value
+  SourceLocation SetterNameLoc; // location of the setter attribute's value
 
   ObjCMethodDecl *GetterMethodDecl; // Declaration of getter instance method
   ObjCMethodDecl *SetterMethodDecl; // Declaration of setter instance method
@@ -855,10 +857,18 @@
   }
 
   Selector getGetterName() const { return GetterName; }
-  void setGetterName(Selector Sel) { GetterName = Sel; }
+  SourceLocation getGetterNameLoc() const { return GetterNameLoc; }
+  void setGetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
+    GetterName = Sel;
+    GetterNameLoc = Loc;
+  }
 
   Selector getSetterName() const { return SetterName; }
-  void setSetterName(Selector Sel) { SetterName = Sel; }
+  SourceLocation getSetterNameLoc() const { return SetterNameLoc; }
+  void setSetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
+    SetterName = Sel;
+    SetterNameLoc = Loc;
+  }
 
   ObjCMethodDecl *getGetterMethodDecl() const { return GetterMethodDecl; }
   void setGetterMethodDecl(ObjCMethodDecl *gDecl) { GetterMethodDecl = gDecl; }
@@ -2320,11 +2330,9 @@
 protected:
   ObjCImplDecl(Kind DK, DeclContext *DC,
                ObjCInterfaceDecl *classInterface,
+               IdentifierInfo *Id,
                SourceLocation nameLoc, SourceLocation atStartLoc)
-    : ObjCContainerDecl(DK, DC,
-                        classInterface? classInterface->getIdentifier()
-                                      : nullptr,
-                        nameLoc, atStartLoc),
+    : ObjCContainerDecl(DK, DC, Id, nameLoc, atStartLoc),
       ClassInterface(classInterface) {}
 
 public:
@@ -2386,9 +2394,6 @@
 class ObjCCategoryImplDecl : public ObjCImplDecl {
   void anchor() override;
 
-  // Category name
-  IdentifierInfo *Id;
-
   // Category name location
   SourceLocation CategoryNameLoc;
 
@@ -2396,8 +2401,9 @@
                        ObjCInterfaceDecl *classInterface,
                        SourceLocation nameLoc, SourceLocation atStartLoc,
                        SourceLocation CategoryNameLoc)
-    : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, nameLoc, atStartLoc),
-      Id(Id), CategoryNameLoc(CategoryNameLoc) {}
+    : ObjCImplDecl(ObjCCategoryImpl, DC, classInterface, Id,
+                   nameLoc, atStartLoc),
+      CategoryNameLoc(CategoryNameLoc) {}
 public:
   static ObjCCategoryImplDecl *Create(ASTContext &C, DeclContext *DC,
                                       IdentifierInfo *Id,
@@ -2407,37 +2413,10 @@
                                       SourceLocation CategoryNameLoc);
   static ObjCCategoryImplDecl *CreateDeserialized(ASTContext &C, unsigned ID);
 
-  /// getIdentifier - Get the identifier that names the category
-  /// interface associated with this implementation.
-  /// FIXME: This is a bad API, we are hiding NamedDecl::getIdentifier()
-  /// with a different meaning. For example:
-  /// ((NamedDecl *)SomeCategoryImplDecl)->getIdentifier()
-  /// returns the class interface name, whereas
-  /// ((ObjCCategoryImplDecl *)SomeCategoryImplDecl)->getIdentifier()
-  /// returns the category name.
-  IdentifierInfo *getIdentifier() const {
-    return Id;
-  }
-  void setIdentifier(IdentifierInfo *II) { Id = II; }
-
   ObjCCategoryDecl *getCategoryDecl() const;
 
   SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; }
 
-  /// getName - Get the name of identifier for the class interface associated
-  /// with this implementation as a StringRef.
-  //
-  // FIXME: This is a bad API, we are hiding NamedDecl::getName with a different
-  // meaning.
-  StringRef getName() const { return Id ? Id->getName() : StringRef(); }
-
-  /// @brief Get the name of the class associated with this interface.
-  //
-  // FIXME: Deprecated, move clients to getName().
-  std::string getNameAsString() const {
-    return getName();
-  }
-
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == ObjCCategoryImpl;}
 
@@ -2493,7 +2472,10 @@
                          SourceLocation superLoc = SourceLocation(),
                          SourceLocation IvarLBraceLoc=SourceLocation(), 
                          SourceLocation IvarRBraceLoc=SourceLocation())
-    : ObjCImplDecl(ObjCImplementation, DC, classInterface, nameLoc, atStartLoc),
+    : ObjCImplDecl(ObjCImplementation, DC, classInterface,
+                   classInterface ? classInterface->getIdentifier()
+                                  : nullptr,
+                   nameLoc, atStartLoc),
        SuperClass(superDecl), SuperLoc(superLoc), IvarLBraceLoc(IvarLBraceLoc),
        IvarRBraceLoc(IvarRBraceLoc),
        IvarInitializers(nullptr), NumIvarInitializers(0),
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 56b99cc..1ef6b42 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -2917,11 +2917,9 @@
 private:
   unsigned Opc : 6;
 
-  // Records the FP_CONTRACT pragma status at the point that this binary
-  // operator was parsed. This bit is only meaningful for operations on
-  // floating point types. For all other types it should default to
-  // false.
-  unsigned FPContractable : 1;
+  // This is only meaningful for operations on floating point types and 0
+  // otherwise.
+  unsigned FPFeatures : 2;
   SourceLocation OpLoc;
 
   enum { LHS, RHS, END_EXPR };
@@ -2930,7 +2928,7 @@
 
   BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
                  ExprValueKind VK, ExprObjectKind OK,
-                 SourceLocation opLoc, bool fpContractable)
+                 SourceLocation opLoc, FPOptions FPFeatures)
     : Expr(BinaryOperatorClass, ResTy, VK, OK,
            lhs->isTypeDependent() || rhs->isTypeDependent(),
            lhs->isValueDependent() || rhs->isValueDependent(),
@@ -2938,7 +2936,7 @@
             rhs->isInstantiationDependent()),
            (lhs->containsUnexpandedParameterPack() ||
             rhs->containsUnexpandedParameterPack())),
-      Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
+      Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
     SubExprs[LHS] = lhs;
     SubExprs[RHS] = rhs;
     assert(!isCompoundAssignmentOp() &&
@@ -3073,16 +3071,20 @@
 
   // Set the FP contractability status of this operator. Only meaningful for
   // operations on floating point types.
-  void setFPContractable(bool FPC) { FPContractable = FPC; }
+  void setFPFeatures(FPOptions F) { FPFeatures = F.getInt(); }
+
+  FPOptions getFPFeatures() const { return FPOptions(FPFeatures); }
 
   // Get the FP contractability status of this operator. Only meaningful for
   // operations on floating point types.
-  bool isFPContractable() const { return FPContractable; }
+  bool isFPContractableWithinStatement() const {
+    return FPOptions(FPFeatures).allowFPContractWithinStatement();
+  }
 
 protected:
   BinaryOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy,
                  ExprValueKind VK, ExprObjectKind OK,
-                 SourceLocation opLoc, bool fpContractable, bool dead2)
+                 SourceLocation opLoc, FPOptions FPFeatures, bool dead2)
     : Expr(CompoundAssignOperatorClass, ResTy, VK, OK,
            lhs->isTypeDependent() || rhs->isTypeDependent(),
            lhs->isValueDependent() || rhs->isValueDependent(),
@@ -3090,7 +3092,7 @@
             rhs->isInstantiationDependent()),
            (lhs->containsUnexpandedParameterPack() ||
             rhs->containsUnexpandedParameterPack())),
-      Opc(opc), FPContractable(fpContractable), OpLoc(opLoc) {
+      Opc(opc), FPFeatures(FPFeatures.getInt()), OpLoc(opLoc) {
     SubExprs[LHS] = lhs;
     SubExprs[RHS] = rhs;
   }
@@ -3112,8 +3114,8 @@
   CompoundAssignOperator(Expr *lhs, Expr *rhs, Opcode opc, QualType ResType,
                          ExprValueKind VK, ExprObjectKind OK,
                          QualType CompLHSType, QualType CompResultType,
-                         SourceLocation OpLoc, bool fpContractable)
-    : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, fpContractable,
+                         SourceLocation OpLoc, FPOptions FPFeatures)
+    : BinaryOperator(lhs, rhs, opc, ResType, VK, OK, OpLoc, FPFeatures,
                      true),
       ComputationLHSType(CompLHSType),
       ComputationResultType(CompResultType) {
diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index 37e5977..f0cc1e4 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -54,18 +54,16 @@
   OverloadedOperatorKind Operator;
   SourceRange Range;
 
-  // Record the FP_CONTRACT state that applies to this operator call. Only
-  // meaningful for floating point types. For other types this value can be
-  // set to false.
-  unsigned FPContractable : 1;
+  // Only meaningful for floating point types.
+  FPOptions FPFeatures;
 
   SourceRange getSourceRangeImpl() const LLVM_READONLY;
 public:
   CXXOperatorCallExpr(ASTContext& C, OverloadedOperatorKind Op, Expr *fn,
                       ArrayRef<Expr*> args, QualType t, ExprValueKind VK,
-                      SourceLocation operatorloc, bool fpContractable)
+                      SourceLocation operatorloc, FPOptions FPFeatures)
     : CallExpr(C, CXXOperatorCallExprClass, fn, args, t, VK, operatorloc),
-      Operator(Op), FPContractable(fpContractable) {
+      Operator(Op), FPFeatures(FPFeatures) {
     Range = getSourceRangeImpl();
   }
   explicit CXXOperatorCallExpr(ASTContext& C, EmptyShell Empty) :
@@ -113,11 +111,15 @@
 
   // Set the FP contractability status of this operator. Only meaningful for
   // operations on floating point types.
-  void setFPContractable(bool FPC) { FPContractable = FPC; }
+  void setFPFeatures(FPOptions F) { FPFeatures = F; }
+
+  FPOptions getFPFeatures() const { return FPFeatures; }
 
   // Get the FP contractability status of this operator. Only meaningful for
   // operations on floating point types.
-  bool isFPContractable() const { return FPContractable; }
+  bool isFPContractableWithinStatement() const {
+    return FPFeatures.allowFPContractWithinStatement();
+  }
 
   friend class ASTStmtReader;
   friend class ASTStmtWriter;
diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h
index 2e99f39..127c324 100644
--- a/include/clang/AST/ExternalASTSource.h
+++ b/include/clang/AST/ExternalASTSource.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H
 #define LLVM_CLANG_AST_EXTERNALASTSOURCE_H
 
+#include "clang/Basic/Module.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclBase.h"
 #include "llvm/ADT/DenseMap.h"
@@ -149,20 +150,20 @@
     StringRef PCHModuleName;
     StringRef Path;
     StringRef ASTFile;
-    uint64_t Signature = 0;
+    ASTFileSignature Signature;
     const Module *ClangModule = nullptr;
 
   public:
     ASTSourceDescriptor(){};
     ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile,
-                        uint64_t Signature)
+                        ASTFileSignature Signature)
         : PCHModuleName(std::move(Name)), Path(std::move(Path)),
           ASTFile(std::move(ASTFile)), Signature(Signature){};
     ASTSourceDescriptor(const Module &M);
     std::string getModuleName() const;
     StringRef getPath() const { return Path; }
     StringRef getASTFile() const { return ASTFile; }
-    uint64_t getSignature() const { return Signature; }
+    ASTFileSignature getSignature() const { return Signature; }
     const Module *getModuleOrNull() const { return ClangModule; }
   };
 
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 10a930a..2e41bc2 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -2305,7 +2305,7 @@
   }
 
   TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
-  FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
+  FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
 
   if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
     // Visit the whole type.
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index a50e054..7e1ad45 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -1020,6 +1020,9 @@
     return getQualifiers().hasStrongOrWeakObjCLifetime();
   }
 
+  // true when Type is objc's weak and weak is enabled but ARC isn't.
+  bool isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const;
+
   enum DestructionKind {
     DK_none,
     DK_cxx_destructor,
@@ -1875,6 +1878,13 @@
   /// immediately following this class.
   template <typename T> const T *getAs() const;
 
+  /// Member-template getAsAdjusted<specific type>. Look through specific kinds
+  /// of sugar (parens, attributes, etc) for an instance of \<specific type>.
+  /// This is used when you need to walk over sugar nodes that represent some
+  /// kind of type adjustment from a type that was written as a \<specific type>
+  /// to another type that is still canonically a \<specific type>.
+  template <typename T> const T *getAsAdjusted() const;
+
   /// A variant of getAs<> for array types which silently discards
   /// qualifiers from the outermost type.
   const ArrayType *getAsArrayTypeUnsafe() const;
@@ -5932,6 +5942,38 @@
   return cast<T>(getUnqualifiedDesugaredType());
 }
 
+template <typename T> const T *Type::getAsAdjusted() const {
+  static_assert(!TypeIsArrayType<T>::value, "ArrayType cannot be used with getAsAdjusted!");
+
+  // If this is directly a T type, return it.
+  if (const T *Ty = dyn_cast<T>(this))
+    return Ty;
+
+  // If the canonical form of this type isn't the right kind, reject it.
+  if (!isa<T>(CanonicalType))
+    return nullptr;
+
+  // Strip off type adjustments that do not modify the underlying nature of the
+  // type.
+  const Type *Ty = this;
+  while (Ty) {
+    if (const auto *A = dyn_cast<AttributedType>(Ty))
+      Ty = A->getModifiedType().getTypePtr();
+    else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
+      Ty = E->desugar().getTypePtr();
+    else if (const auto *P = dyn_cast<ParenType>(Ty))
+      Ty = P->desugar().getTypePtr();
+    else if (const auto *A = dyn_cast<AdjustedType>(Ty))
+      Ty = A->desugar().getTypePtr();
+    else
+      break;
+  }
+
+  // Just because the canonical type is correct does not mean we can use cast<>,
+  // since we may not have stripped off all the sugar down to the base type.
+  return dyn_cast<T>(Ty);
+}
+
 inline const ArrayType *Type::getAsArrayTypeUnsafe() const {
   // If this is directly an array type, return it.
   if (const ArrayType *arr = dyn_cast<ArrayType>(this))
diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 5b7d9e6..bbf3498 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -70,6 +70,13 @@
     return t;
   }
 
+  /// \brief Convert to the specified TypeLoc type, returning a null TypeLoc if
+  /// this TypeLock is not of the desired type. It will consider type
+  /// adjustments from a type that wad written as a T to another type that is
+  /// still canonically a T (ignores parens, attributes, elaborated types, etc).
+  template <typename T>
+  T getAsAdjusted() const;
+
   /// The kinds of TypeLocs.  Equivalent to the Type::TypeClass enum,
   /// except it also defines a Qualified enum that corresponds to the
   /// QualifiedLoc class.
@@ -2172,6 +2179,24 @@
 
   QualType getInnerType() const { return this->getTypePtr()->getElementType(); }
 };
+
+template <typename T>
+inline T TypeLoc::getAsAdjusted() const {
+  TypeLoc Cur = *this;
+  while (!T::isKind(Cur)) {
+    if (auto PTL = Cur.getAs<ParenTypeLoc>())
+      Cur = PTL.getInnerLoc();
+    else if (auto ATL = Cur.getAs<AttributedTypeLoc>())
+      Cur = ATL.getModifiedLoc();
+    else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
+      Cur = ETL.getNamedTypeLoc();
+    else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
+      Cur = ATL.getOriginalLoc();
+    else
+      break;
+  }
+  return Cur.getAs<T>();
+}
 }
 
 #endif
diff --git a/include/clang/Analysis/CallGraph.h b/include/clang/Analysis/CallGraph.h
index b8ae67c..a2a27a8 100644
--- a/include/clang/Analysis/CallGraph.h
+++ b/include/clang/Analysis/CallGraph.h
@@ -98,7 +98,7 @@
   bool VisitFunctionDecl(FunctionDecl *FD) {
     // We skip function template definitions, as their semantics is
     // only determined when they are instantiated.
-    if (includeInGraph(FD)) {
+    if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) {
       // Add all blocks declared inside this function to the graph.
       addNodesForBlocks(FD);
       // If this function has external linkage, anything could call it.
diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h
index 51cad7a..a433f70 100644
--- a/include/clang/Analysis/CloneDetection.h
+++ b/include/clang/Analysis/CloneDetection.h
@@ -16,9 +16,7 @@
 #define LLVM_CLANG_AST_CLONEDETECTION_H
 
 #include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/Hashing.h"
-#include "llvm/ADT/StringMap.h"
-
+#include "llvm/ADT/SmallVector.h"
 #include <vector>
 
 namespace clang {
@@ -29,7 +27,7 @@
 class ASTContext;
 class CompoundStmt;
 
-/// \brief Identifies a list of statements.
+/// Identifies a list of statements.
 ///
 /// Can either identify a single arbitrary Stmt object, a continuous sequence of
 /// child statements inside a CompoundStmt or no statements at all.
@@ -39,8 +37,8 @@
   /// Stmt, then S is a pointer to this Stmt.
   const Stmt *S;
 
-  /// The related ASTContext for S.
-  ASTContext *Context;
+  /// The declaration that contains the statements.
+  const Decl *D;
 
   /// If EndIndex is non-zero, then S is a CompoundStmt and this StmtSequence
   /// instance is representing the CompoundStmt children inside the array
@@ -49,7 +47,7 @@
   unsigned EndIndex;
 
 public:
-  /// \brief Constructs a StmtSequence holding multiple statements.
+  /// Constructs a StmtSequence holding multiple statements.
   ///
   /// The resulting StmtSequence identifies a continuous sequence of statements
   /// in the body of the given CompoundStmt. Which statements of the body should
@@ -57,20 +55,20 @@
   /// that describe a non-empty sub-array in the body of the given CompoundStmt.
   ///
   /// \param Stmt A CompoundStmt that contains all statements in its body.
-  /// \param Context The ASTContext for the given CompoundStmt.
+  /// \param Decl The Decl containing this Stmt.
   /// \param StartIndex The inclusive start index in the children array of
   ///                   \p Stmt
   /// \param EndIndex The exclusive end index in the children array of \p Stmt.
-  StmtSequence(const CompoundStmt *Stmt, ASTContext &Context,
-               unsigned StartIndex, unsigned EndIndex);
+  StmtSequence(const CompoundStmt *Stmt, const Decl *D, unsigned StartIndex,
+               unsigned EndIndex);
 
-  /// \brief Constructs a StmtSequence holding a single statement.
+  /// Constructs a StmtSequence holding a single statement.
   ///
   /// \param Stmt An arbitrary Stmt.
-  /// \param Context The ASTContext for the given Stmt.
-  StmtSequence(const Stmt *Stmt, ASTContext &Context);
+  /// \param Decl The Decl containing this Stmt.
+  StmtSequence(const Stmt *Stmt, const Decl *D);
 
-  /// \brief Constructs an empty StmtSequence.
+  /// Constructs an empty StmtSequence.
   StmtSequence();
 
   typedef const Stmt *const *iterator;
@@ -110,9 +108,12 @@
   bool empty() const { return size() == 0; }
 
   /// Returns the related ASTContext for the stored Stmts.
-  ASTContext &getASTContext() const {
-    assert(Context);
-    return *Context;
+  ASTContext &getASTContext() const;
+
+  /// Returns the declaration that contains the stored Stmts.
+  const Decl *getContainingDecl() const {
+    assert(D);
+    return D;
   }
 
   /// Returns true if this objects holds a list of statements.
@@ -150,106 +151,214 @@
   bool contains(const StmtSequence &Other) const;
 };
 
-/// \brief Searches for clones in source code.
+/// Searches for similar subtrees in the AST.
 ///
-/// First, this class needs a translation unit which is passed via
-/// \p analyzeTranslationUnit . It will then generate and store search data
-/// for all statements inside the given translation unit.
-/// Afterwards the generated data can be used to find code clones by calling
-/// \p findClones .
+/// First, this class needs several declarations with statement bodies which
+/// can be passed via analyzeCodeBody. Afterwards all statements can be
+/// searched for clones by calling findClones with a given list of constraints
+/// that should specify the wanted properties of the clones.
+///
+/// The result of findClones can be further constrained with the constrainClones
+/// method.
 ///
 /// This class only searches for clones in exectuable source code
 /// (e.g. function bodies). Other clones (e.g. cloned comments or declarations)
 /// are not supported.
 class CloneDetector {
+
 public:
-  typedef unsigned DataPiece;
+  /// A collection of StmtSequences that share an arbitrary property.
+  typedef llvm::SmallVector<StmtSequence, 8> CloneGroup;
 
-  /// Holds the data about a StmtSequence that is needed during the search for
-  /// code clones.
-  struct CloneSignature {
-    /// \brief The hash code of the StmtSequence.
-    ///
-    /// The initial clone groups that are formed during the search for clones
-    /// consist only of Sequences that share the same hash code. This makes this
-    /// value the central part of this heuristic that is needed to find clones
-    /// in a performant way. For this to work, the type of this variable
-    /// always needs to be small and fast to compare.
-    ///
-    /// Also, StmtSequences that are clones of each others have to share
-    /// the same hash code. StmtSequences that are not clones of each other
-    /// shouldn't share the same hash code, but if they do, it will only
-    /// degrade the performance of the hash search but doesn't influence
-    /// the correctness of the result.
-    size_t Hash;
-
-    /// \brief The complexity of the StmtSequence.
-    ///
-    /// This value gives an approximation on how many direct or indirect child
-    /// statements are contained in the related StmtSequence. In general, the
-    /// greater this value, the greater the amount of statements. However, this
-    /// is only an approximation and the actual amount of statements can be
-    /// higher or lower than this value. Statements that are generated by the
-    /// compiler (e.g. macro expansions) for example barely influence the
-    /// complexity value.
-    ///
-    /// The main purpose of this value is to filter clones that are too small
-    /// and therefore probably not interesting enough for the user.
-    unsigned Complexity;
-
-    /// \brief Creates an empty CloneSignature without any data.
-    CloneSignature() : Complexity(1) {}
-
-    CloneSignature(llvm::hash_code Hash, unsigned Complexity)
-        : Hash(Hash), Complexity(Complexity) {}
-  };
-
-  /// Holds group of StmtSequences that are clones of each other and the
-  /// complexity value (see CloneSignature::Complexity) that all stored
-  /// StmtSequences have in common.
-  struct CloneGroup {
-    std::vector<StmtSequence> Sequences;
-    CloneSignature Signature;
-
-    CloneGroup() {}
-
-    CloneGroup(const StmtSequence &Seq, CloneSignature Signature)
-        : Signature(Signature) {
-      Sequences.push_back(Seq);
-    }
-
-    /// \brief Returns false if and only if this group should be skipped when
-    ///        searching for clones.
-    bool isValid() const {
-      // A clone group with only one member makes no sense, so we skip them.
-      return Sequences.size() > 1;
-    }
-  };
-
-  /// \brief Generates and stores search data for all statements in the body of
-  ///        the given Decl.
+  /// Generates and stores search data for all statements in the body of
+  /// the given Decl.
   void analyzeCodeBody(const Decl *D);
 
-  /// \brief Stores the CloneSignature to allow future querying.
-  void add(const StmtSequence &S, const CloneSignature &Signature);
-
-  /// \brief Searches the provided statements for clones.
+  /// Constrains the given list of clone groups with the given constraint.
   ///
-  /// \param Result Output parameter that is filled with a list of found
-  ///               clone groups. Each group contains multiple StmtSequences
-  ///               that were identified to be clones of each other.
-  /// \param MinGroupComplexity Only return clones which have at least this
-  ///                           complexity value.
-  /// \param CheckPatterns Returns only clone groups in which the referenced
-  ///                      variables follow the same pattern.
-  void findClones(std::vector<CloneGroup> &Result, unsigned MinGroupComplexity,
-                  bool CheckPatterns = true);
+  /// The constraint is expected to have a method with the signature
+  ///     `void constrain(std::vector<CloneDetector::CloneGroup> &Sequences)`
+  /// as this is the interface that the CloneDetector uses for applying the
+  /// constraint. The constraint is supposed to directly modify the passed list
+  /// so that all clones in the list fulfill the specific property this
+  /// constraint ensures.
+  template <typename T>
+  static void constrainClones(std::vector<CloneGroup> &CloneGroups, T C) {
+    C.constrain(CloneGroups);
+  }
 
-  /// \brief Describes two clones that reference their variables in a different
-  ///        pattern which could indicate a programming error.
+  /// Constrains the given list of clone groups with the given list of
+  /// constraints.
+  ///
+  /// The constraints are applied in sequence in the order in which they are
+  /// passed to this function.
+  template <typename T1, typename... Ts>
+  static void constrainClones(std::vector<CloneGroup> &CloneGroups, T1 C,
+                              Ts... ConstraintList) {
+    constrainClones(CloneGroups, C);
+    constrainClones(CloneGroups, ConstraintList...);
+  }
+
+  /// Searches for clones in all previously passed statements.
+  /// \param Result Output parameter to which all created clone groups are
+  ///               added.
+  /// \param Passes The constraints that should be applied to the result.
+  template <typename... Ts>
+  void findClones(std::vector<CloneGroup> &Result, Ts... ConstraintList) {
+    // The initial assumption is that there is only one clone group and every
+    // statement is a clone of the others. This clone group will then be
+    // split up with the help of the constraints.
+    CloneGroup AllClones;
+    AllClones.reserve(Sequences.size());
+    for (const auto &C : Sequences) {
+      AllClones.push_back(C);
+    }
+
+    Result.push_back(AllClones);
+
+    constrainClones(Result, ConstraintList...);
+  }
+
+private:
+  CloneGroup Sequences;
+};
+
+/// This class is a utility class that contains utility functions for building
+/// custom constraints.
+class CloneConstraint {
+public:
+  /// Removes all groups by using a filter function.
+  /// \param CloneGroups The list of CloneGroups that is supposed to be
+  ///                    filtered.
+  /// \param Filter The filter function that should return true for all groups
+  ///               that should be removed from the list.
+  static void
+  filterGroups(std::vector<CloneDetector::CloneGroup> &CloneGroups,
+               std::function<bool(const CloneDetector::CloneGroup &)> Filter) {
+    CloneGroups.erase(
+        std::remove_if(CloneGroups.begin(), CloneGroups.end(), Filter),
+        CloneGroups.end());
+  }
+
+  /// Splits the given CloneGroups until the given Compare function returns true
+  /// for all clones in a single group.
+  /// \param CloneGroups A list of CloneGroups that should be modified.
+  /// \param Compare The comparison function that all clones are supposed to
+  ///                pass. Should return true if and only if two clones belong
+  ///                to the same CloneGroup.
+  static void splitCloneGroups(
+      std::vector<CloneDetector::CloneGroup> &CloneGroups,
+      std::function<bool(const StmtSequence &, const StmtSequence &)> Compare);
+};
+
+/// Searches all children of the given clones for type II clones (i.e. they are
+/// identical in every aspect beside the used variable names).
+class RecursiveCloneTypeIIConstraint {
+
+  /// Generates and saves a hash code for the given Stmt.
+  /// \param S The given Stmt.
+  /// \param D The Decl containing S.
+  /// \param StmtsByHash Output parameter that will contain the hash codes for
+  ///                    each StmtSequence in the given Stmt.
+  /// \return The hash code of the given Stmt.
+  ///
+  /// If the given Stmt is a CompoundStmt, this method will also generate
+  /// hashes for all possible StmtSequences in the children of this Stmt.
+  size_t saveHash(const Stmt *S, const Decl *D,
+                  std::vector<std::pair<size_t, StmtSequence>> &StmtsByHash);
+
+public:
+  void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
+};
+
+/// Ensures that every clone has at least the given complexity.
+///
+/// Complexity is here defined as the total amount of children of a statement.
+/// This constraint assumes the first statement in the group is representative
+/// for all other statements in the group in terms of complexity.
+class MinComplexityConstraint {
+  unsigned MinComplexity;
+
+public:
+  MinComplexityConstraint(unsigned MinComplexity)
+      : MinComplexity(MinComplexity) {}
+
+  size_t calculateStmtComplexity(const StmtSequence &Seq,
+                                 const std::string &ParentMacroStack = "");
+
+  void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
+    CloneConstraint::filterGroups(
+        CloneGroups, [this](const CloneDetector::CloneGroup &A) {
+          if (!A.empty())
+            return calculateStmtComplexity(A.front()) < MinComplexity;
+          else
+            return false;
+        });
+  }
+};
+
+/// Ensures that all clone groups contain at least the given amount of clones.
+class MinGroupSizeConstraint {
+  unsigned MinGroupSize;
+
+public:
+  MinGroupSizeConstraint(unsigned MinGroupSize = 2)
+      : MinGroupSize(MinGroupSize) {}
+
+  void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
+    CloneConstraint::filterGroups(CloneGroups,
+                                  [this](const CloneDetector::CloneGroup &A) {
+                                    return A.size() < MinGroupSize;
+                                  });
+  }
+};
+
+/// Ensures that no clone group fully contains another clone group.
+struct OnlyLargestCloneConstraint {
+  void constrain(std::vector<CloneDetector::CloneGroup> &Result);
+};
+
+/// Analyzes the pattern of the referenced variables in a statement.
+class VariablePattern {
+
+  /// Describes an occurence of a variable reference in a statement.
+  struct VariableOccurence {
+    /// The index of the associated VarDecl in the Variables vector.
+    size_t KindID;
+    /// The statement in the code where the variable was referenced.
+    const Stmt *Mention;
+
+    VariableOccurence(size_t KindID, const Stmt *Mention)
+        : KindID(KindID), Mention(Mention) {}
+  };
+
+  /// All occurences of referenced variables in the order of appearance.
+  std::vector<VariableOccurence> Occurences;
+  /// List of referenced variables in the order of appearance.
+  /// Every item in this list is unique.
+  std::vector<const VarDecl *> Variables;
+
+  /// Adds a new variable referenced to this pattern.
+  /// \param VarDecl The declaration of the variable that is referenced.
+  /// \param Mention The SourceRange where this variable is referenced.
+  void addVariableOccurence(const VarDecl *VarDecl, const Stmt *Mention);
+
+  /// Adds each referenced variable from the given statement.
+  void addVariables(const Stmt *S);
+
+public:
+  /// Creates an VariablePattern object with information about the given
+  /// StmtSequence.
+  VariablePattern(const StmtSequence &Sequence) {
+    for (const Stmt *S : Sequence)
+      addVariables(S);
+  }
+
+  /// Describes two clones that reference their variables in a different pattern
+  /// which could indicate a programming error.
   struct SuspiciousClonePair {
-    /// \brief Utility class holding the relevant information about a single
-    ///        clone in this pair.
+    /// Utility class holding the relevant information about a single
+    /// clone in this pair.
     struct SuspiciousCloneInfo {
       /// The variable which referencing in this clone was against the pattern.
       const VarDecl *Variable;
@@ -270,17 +379,37 @@
     SuspiciousCloneInfo SecondCloneInfo;
   };
 
-  /// \brief Searches the provided statements for pairs of clones that don't
-  ///        follow the same pattern when referencing variables.
-  /// \param Result Output parameter that will contain the clone pairs.
-  /// \param MinGroupComplexity Only clone pairs in which the clones have at
-  ///                           least this complexity value.
-  void findSuspiciousClones(std::vector<SuspiciousClonePair> &Result,
-                            unsigned MinGroupComplexity);
+  /// Counts the differences between this pattern and the given one.
+  /// \param Other The given VariablePattern to compare with.
+  /// \param FirstMismatch Output parameter that will be filled with information
+  ///        about the first difference between the two patterns. This parameter
+  ///        can be a nullptr, in which case it will be ignored.
+  /// \return Returns the number of differences between the pattern this object
+  ///         is following and the given VariablePattern.
+  ///
+  /// For example, the following statements all have the same pattern and this
+  /// function would return zero:
+  ///
+  ///   if (a < b) return a; return b;
+  ///   if (x < y) return x; return y;
+  ///   if (u2 < u1) return u2; return u1;
+  ///
+  /// But the following statement has a different pattern (note the changed
+  /// variables in the return statements) and would have two differences when
+  /// compared with one of the statements above.
+  ///
+  ///   if (a < b) return b; return a;
+  ///
+  /// This function should only be called if the related statements of the given
+  /// pattern and the statements of this objects are clones of each other.
+  unsigned countPatternDifferences(
+      const VariablePattern &Other,
+      VariablePattern::SuspiciousClonePair *FirstMismatch = nullptr);
+};
 
-private:
-  /// Stores all encountered StmtSequences alongside their CloneSignature.
-  std::vector<std::pair<CloneSignature, StmtSequence>> Sequences;
+/// Ensures that all clones reference variables in the same pattern.
+struct MatchingVariablePatternConstraint {
+  void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups);
 };
 
 } // end namespace clang
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index fa60d51..d4cec49 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -87,6 +87,9 @@
 def NonBitField : SubsetSubject<Field,
                                 [{!S->isBitField()}]>;
 
+def ObjCClassMethod : SubsetSubject<ObjCMethod,
+                                    [{!S->isInstanceMethod()}]>;
+
 def ObjCInstanceMethod : SubsetSubject<ObjCMethod,
                                        [{S->isInstanceMethod()}]>;
 
@@ -149,6 +152,9 @@
 class FunctionArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
                                                                           opt,
                                                                           fake>;
+class NamedArgument<string name, bit opt = 0, bit fake = 0> : Argument<name,
+                                                                          opt,
+                                                                          fake>;
 class TypeArgument<string name, bit opt = 0> : Argument<name, opt>;
 class UnsignedArgument<string name, bit opt = 0> : Argument<name, opt>;
 class VariadicUnsignedArgument<string name> : Argument<name, 1>;
@@ -192,6 +198,9 @@
   list<string> Enums = enums;
 }
 
+// Represents an attribute wrapped by another attribute.
+class AttrArgument<string name, bit opt = 0> : Argument<name, opt>;
+
 // This handles one spelling of an attribute.
 class Spelling<string name, string variety> {
   string Name = name;
@@ -248,6 +257,8 @@
 def CPlusPlus : LangOpt<"CPlusPlus">;
 def OpenCL : LangOpt<"OpenCL">;
 def RenderScript : LangOpt<"RenderScript">;
+def ObjC : LangOpt<"ObjC1">;
+def BlocksSupported : LangOpt<"Blocks">;
 
 // Defines targets for target-specific attributes. The list of strings should
 // specify architectures for which the target applies, based off the ArchType
@@ -269,6 +280,112 @@
   let CXXABIs = ["Microsoft"];
 }
 
+// Attribute subject match rules that are used for #pragma clang attribute.
+//
+// A instance of AttrSubjectMatcherRule represents an individual match rule.
+// An individual match rule can correspond to a number of different attribute
+// subjects, e.g. "record" matching rule corresponds to the Record and
+// CXXRecord attribute subjects.
+//
+// Match rules are used in the subject list of the #pragma clang attribute.
+// Match rules can have sub-match rules that are instances of
+// AttrSubjectMatcherSubRule. A sub-match rule can correspond to a number
+// of different attribute subjects, and it can have a negated spelling as well.
+// For example, "variable(unless(is_parameter))" matching rule corresponds to
+// the NonParmVar attribute subject.
+class AttrSubjectMatcherSubRule<string name, list<AttrSubject> subjects,
+                                bit negated = 0> {
+  string Name = name;
+  list<AttrSubject> Subjects = subjects;
+  bit Negated = negated;
+  // Lists language options, one of which is required to be true for the
+  // attribute to be applicable. If empty, the language options are taken
+  // from the parent matcher rule.
+  list<LangOpt> LangOpts = [];
+}
+class AttrSubjectMatcherRule<string name, list<AttrSubject> subjects,
+                             list<AttrSubjectMatcherSubRule> subrules = []> {
+  string Name = name;
+  list<AttrSubject> Subjects = subjects;
+  list<AttrSubjectMatcherSubRule> Constraints = subrules;
+  // Lists language options, one of which is required to be true for the
+  // attribute to be applicable. If empty, no language options are required.
+  list<LangOpt> LangOpts = [];
+}
+
+// function(is_member)
+def SubRuleForCXXMethod : AttrSubjectMatcherSubRule<"is_member", [CXXMethod]> {
+  let LangOpts = [CPlusPlus];
+}
+def SubjectMatcherForFunction : AttrSubjectMatcherRule<"function", [Function], [
+  SubRuleForCXXMethod
+]>;
+// hasType is abstract, it should be used with one of the sub-rules.
+def SubjectMatcherForType : AttrSubjectMatcherRule<"hasType", [], [
+  AttrSubjectMatcherSubRule<"functionType", [FunctionLike]>
+
+  // FIXME: There's a matcher ambiguity with objc methods and blocks since
+  // functionType excludes them but functionProtoType includes them.
+  // AttrSubjectMatcherSubRule<"functionProtoType", [HasFunctionProto]>
+]>;
+def SubjectMatcherForTypedef : AttrSubjectMatcherRule<"type_alias",
+                                                      [TypedefName]>;
+def SubjectMatcherForRecord : AttrSubjectMatcherRule<"record", [Record,
+                                                                CXXRecord], [
+  // unless(is_union)
+  AttrSubjectMatcherSubRule<"is_union", [Struct], 1>
+]>;
+def SubjectMatcherForEnum : AttrSubjectMatcherRule<"enum", [Enum]>;
+def SubjectMatcherForEnumConstant : AttrSubjectMatcherRule<"enum_constant",
+                                                           [EnumConstant]>;
+def SubjectMatcherForVar : AttrSubjectMatcherRule<"variable", [Var], [
+  AttrSubjectMatcherSubRule<"is_thread_local", [TLSVar]>,
+  AttrSubjectMatcherSubRule<"is_global", [GlobalVar]>,
+  AttrSubjectMatcherSubRule<"is_parameter", [ParmVar]>,
+  // unless(is_parameter)
+  AttrSubjectMatcherSubRule<"is_parameter", [NonParmVar], 1>
+]>;
+def SubjectMatcherForField : AttrSubjectMatcherRule<"field", [Field]>;
+def SubjectMatcherForNamespace : AttrSubjectMatcherRule<"namespace",
+                                                        [Namespace]> {
+  let LangOpts = [CPlusPlus];
+}
+def SubjectMatcherForObjCInterface : AttrSubjectMatcherRule<"objc_interface",
+                                                            [ObjCInterface]> {
+  let LangOpts = [ObjC];
+}
+def SubjectMatcherForObjCProtocol : AttrSubjectMatcherRule<"objc_protocol",
+                                                           [ObjCProtocol]> {
+  let LangOpts = [ObjC];
+}
+def SubjectMatcherForObjCCategory : AttrSubjectMatcherRule<"objc_category",
+                                                           [ObjCCategory]> {
+  let LangOpts = [ObjC];
+}
+def SubjectMatcherForObjCMethod : AttrSubjectMatcherRule<"objc_method",
+                                                         [ObjCMethod], [
+  AttrSubjectMatcherSubRule<"is_instance", [ObjCInstanceMethod]>
+]> {
+  let LangOpts = [ObjC];
+}
+def SubjectMatcherForObjCProperty : AttrSubjectMatcherRule<"objc_property",
+                                                           [ObjCProperty]> {
+  let LangOpts = [ObjC];
+}
+def SubjectMatcherForBlock : AttrSubjectMatcherRule<"block", [Block]> {
+  let LangOpts = [BlocksSupported];
+}
+
+// Aggregate attribute subject match rules are abstract match rules that can't
+// be used directly in #pragma clang attribute. Instead, users have to use
+// subject match rules that correspond to attribute subjects that derive from
+// the specified subject.
+class AttrSubjectMatcherAggregateRule<AttrSubject subject> {
+  AttrSubject Subject = subject;
+}
+
+def SubjectMatcherForNamed : AttrSubjectMatcherAggregateRule<Named>;
+
 class Attr {
   // The various ways in which an attribute can be spelled in source
   list<Spelling> Spellings;
@@ -301,6 +418,17 @@
   // Set to true if this attribute can be duplicated on a subject when merging
   // attributes. By default, attributes are not merged.
   bit DuplicatesAllowedWhileMerging = 0;
+  // Set to true if this attribute meaningful when applied to or inherited 
+  // in a class template definition.
+  bit MeaningfulToClassTemplateDefinition = 0;
+  // Set to true if this attribute can be used with '#pragma clang attribute'.
+  // By default, when this value is false, an attribute is supported by the
+  // '#pragma clang attribute' only when:
+  // - It has documentation.
+  // - It has a subject list whose subjects can be represented using subject
+  //   match rules.
+  // - It has GNU/CXX11 spelling and doesn't require delayed parsing.
+  bit ForcePragmaAttributeSupport = 0;
   // Lists language options, one of which is required to be true for the
   // attribute to be applicable. If empty, no language options are required.
   list<LangOpt> LangOpts = [];
@@ -372,6 +500,7 @@
   let Args = [VariadicStringArgument<"Tags">];
   let Subjects = SubjectList<[Struct, Var, Function, Namespace], ErrorDiag,
       "ExpectedStructClassVariableFunctionOrInlineNamespace">;
+  let MeaningfulToClassTemplateDefinition = 1;
   let Documentation = [AbiTagsDocs];
 }
 
@@ -464,6 +593,9 @@
 def Annotate : InheritableParamAttr {
   let Spellings = [GNU<"annotate">];
   let Args = [StringArgument<"Annotation">];
+  // Ensure that the annotate attribute can be used with
+  // '#pragma clang attribute' even though it has no subject list.
+  let ForcePragmaAttributeSupport = 1;
   let Documentation = [Undocumented];
 }
 
@@ -505,14 +637,50 @@
              .Case("macos_app_extension", "macOS (App Extension)")
              .Case("tvos_app_extension", "tvOS (App Extension)")
              .Case("watchos_app_extension", "watchOS (App Extension)")
+             .Case("swift", "Swift")
              .Default(llvm::StringRef());
+}
+static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
+    return llvm::StringSwitch<llvm::StringRef>(Platform)
+             .Case("ios", "iOS")
+             .Case("macos", "macOS")
+             .Case("tvos", "tvOS")
+             .Case("watchos", "watchOS")
+             .Case("ios_app_extension", "iOSApplicationExtension")
+             .Case("macos_app_extension", "macOSApplicationExtension")
+             .Case("tvos_app_extension", "tvOSApplicationExtension")
+             .Case("watchos_app_extension", "watchOSApplicationExtension")
+             .Default(Platform);
+}
+static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
+    return llvm::StringSwitch<llvm::StringRef>(Platform)
+             .Case("iOS", "ios")
+             .Case("macOS", "macos")
+             .Case("tvOS", "tvos")
+             .Case("watchOS", "watchos")
+             .Case("iOSApplicationExtension", "ios_app_extension")
+             .Case("macOSApplicationExtension", "macos_app_extension")
+             .Case("tvOSApplicationExtension", "tvos_app_extension")
+             .Case("watchOSApplicationExtension", "watchos_app_extension")
+             .Default(Platform);
 } }];
   let HasCustomParsing = 1;
   let DuplicatesAllowedWhileMerging = 1;
-//  let Subjects = SubjectList<[Named]>;
+  let Subjects = SubjectList<[Named]>;
   let Documentation = [AvailabilityDocs];
 }
 
+def ExternalSourceSymbol : InheritableAttr {
+  let Spellings = [GNU<"external_source_symbol">,
+                   CXX11<"clang", "external_source_symbol">];
+  let Args = [StringArgument<"language", 1>,
+              StringArgument<"definedIn", 1>,
+              BoolArgument<"generatedDeclaration", 1>];
+  let HasCustomParsing = 1;
+  let Subjects = SubjectList<[Named]>;
+  let Documentation = [ExternalSourceSymbolDocs];
+}
+
 def Blocks : InheritableAttr {
   let Spellings = [GNU<"blocks">];
   let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
@@ -771,6 +939,7 @@
               // An optional string argument that enables us to provide a
               // Fix-It.
               StringArgument<"Replacement", 1>];
+  let MeaningfulToClassTemplateDefinition = 1;
   let Documentation = [DeprecatedDocs];
 }
 
@@ -847,7 +1016,15 @@
   let Spellings = [GNU<"flag_enum">];
   let Subjects = SubjectList<[Enum]>;
   let Documentation = [FlagEnumDocs];
-  let LangOpts = [COnly];
+}
+
+def EnumExtensibility : InheritableAttr {
+  let Spellings = [GNU<"enum_extensibility">,
+                   CXX11<"clang", "enum_extensibility">];
+  let Subjects = SubjectList<[Enum]>;
+  let Args = [EnumArgument<"Extensibility", "Kind",
+              ["closed", "open"], ["Closed", "Open"]>];
+  let Documentation = [EnumExtensibilityDocs];
 }
 
 def Flatten : InheritableAttr {
@@ -1171,6 +1348,12 @@
   let Documentation = [Undocumented];
 }
 
+def NoEscape : InheritableAttr {
+  let Spellings = [GCC<"noescape">];
+  let Subjects = SubjectList<[ParmVar], WarnDiag, "ExpectedParameter">;
+  let Documentation = [Undocumented];
+}
+
 def AssumeAligned : InheritableAttr {
   let Spellings = [GCC<"assume_aligned">];
   let Subjects = SubjectList<[ObjCMethod, Function]>;
@@ -1233,6 +1416,12 @@
   let Documentation = [Undocumented];
 }
 
+def NSErrorDomain : Attr {
+  let Spellings = [GNU<"ns_error_domain">];
+  let Args = [IdentifierArgument<"ErrorDomain">];
+  let Documentation = [NSErrorDomainDocs];
+}
+
 def NSReturnsRetained : InheritableAttr {
   let Spellings = [GNU<"ns_returns_retained">];
 //  let Subjects = SubjectList<[ObjCMethod, ObjCProperty, Function]>;
@@ -1319,6 +1508,12 @@
   let Documentation = [ObjCSubclassingRestrictedDocs];
 }
 
+def ObjCCompleteDefinition : InheritableAttr {
+  let Spellings = [GNU<"objc_complete_definition">];
+  let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+  let Documentation = [Undocumented];
+}
+
 def ObjCExplicitProtocolImpl : InheritableAttr {
   let Spellings = [GNU<"objc_protocol_requires_explicit_implementation">];
   let Subjects = SubjectList<[ObjCProtocol], ErrorDiag>;
@@ -1421,6 +1616,92 @@
   let Documentation = [RegparmDocs];
 }
 
+def SwiftBridge : Attr {
+  let Spellings = [GNU<"swift_bridge">];
+  let Subjects = SubjectList<[Tag, TypedefName, ObjCInterface, ObjCProtocol],
+                             ErrorDiag, "ExpectedType">;
+  let Args = [StringArgument<"SwiftType">];
+  let Documentation = [SwiftBridgeDocs];
+}
+
+def SwiftObjCMembers : Attr {
+  let Spellings = [GNU<"swift_objc_members">];
+  let Subjects = SubjectList<[ObjCInterface], ErrorDiag>;
+  let Documentation = [SwiftObjCMembersDocs];
+}
+
+def SwiftError : InheritableAttr {
+  let Spellings = [GCC<"swift_error">];
+  let Args = [EnumArgument<"Convention", "ConventionKind",
+               ["none", "nonnull_error", "null_result", "zero_result", "nonzero_result"],
+               ["None", "NonNullError", "NullResult", "ZeroResult", "NonZeroResult"]>];
+  let Subjects = SubjectList<[ObjCMethod, Function], ErrorDiag>;
+  let Documentation = [SwiftErrorDocs];
+}
+
+def SwiftName : InheritableAttr {
+  let Spellings = [GCC<"swift_name">];
+  let Args = [StringArgument<"Name">];
+  // Proper subject list disabled because of the custom error needed.
+  // Let's avoid merge conflicts for now.
+//  let Subjects = SubjectList<[EnumConstant, ObjCProtocol, ObjCClassMethod],
+//                             ErrorDiag, "ExpectedSwiftNameSubjects">;
+  let Documentation = [Undocumented];
+}
+
+def SwiftNewtype : Attr {
+  let Spellings = [GNU<"swift_newtype">, GNU<"swift_wrapper">];
+  let Subjects = SubjectList<[TypedefName], ErrorDiag, "ExpectedType">;
+  let Args = [EnumArgument<"NewtypeKind", "NewtypeKind",
+               ["struct", "enum"],
+               ["NK_Struct", "NK_Enum"]>];
+  let Documentation = [SwiftNewtypeDocs];
+}
+
+def SwiftPrivate : InheritableAttr {
+  let Spellings = [GCC<"swift_private">];
+  let Documentation = [Undocumented];
+}
+
+def SwiftImportAsNonGeneric : InheritableAttr {
+  // This attribute has no spellings as it is only ever created implicitly
+  // from API notes.
+  let Spellings = [];
+  let SemaHandler = 0;
+  let Documentation = [Undocumented];
+}
+
+def SwiftImportPropertyAsAccessors : InheritableAttr { 
+  // This attribute has no spellings as it is only ever created implicitly
+  // from API notes.
+  let Spellings = [];
+  let SemaHandler = 0;
+  let Documentation = [Undocumented];
+}
+
+def SwiftVersioned : Attr {
+  // This attribute has no spellings as it is only ever created implicitly
+  // from API notes.
+  let Spellings = [];
+  let Args = [VersionArgument<"Version">, AttrArgument<"AttrToAdd">];
+  let SemaHandler = 0;
+  let Documentation = [Undocumented];
+}
+
+def SwiftVersionedRemoval : Attr {
+  // This attribute has no spellings as it is only ever created implicitly
+  // from API notes.
+  let Spellings = [];
+  let Args = [VersionArgument<"Version">, UnsignedArgument<"RawKind">];
+  let SemaHandler = 0;
+  let Documentation = [Undocumented];
+  let AdditionalMembers = [{
+    attr::Kind getAttrKindToRemove() const {
+      return static_cast<attr::Kind>(getRawKind());
+    }
+  }];
+}
+
 def ReqdWorkGroupSize : InheritableAttr {
   let Spellings = [GNU<"reqd_work_group_size">];
   let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
@@ -1596,14 +1877,14 @@
 
 def DiagnoseIf : InheritableAttr {
   let Spellings = [GNU<"diagnose_if">];
-  let Subjects = SubjectList<[Function]>;
+  let Subjects = SubjectList<[Function, ObjCMethod, ObjCProperty]>;
   let Args = [ExprArgument<"Cond">, StringArgument<"Message">,
               EnumArgument<"DiagnosticType",
                            "DiagnosticType",
                            ["error", "warning"],
                            ["DT_Error", "DT_Warning"]>,
               BoolArgument<"ArgDependent", 0, /*fake*/ 1>,
-              FunctionArgument<"Parent", 0, /*fake*/ 1>];
+              NamedArgument<"Parent", 0, /*fake*/ 1>];
   let DuplicatesAllowedWhileMerging = 1;
   let LateParsed = 1;
   let AdditionalMembers = [{
@@ -1681,6 +1962,7 @@
   let Args = [EnumArgument<"Visibility", "VisibilityType",
                            ["default", "hidden", "internal", "protected"],
                            ["Default", "Hidden", "Hidden", "Protected"]>];
+  let MeaningfulToClassTemplateDefinition = 1;
   let Documentation = [Undocumented];
 }
 
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 8f6a7ea..e5aa67e 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -657,7 +657,8 @@
   let Content = [{
 The ``nodebug`` attribute allows you to suppress debugging information for a
 function or method, or for a variable that is not a parameter or a non-static
-data member.
+data member. It will also suppress debug information for any code that is
+inlined into a ``nodebug`` function or method.
   }];
 }
 
@@ -960,6 +961,63 @@
   }];
 }
 
+def ExternalSourceSymbolDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``external_source_symbol`` attribute specifies that a declaration originates
+from an external source and describes the nature of that source.
+
+The fact that Clang is capable of recognizing declarations that were defined
+externally can be used to provide better tooling support for mixed-language
+projects or projects that rely on auto-generated code. For instance, an IDE that
+uses Clang and that supports mixed-language projects can use this attribute to
+provide a correct 'jump-to-definition' feature. For a concrete example,
+consider a protocol that's defined in a Swift file:
+
+.. code-block:: swift
+
+  @objc public protocol SwiftProtocol {
+    func method()
+  }
+
+This protocol can be used from Objective-C code by including a header file that
+was generated by the Swift compiler. The declarations in that header can use
+the ``external_source_symbol`` attribute to make Clang aware of the fact
+that ``SwiftProtocol`` actually originates from a Swift module:
+
+.. code-block:: objc
+
+  __attribute__((external_source_symbol(language=Swift,defined_in="module")))
+  @protocol SwiftProtocol
+  @required
+  - (void) method;
+  @end
+
+Consequently, when 'jump-to-definition' is performed at a location that
+references ``SwiftProtocol``, the IDE can jump to the original definition in
+the Swift source file rather than jumping to the Objective-C declaration in the
+auto-generated header file.
+
+The ``external_source_symbol`` attribute is a comma-separated list that includes
+clauses that describe the origin and the nature of the particular declaration.
+Those clauses can be:
+
+language=\ *string-literal*
+  The name of the source language in which this declaration was defined.
+
+defined_in=\ *string-literal*
+  The name of the source container in which the declaration was defined. The
+  exact definition of source container is language-specific, e.g. Swift's
+  source containers are modules, so ``defined_in`` should specify the Swift
+  module name.
+
+generated_declaration
+  This declaration was automatically generated by some tool.
+
+The clauses can be specified in any order. The clauses that are listed above are
+all optional, but the attribute has to have at least one clause.
+  }];
+}
 
 def RequireConstantInitDocs : Documentation {
   let Category = DocCatVariable;
@@ -1879,6 +1937,55 @@
   }];
 }
 
+def EnumExtensibilityDocs : Documentation {
+  let Category = DocCatType;
+  let Content = [{
+Attribute ``enum_extensibility`` is used to distinguish between enum definitions
+that are extensible and those that are not. The attribute can take either
+``closed`` or ``open`` as an argument. ``closed`` indicates a variable of the
+enum type takes a value that corresponds to one of the enumerators listed in the
+enum definition or, when the enum is annotated with ``flag_enum``, a value that
+can be constructed using values corresponding to the enumerators. ``open``
+indicates a variable of the enum type can take any values allowed by the
+standard and instructs clang to be more lenient when issuing warnings.
+
+.. code-block:: c
+
+  enum __attribute__((enum_extensibility(closed))) ClosedEnum {
+    A0, A1
+  };
+
+  enum __attribute__((enum_extensibility(open))) OpenEnum {
+    B0, B1
+  };
+
+  enum __attribute__((enum_extensibility(closed),flag_enum)) ClosedFlagEnum {
+    C0 = 1 << 0, C1 = 1 << 1
+  };
+
+  enum __attribute__((enum_extensibility(open),flag_enum)) OpenFlagEnum {
+    D0 = 1 << 0, D1 = 1 << 1
+  };
+
+  void foo1() {
+    enum ClosedEnum ce;
+    enum OpenEnum oe;
+    enum ClosedFlagEnum cfe;
+    enum OpenFlagEnum ofe;
+
+    ce = A1;           // no warnings
+    ce = 100;          // warning issued
+    oe = B1;           // no warnings
+    oe = 100;          // no warnings
+    cfe = C0 | C1;     // no warnings
+    cfe = C0 | C1 | 4; // warning issued
+    ofe = D0 | D1;     // no warnings
+    ofe = D0 | D1 | 4; // no warnings
+  }
+
+  }];
+}
+
 def EmptyBasesDocs : Documentation {
   let Category = DocCatType;
   let Content = [{
@@ -2322,6 +2429,65 @@
   }];
 }
 
+def SwiftDocs : DocumentationCategory<"Controlling Swift Import"> {
+  let Content = [{
+Clang supports additional attributes for controlling how APIs are imported into Swift.
+  }];
+}
+
+def NSErrorDomainDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+The ``ns_error_domain`` attribute indicates a global constant representing the error domain.
+  }];
+}
+
+def SwiftBridgeDocs : Documentation {
+  let Category = SwiftDocs;
+  let Content = [{
+The ``swift_bridge`` attribute indicates that the type to which the attribute appertains is bridged to the named Swift type. 
+  }];
+}
+
+def SwiftObjCMembersDocs : Documentation {
+  let Category = SwiftDocs;
+  let Content = [{
+The ``swift_objc_members`` attribute maps to the Swift ``@objcMembers`` attribute, which indicates that Swift members of this class, its subclasses, and all of the extensions thereof, will implicitly be exposed back to Objective-C.
+  }];
+}
+
+def SwiftErrorDocs : Documentation {
+  let Category = SwiftDocs;
+  let Heading = "swift_error";
+  let Content = [{
+The ``swift_error`` attribute controls whether a particular function (or Objective-C method) is imported into Swift as a throwing function, and if so, the dynamic convention it uses.
+
+All of these conventions except ``none`` require the function to have an error parameter.  Currently, the error parameter is always the last parameter of type ``NSError**`` or ``CFErrorRef*``.  Swift will remove the error parameter from the imported API, and dynamically will always pass a valid address initialized to a null pointer.
+
+* ``swift_error(none)`` means that the function should not be imported as throwing.  The error parameter and result type will be left alone.
+
+* ``swift_error(null_result)`` means that calls to the function should be considered to have thrown if they return a null value.  The return type must be a pointer type, and it will be imported into Swift with a non-optional type.  This is the default error convention for Objective-C methods that return pointers.
+
+* ``swift_error(zero_result)`` means that calls to the function should be considered to have thrown if they return a zero result.  The return type must be an integral type.  If the return type would have been imported as ``Bool``, it is instead imported as ``Void``.  This is the default error convention for Objective-C methods that return a type that would be imported as ``Bool``.
+
+* ``swift_error(nonzero_result)`` means that calls to the function should be considered to have thrown if they return a non-zero result.  The return type must be an integral type.  If the return type would have been imported as ``Bool``, it is instead imported as ``Void``.
+
+* ``swift_error(nonnull_error)`` means that calls to the function should be considered to have thrown if they leave a non-null error in the error parameter.  The return type is left unmodified.
+
+}];
+}
+
+def SwiftNewtypeDocs : Documentation {
+  let Category = SwiftDocs;
+  let Heading = "swift_newtype";
+  let Content = [{
+The ``swift_newtype`` attribute indicates that the typedef to which the attribute appertains is imported as a new Swift type of the typedef's name.
+* ``swift_newtype(struct)`` means that a Swift struct will be created for this typedef.
+* ``swift_newtype(enum)`` means that a Swift enum will be created for this typedef.
+  }];
+}
+
+
 def OMPDeclareTargetDocs : Documentation {
   let Category = DocCatFunction;
   let Heading = "#pragma omp declare target";
diff --git a/include/clang/Basic/AttrSubjectMatchRules.h b/include/clang/Basic/AttrSubjectMatchRules.h
new file mode 100644
index 0000000..4c88adf
--- /dev/null
+++ b/include/clang/Basic/AttrSubjectMatchRules.h
@@ -0,0 +1,32 @@
+//===-- AttrSubjectMatchRules.h - Attribute subject match rules -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_ATTR_SUBJECT_MATCH_RULES_H
+#define LLVM_CLANG_BASIC_ATTR_SUBJECT_MATCH_RULES_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/DenseMap.h"
+
+namespace clang {
+namespace attr {
+
+/// \brief A list of all the recognized kinds of attributes.
+enum SubjectMatchRule {
+#define ATTR_MATCH_RULE(X, Spelling, IsAbstract) X,
+#include "clang/Basic/AttrSubMatchRulesList.inc"
+};
+
+const char *getSubjectMatchRuleSpelling(SubjectMatchRule Rule);
+
+using ParsedSubjectMatchRuleSet = llvm::DenseMap<int, SourceRange>;
+
+} // end namespace attr
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
index e4929b5..3e0fb87 100644
--- a/include/clang/Basic/CMakeLists.txt
+++ b/include/clang/Basic/CMakeLists.txt
@@ -28,6 +28,11 @@
   SOURCE Attr.td
   TARGET ClangAttrList)
 
+clang_tablegen(AttrSubMatchRulesList.inc -gen-clang-attr-subject-match-rule-list
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE Attr.td
+  TARGET ClangAttrSubjectMatchRuleList)
+
 clang_tablegen(AttrHasAttributeImpl.inc -gen-clang-attr-has-attribute-impl
   -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
   SOURCE Attr.td
diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h
index b83ef4d..ffce99b 100644
--- a/include/clang/Basic/Diagnostic.h
+++ b/include/clang/Basic/Diagnostic.h
@@ -29,6 +29,7 @@
 #include <cassert>
 #include <cstdint>
 #include <list>
+#include <map>
 #include <memory>
 #include <string>
 #include <type_traits>
@@ -232,59 +233,97 @@
   /// \brief Keeps and automatically disposes all DiagStates that we create.
   std::list<DiagState> DiagStates;
 
-  /// \brief Represents a point in source where the diagnostic state was
-  /// modified because of a pragma.
-  ///
-  /// 'Loc' can be null if the point represents the diagnostic state
-  /// modifications done through the command-line.
-  struct DiagStatePoint {
-    DiagState *State;
-    FullSourceLoc Loc;
-    DiagStatePoint(DiagState *State, FullSourceLoc Loc)
-      : State(State), Loc(Loc) { } 
-    
-    bool operator<(const DiagStatePoint &RHS) const {
-      // If Loc is invalid it means it came from <command-line>, in which case
-      // we regard it as coming before any valid source location.
-      if (RHS.Loc.isInvalid())
-        return false;
-      if (Loc.isInvalid())
-        return true;
-      return Loc.isBeforeInTranslationUnitThan(RHS.Loc);
+  /// A mapping from files to the diagnostic states for those files. Lazily
+  /// built on demand for files in which the diagnostic state has not changed.
+  class DiagStateMap {
+  public:
+    /// Add an initial diagnostic state.
+    void appendFirst(DiagState *State);
+    /// Add a new latest state point.
+    void append(SourceManager &SrcMgr, SourceLocation Loc, DiagState *State);
+    /// Look up the diagnostic state at a given source location.
+    DiagState *lookup(SourceManager &SrcMgr, SourceLocation Loc) const;
+    /// Determine whether this map is empty.
+    bool empty() const { return Files.empty(); }
+    /// Clear out this map.
+    void clear() {
+      Files.clear();
+      FirstDiagState = CurDiagState = nullptr;
+      CurDiagStateLoc = SourceLocation();
     }
+
+    /// Grab the most-recently-added state point.
+    DiagState *getCurDiagState() const { return CurDiagState; }
+    /// Get the location at which a diagnostic state was last added.
+    SourceLocation getCurDiagStateLoc() const { return CurDiagStateLoc; }
+
+  private:
+    /// \brief Represents a point in source where the diagnostic state was
+    /// modified because of a pragma.
+    ///
+    /// 'Loc' can be null if the point represents the diagnostic state
+    /// modifications done through the command-line.
+    struct DiagStatePoint {
+      DiagState *State;
+      unsigned Offset;
+      DiagStatePoint(DiagState *State, unsigned Offset)
+        : State(State), Offset(Offset) { } 
+    };
+
+    /// Description of the diagnostic states and state transitions for a
+    /// particular FileID.
+    struct File {
+      /// The diagnostic state for the parent file. This is strictly redundant,
+      /// as looking up the DecomposedIncludedLoc for the FileID in the Files
+      /// map would give us this, but we cache it here for performance.
+      File *Parent = nullptr;
+      /// The offset of this file within its parent.
+      unsigned ParentOffset = 0;
+      /// Whether this file has any local (not imported from an AST file)
+      /// diagnostic state transitions.
+      bool HasLocalTransitions = false;
+      /// The points within the file where the state changes. There will always
+      /// be at least one of these (the state on entry to the file).
+      llvm::SmallVector<DiagStatePoint, 4> StateTransitions;
+
+      DiagState *lookup(unsigned Offset) const;
+    };
+
+    /// The diagnostic states for each file.
+    mutable std::map<FileID, File> Files;
+
+    /// The initial diagnostic state.
+    DiagState *FirstDiagState;
+    /// The current diagnostic state.
+    DiagState *CurDiagState;
+    /// The location at which the current diagnostic state was established.
+    SourceLocation CurDiagStateLoc;
+
+    /// Get the diagnostic state information for a file.
+    File *getFile(SourceManager &SrcMgr, FileID ID) const;
+
+    friend class ASTReader;
+    friend class ASTWriter;
   };
 
-  /// \brief A sorted vector of all DiagStatePoints representing changes in
-  /// diagnostic state due to diagnostic pragmas.
-  ///
-  /// The vector is always sorted according to the SourceLocation of the
-  /// DiagStatePoint.
-  typedef std::vector<DiagStatePoint> DiagStatePointsTy;
-  mutable DiagStatePointsTy DiagStatePoints;
+  DiagStateMap DiagStatesByLoc;
 
   /// \brief Keeps the DiagState that was active during each diagnostic 'push'
   /// so we can get back at it when we 'pop'.
   std::vector<DiagState *> DiagStateOnPushStack;
 
   DiagState *GetCurDiagState() const {
-    assert(!DiagStatePoints.empty());
-    return DiagStatePoints.back().State;
+    return DiagStatesByLoc.getCurDiagState();
   }
 
-  void PushDiagStatePoint(DiagState *State, SourceLocation L) {
-    FullSourceLoc Loc(L, getSourceManager());
-    // Make sure that DiagStatePoints is always sorted according to Loc.
-    assert(Loc.isValid() && "Adding invalid loc point");
-    assert(!DiagStatePoints.empty() &&
-           (DiagStatePoints.back().Loc.isInvalid() ||
-            DiagStatePoints.back().Loc.isBeforeInTranslationUnitThan(Loc)) &&
-           "Previous point loc comes after or is the same as new one");
-    DiagStatePoints.push_back(DiagStatePoint(State, Loc));
-  }
+  void PushDiagStatePoint(DiagState *State, SourceLocation L);
 
   /// \brief Finds the DiagStatePoint that contains the diagnostic state of
   /// the given source location.
-  DiagStatePointsTy::iterator GetDiagStatePointForLoc(SourceLocation Loc) const;
+  DiagState *GetDiagStateForLoc(SourceLocation Loc) const {
+    return SourceMgr ? DiagStatesByLoc.lookup(*SourceMgr, Loc)
+                     : DiagStatesByLoc.getCurDiagState();
+  }
 
   /// \brief Sticky flag set to \c true when an error is emitted.
   bool ErrorOccurred;
@@ -390,7 +429,11 @@
     assert(SourceMgr && "SourceManager not set!");
     return *SourceMgr;
   }
-  void setSourceManager(SourceManager *SrcMgr) { SourceMgr = SrcMgr; }
+  void setSourceManager(SourceManager *SrcMgr) {
+    assert(DiagStatesByLoc.empty() &&
+           "Leftover diag state from a different SourceManager.");
+    SourceMgr = SrcMgr;
+  }
 
   //===--------------------------------------------------------------------===//
   //  DiagnosticsEngine characterization methods, used by a client to customize
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index af0612a..fac6f38 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -45,7 +45,9 @@
   "must end with ':'">;
 def err_expected_string_literal : Error<"expected string literal "
   "%select{in %1|for diagnostic message in static_assert|"
-          "for optional message in 'availability' attribute}0">;
+          "for optional message in 'availability' attribute|"
+          "for %select{language|source container}1 name in "
+          "'external_source_symbol' attribute}0">;
 def err_invalid_string_udl : Error<
   "string literal with user-defined suffix cannot be used here">;
 def err_invalid_character_udl : Error<
@@ -88,10 +90,12 @@
   "module '%0' %select{is incompatible with|requires}1 feature '%2'">;
 def err_module_header_missing : Error<
   "%select{|umbrella }0header '%1' not found">;
-def err_module_lock_failure : Error<
-  "could not acquire lock file for module '%0': %1">, DefaultFatal;
-def err_module_lock_timeout : Error<
-  "timed out waiting to acquire lock file for module '%0'">, DefaultFatal;
+def err_module_shadowed : Error<
+  "import of shadowed module '%0'">;
+def remark_module_lock_failure : Remark<
+  "could not acquire lock file for module '%0': %1">, InGroup<ModuleBuild>;
+def remark_module_lock_timeout : Remark<
+  "timed out waiting to acquire lock file for module '%0'">, InGroup<ModuleBuild>;
 def err_module_cycle : Error<"cyclic dependency in module '%0': %1">, 
   DefaultFatal;
 def err_module_prebuilt : Error<
@@ -222,6 +226,11 @@
 def warn_arcmt_nsalloc_realloc : Warning<"[rewriter] call returns pointer to GC managed memory; it will become unmanaged in ARC">;
 def err_arcmt_nsinvocation_ownership : Error<"NSInvocation's %0 is not safe to be used with an object with ownership other than __unsafe_unretained">;
 
+// API notes
+def err_apinotes_message : Error<"%0">;
+def warn_apinotes_message : Warning<"%0">, InGroup<DiagGroup<"apinotes">>;
+def note_apinotes_message : Note<"%0">;
+
 // OpenMP
 def err_omp_more_one_clause : Error<
   "directive '#pragma omp %0' cannot contain more than one '%1' clause%select{| with '%3' name modifier| with 'source' dependence}2">;
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td
index 2fcd3a5..12775fd 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -92,7 +92,7 @@
 def err_drv_command_signalled : Error<
   "%0 command failed due to signal (use -v to see invocation)">;
 def err_drv_force_crash : Error<
-  "failing because environment variable '%0' is set">;
+  "failing because %select{environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set|'-gen-reproducer' is used}0">;
 def err_drv_invalid_mfloat_abi : Error<
   "invalid float ABI '%0'">;
 def err_drv_invalid_libcxx_deployment : Error<
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 1267f8d..257448e 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -222,6 +222,10 @@
 def err_invalid_vfs_overlay : Error<
   "invalid virtual filesystem overlay file '%0'">, DefaultFatal;
 
+def err_no_apinotes_cache_path : Error<
+  "-fapinotes was provided without -fapinotes-cache-path=<directory>">,
+  DefaultFatal;
+
 def warn_option_invalid_ocl_version : Warning<
   "OpenCL version %0 does not support the option '%1'">, InGroup<Deprecated>;
 }
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 4173d03..a2dcc70 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -219,7 +219,6 @@
 def DanglingElse: DiagGroup<"dangling-else">;
 def DanglingField : DiagGroup<"dangling-field">;
 def DistributedObjectModifiers : DiagGroup<"distributed-object-modifiers">;
-def ExpansionToDefined : DiagGroup<"expansion-to-defined">;
 def FlagEnum : DiagGroup<"flag-enum">;
 def IncrementBool : DiagGroup<"increment-bool", [DeprecatedIncrementBool]>;
 def InfiniteRecursion : DiagGroup<"infinite-recursion">;
@@ -386,6 +385,9 @@
 def StringPlusInt : DiagGroup<"string-plus-int">;
 def StringPlusChar : DiagGroup<"string-plus-char">;
 def StrncatSize : DiagGroup<"strncat-size">;
+
+def SwiftNameAttribute : DiagGroup<"swift-name-attribute">;
+
 def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
 def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
 def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
@@ -454,7 +456,9 @@
 def IgnoredPragmaIntrinsic : DiagGroup<"ignored-pragma-intrinsic">;
 def UnknownPragmas : DiagGroup<"unknown-pragmas">;
 def IgnoredPragmas : DiagGroup<"ignored-pragmas", [IgnoredPragmaIntrinsic]>;
-def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas]>;
+def PragmaClangAttribute : DiagGroup<"pragma-clang-attribute">;
+def Pragmas : DiagGroup<"pragmas", [UnknownPragmas, IgnoredPragmas,
+                                    PragmaClangAttribute]>;
 def UnknownWarningOption : DiagGroup<"unknown-warning-option">;
 def NSobjectAttribute : DiagGroup<"NSObject-attribute">;
 def IndependentClassAttribute : DiagGroup<"IndependentClass-attribute">;
@@ -878,6 +882,7 @@
 def BackendOptimizationFailure : DiagGroup<"pass-failed">;
 
 // Instrumentation based profiling warnings.
+def ProfileInstrMissing : DiagGroup<"profile-instr-missing">;
 def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;
 def ProfileInstrUnprofiled : DiagGroup<"profile-instr-unprofiled">;
 
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index fcd04a0..d13ae4c 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -36,7 +36,7 @@
       DIAG_START_AST           = DIAG_START_PARSE           +  500,
       DIAG_START_COMMENT       = DIAG_START_AST             +  110,
       DIAG_START_SEMA          = DIAG_START_COMMENT         +  100,
-      DIAG_START_ANALYSIS      = DIAG_START_SEMA            + 3500,
+      DIAG_START_ANALYSIS      = DIAG_START_SEMA            + 4000,
       DIAG_UPPER_LIMIT         = DIAG_START_ANALYSIS        +  100
     };
 
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 7f7022b..5a07acc 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -242,6 +242,7 @@
   "illegal character encoding in character literal">,
   InGroup<InvalidSourceEncoding>;
 def err_lexing_string : Error<"failure when lexing a string">;
+def err_placeholder_in_source : Error<"editor placeholder in source file">;
 
 
 //===----------------------------------------------------------------------===//
@@ -502,7 +503,7 @@
    InGroup<UnknownPragmas>;
 def warn_pragma_diagnostic_unknown_warning :
    ExtWarn<"unknown warning group '%0', ignored">,
-   InGroup<UnknownPragmas>;
+   InGroup<UnknownWarningOption>;
 // - #pragma __debug
 def warn_pragma_debug_unexpected_command : Warning<
   "unexpected debug command '%0'">, InGroup<IgnoredPragmas>;
@@ -679,13 +680,6 @@
 def note_header_guard : Note<
   "%0 is defined here; did you mean %1?">;
 
-def warn_defined_in_object_type_macro : Warning<
-  "macro expansion producing 'defined' has undefined behavior">,
-  InGroup<ExpansionToDefined>;
-def warn_defined_in_function_type_macro : Extension<
-  "macro expansion producing 'defined' has undefined behavior">,
-  InGroup<ExpansionToDefined>;
-
 let CategoryName = "Nullability Issue" in {
 
 def err_pp_assume_nonnull_syntax : Error<"expected 'begin' or 'end'">;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 0943fea..1b27204 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -361,8 +361,6 @@
 /// Objective-C parser diagnostics
 def err_expected_minus_or_plus : Error<
   "method type specifier must start with '-' or '+'">;
-def err_objc_no_attributes_on_category : Error<
-  "attributes may not be specified on a category">;
 def err_objc_missing_end : Error<"missing '@end'">;
 def note_objc_container_start : Note<
   "%select{class|protocol|category|class extension|implementation"
@@ -435,6 +433,13 @@
   "declaration does not declare a parameter">;
 def err_no_matching_param : Error<"parameter named %0 is missing">;
 
+/// Objective-C++ parser diagnostics
+def err_expected_token_instead_of_objcxx_keyword : Error<
+  "expected %0; %1 is a keyword in Objective-C++">;
+def err_expected_member_name_or_semi_objcxx_keyword : Error<
+  "expected member name or ';' after declaration specifiers; "
+  "%0 is a keyword in Objective-C++">;
+
 /// C++ parser diagnostics
 def err_invalid_operator_on_type : Error<
   "cannot use %select{dot|arrow}0 operator on a type">;
@@ -859,6 +864,12 @@
 def err_availability_query_repeated_star : Error<
   "'*' query has already been specified">;
 
+// External source symbol attribute
+def err_external_source_symbol_expected_keyword : Error<
+  "expected 'language', 'defined_in', or 'generated_declaration'">;
+def err_external_source_symbol_duplicate_clause : Error<
+  "duplicate %0 clause in an 'external_source_symbol' attribute">;
+
 // Type safety attributes
 def err_type_safety_unknown_flag : Error<
   "invalid comparison flag %0; use 'layout_compatible' or 'must_be_null'">;
@@ -968,6 +979,43 @@
   "expected 'on' or 'off'">;
 def err_pragma_optimize_extra_argument : Error<
   "unexpected extra argument '%0' to '#pragma clang optimize'">;
+// - #pragma clang attribute
+def err_pragma_attribute_expected_push_pop : Error<
+  "expected 'push' or 'pop' after '#pragma clang attribute'">;
+def err_pragma_attribute_invalid_argument : Error<
+  "unexpected argument '%0' to '#pragma clang attribute'; "
+  "expected 'push' or 'pop'">;
+def err_pragma_attribute_expected_attribute : Error<
+  "expected an attribute after '('">;
+def err_pragma_attribute_expected_attribute_name : Error<
+  "expected identifier that represents an attribute name">;
+def err_pragma_attribute_extra_tokens_after_attribute : Error<
+  "extra tokens after attribute in a '#pragma clang attribute push'">;
+def err_pragma_attribute_unsupported_attribute : Error<
+  "attribute %0 is not supported by '#pragma clang attribute'">;
+def err_pragma_attribute_multiple_attributes : Error<
+  "more than one attribute specified in '#pragma clang attribute push'">;
+def err_pragma_attribute_expected_attribute_syntax : Error<
+  "expected an attribute that is specified using the GNU, C++11 or '__declspec'"
+  " syntax">;
+def note_pragma_attribute_use_attribute_kw : Note<"use the GNU '__attribute__' "
+  "syntax">;
+def err_pragma_attribute_invalid_subject_set_specifier : Error<
+  "expected attribute subject set specifier 'apply_to'">;
+def err_pragma_attribute_expected_subject_identifier : Error<
+  "expected an identifier that corresponds to an attribute subject rule">;
+def err_pragma_attribute_unknown_subject_rule : Error<
+  "unknown attribute subject rule '%0'">;
+def err_pragma_attribute_expected_subject_sub_identifier : Error<
+  "expected an identifier that corresponds to an attribute subject matcher "
+  "sub-rule; '%0' matcher %select{does not support sub-rules|supports the "
+  "following sub-rules: %2|}1">;
+def err_pragma_attribute_unknown_subject_sub_rule : Error<
+  "%select{invalid use of|unknown}2 attribute subject matcher sub-rule '%0'; "
+  "'%1' matcher %select{does not support sub-rules|supports the following "
+  "sub-rules: %3}2">;
+def err_pragma_attribute_duplicate_subject : Error<
+  "duplicate attribute subject matcher '%0'">;
 
 def err_opencl_unroll_hint_on_non_loop : Error<
   "OpenCL only supports 'opencl_unroll_hint' attribute on for, while, and do statements">;
@@ -1036,9 +1084,22 @@
 def err_pragma_loop_invalid_option : Error<
   "%select{invalid|missing}0 option%select{ %1|}0; expected vectorize, "
   "vectorize_width, interleave, interleave_count, unroll, unroll_count, or distribute">;
+
+def err_pragma_fp_invalid_option : Error<
+  "%select{invalid|missing}0 option%select{ %1|}0; expected contract">;
+def err_pragma_fp_invalid_argument : Error<
+  "unexpected argument '%0' to '#pragma clang fp %1'; "
+  "expected 'on', 'fast' or 'off'">;
+def err_pragma_fp_scope : Error<
+  "'#pragma clang fp' can only appear at file scope or at the start of a "
+  "compound statement">;
+
 def err_pragma_invalid_keyword : Error<
   "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;
 
+// API notes.
+def err_type_unparsed : Error<"unparsed tokens following type">;
+
 // Pragma unroll support.
 def warn_pragma_unroll_cuda_value_in_parens : Warning<
   "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index c934351..8b44e0f 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -742,6 +742,25 @@
 def err_pragma_loop_precedes_nonloop : Error<
   "expected a for, while, or do-while loop to follow '%0'">;
 
+def err_pragma_attribute_matcher_subrule_contradicts_rule : Error<
+  "redundant attribute subject matcher sub-rule '%0'; '%1' already matches "
+  "those declarations">;
+def err_pragma_attribute_matcher_negated_subrule_contradicts_subrule : Error<
+  "negated attribute subject matcher sub-rule '%0' contradicts sub-rule '%1'">;
+def err_pragma_attribute_invalid_matchers : Error<
+  "attribute %0 can't be applied to %1">;
+def err_pragma_attribute_stack_mismatch : Error<
+  "'#pragma clang attribute pop' with no matching '#pragma clang attribute push'">;
+def warn_pragma_attribute_unused : Warning<
+  "unused attribute %0 in '#pragma clang attribute push' region">,
+  InGroup<PragmaClangAttribute>;
+def note_pragma_attribute_region_ends_here : Note<
+  "'#pragma clang attribute push' regions ends here">;
+def err_pragma_attribute_no_pop_eof : Error<"unterminated "
+  "'#pragma clang attribute push' at end of file">;
+def note_pragma_attribute_applied_decl_here : Note<
+  "when applied to this declaration">;
+
 /// Objective-C parser diagnostics
 def err_duplicate_class_def : Error<
   "duplicate interface definition for class %0">;
@@ -1153,6 +1172,10 @@
 def err_objc_kindof_wrong_position : Error<
   "'__kindof' type specifier must precede the declarator">;
 
+def err_objc_method_unsupported_param_ret_type : Error<
+  "%0 %select{parameter|return}1 type is unsupported; "
+  "support for vector types for this target is introduced in %2">;
+
 // C++ declarations
 def err_static_assert_expression_is_not_constant : Error<
   "static_assert expression is not an integral constant expression">;
@@ -1664,8 +1687,8 @@
   "cannot initialize %select{a variable|a parameter|return object|an "
   "exception object|a member subobject|an array element|a new value|a value|a "
   "base class|a constructor delegation|a vector element|a block element|a "
-  "complex element|a lambda capture|a compound literal initializer|a "
-  "related result|a parameter of CF audited function}0 "
+  "block element|a complex element|a lambda capture|a compound literal "
+  "initializer|a related result|a parameter of CF audited function}0 "
   "%diff{of type $ with an %select{rvalue|lvalue}2 of type $|"
   "with an %select{rvalue|lvalue}2 of incompatible type}1,3"
   "%select{|: different classes%diff{ ($ vs $)|}5,6"
@@ -2640,6 +2663,7 @@
   "|types and namespaces"
   "|Objective-C interfaces"
   "|methods and properties"
+  "|functions, methods, and properties"
   "|struct or union"
   "|struct, union or class"
   "|types"
@@ -2659,7 +2683,8 @@
   "|functions, methods, enums, and classes"
   "|structs, classes, variables, functions, and inline namespaces"
   "|variables, functions, methods, types, enumerations, enumerators, labels, and non-static data members"
-  "|classes and enumerations}1">,
+  "|classes and enumerations"
+  "|named declarations}1">,
   InGroup<IgnoredAttributes>;
 def err_attribute_wrong_decl_type : Error<warn_attribute_wrong_decl_type.Text>;
 def warn_type_attribute_wrong_type : Warning<
@@ -2735,6 +2760,9 @@
   InGroup<Availability>;
 def note_overridden_method : Note<
   "overridden method is here">;
+def warn_availability_swift_unavailable_deprecated_only : Warning<
+  "only 'unavailable' and 'deprecated' are supported for Swift availability">,
+  InGroup<Availability>;
 def note_protocol_method : Note<
   "protocol method is here">;
 
@@ -2746,12 +2774,17 @@
 def note_partial_availability_silence : Note<
   "explicitly redeclare %0 to silence this warning">;
 def note_unguarded_available_silence : Note<
-  "enclose %0 in an @available check to silence this warning">;
+  "enclose %0 in %select{an @available|a __builtin_available}1 check to silence"
+  " this warning">;
 def warn_partial_message : Warning<"%0 is partial: %1">,
     InGroup<UnguardedAvailability>, DefaultIgnore;
 def warn_partial_fwdclass_message : Warning<
     "%0 may be partial because the receiver type is unknown">,
     InGroup<UnguardedAvailability>, DefaultIgnore;
+def warn_at_available_unchecked_use : Warning<
+  "%select{@available|__builtin_available}0 does not guard availability here; "
+  "use if (%select{@available|__builtin_available}0) instead">,
+  InGroup<DiagGroup<"unsupported-availability-guard">>;
 
 // Thread Safety Attributes
 def warn_invalid_capability_name : Warning<
@@ -3103,6 +3136,9 @@
 def warn_attribute_nonnull_parm_no_args : Warning<
   "'nonnull' attribute when used on parameters takes no arguments">,
   InGroup<IgnoredAttributes>;
+def warn_attribute_noescape_non_pointer : Warning<
+  "'noescape' attribute ignored on parameter of non-pointer type %0">,
+  InGroup<IgnoredAttributes>;
 def note_declared_nonnull : Note<
   "declared %select{'returns_nonnull'|'nonnull'}0 here">;
 def warn_attribute_sentinel_named_arguments : Warning<
@@ -3225,6 +3261,68 @@
 def err_objc_attr_protocol_requires_definition : Error<
   "attribute %0 can only be applied to @protocol definitions, not forward declarations">;
 
+// Swift attributes
+def warn_attr_swift_name_decl_kind : Warning<
+  "%0 attribute cannot be applied to this declaration">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_function : Warning<
+  "parameter of %0 attribute must be a Swift function name string">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_function_no_prototype : Warning<
+  "%0 attribute can only be applied to function declarations with prototypes">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_context_name_invalid_identifier : Warning<
+  "%0 attribute has invalid identifier for context name">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_basename_invalid_identifier : Warning<
+  "%0 attribute has invalid identifier for base name">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_parameter_invalid_identifier : Warning<
+  "%0 attribute has invalid identifier for parameter name">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_missing_parameters : Warning<
+  "%0 attribute is missing parameter label clause">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_not_accessor : Warning<
+  "%0 attribute for 'subscript' must be a getter or setter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_no_parameter : Warning<
+  "%0 attribute for 'subscript' must take at least one parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_getter_newValue : Warning<
+  "%0 attribute for 'subscript' getter cannot take a 'newValue:' parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_setter_no_newValue : Warning<
+  "%0 attribute for 'subscript' setter must take a 'newValue:' parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_subscript_setter_multiple_newValues : Warning<
+  "%0 attribute for 'subscript' setter cannot take multiple 'newValue:' parameters">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_getter_parameters : Warning<
+  "%0 attribute for getter must not take any parameters besides 'self:'">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_setter_parameters : Warning<
+  "%0 attribute for setter must take one parameter for new value">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_multiple_selfs : Warning<
+  "%0 attribute cannot specify more than one 'self:' parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_static_subscript : Warning<
+  "%0 attribute for 'subscript' must take a 'self:' parameter">,
+  InGroup<SwiftNameAttribute>;
+def warn_attr_swift_name_num_params : Warning<
+  "too %select{few|many}0 parameters in %1 attribute (expected %2; got %3)">,
+  InGroup<SwiftNameAttribute>;
+def err_attr_swift_error_no_error_parameter : Error<
+  "%0 attribute can only be applied to a %select{function|method}1 "
+  "with an error parameter">;
+def err_attr_swift_error_return_type : Error<
+  "%0 attribute with '%1' convention can only be applied to a "
+  "%select{function|method}2 returning %select{an integral type|a pointer}3">;
+def warn_swift_newtype_attribute_non_typedef : Warning<
+  "'swift_newtype' attribute may be put on a typedef only; "
+  "attribute is ignored">, InGroup<DiagGroup<"swift-newtype-attribute">>;
+
 // Function Parameter Semantic Analysis.
 def err_param_with_void_type : Error<"argument may not have 'void' type">;
 def err_void_only_param : Error<
@@ -4476,6 +4574,8 @@
   "cannot add 'abi_tag' attribute in a redeclaration">;
 def err_new_abi_tag_on_redeclaration : Error<
   "'abi_tag' %0 missing in original declaration">;
+def note_use_ifdef_guards :
+  Note <"unguarded header; consider using #ifdef guards or #pragma once">;
 
 def note_deleted_dtor_no_operator_delete : Note<
   "virtual destructor requires an unambiguous, accessible 'operator delete'">;
@@ -4862,6 +4962,8 @@
   "jump enters controlled statement of if available">;
 def note_protected_by_vla : Note<
   "jump bypasses initialization of variable length array">;
+def note_protected_by_objc_fast_enumeration : Note<
+  "jump enters Objective-C fast enumeration loop">;
 def note_protected_by_objc_try : Note<
   "jump bypasses initialization of @try block">;
 def note_protected_by_objc_catch : Note<
@@ -5164,7 +5266,7 @@
 def warn_block_capture_autoreleasing : Warning<
   "block captures an autoreleasing out-parameter, which may result in "
   "use-after-free bugs">,
-  InGroup<BlockCaptureAutoReleasing>, DefaultIgnore;
+  InGroup<BlockCaptureAutoReleasing>;
 def note_declare_parameter_autoreleasing : Note<
   "declare the parameter __autoreleasing explicitly to suppress this warning">;
 def note_declare_parameter_strong : Note<
@@ -5916,6 +6018,12 @@
   "adding '%0' to '%1' might cause circular dependency in container">,
   InGroup<DiagGroup<"objc-circular-container">>;
 def note_objc_circular_container_declared_here : Note<"'%0' declared here">;
+def warn_objc_unsafe_perform_selector : Warning<
+  "%0 is incompatible with selectors that return a "
+  "%select{struct|union|vector}1 type">,
+  InGroup<DiagGroup<"objc-unsafe-perform-selector">>;
+def note_objc_unsafe_perform_selector_method_declared_here :  Note<
+  "method %0 that returns %1 declared here">;
 
 def warn_setter_getter_impl_required : Warning<
   "property %0 requires method %1 to be defined - "
@@ -7979,6 +8087,14 @@
 def err_nsreturns_retained_attribute_mismatch : Error<
   "overriding method has mismatched ns_returns_%select{not_retained|retained}0"
   " attributes">;
+
+def err_nserrordomain_not_tagdecl : Error<
+  "ns_error_domain attribute only valid on "
+  "%select{enums, structs, and unions|enums, structs, unions, and classes}0">;
+def err_nserrordomain_invalid_decl : Error<
+  "domain argument %0 does not refer to global constant">;
+def err_nserrordomain_requires_identifier : Error<
+  "domain argument must be an identifier">;
   
 def note_getter_unavailable : Note<
   "or because setter is declared here, but no getter method %0 is found">;
@@ -8237,6 +8353,13 @@
   InGroup<OpenCLUnsupportedRGBA>;
 } // end of sema category
 
+let CategoryName = "API Notes Issue" in {
+
+def err_incompatible_replacement_type : Error<
+  "API notes replacement type %0 has a different size from original type %1">;
+
+}
+
 let CategoryName = "OpenMP Issue" in {
 // OpenMP support.
 def err_omp_expected_var_arg : Error<
@@ -8702,6 +8825,13 @@
   InGroup<DiagGroup<"modules-ambiguous-internal-linkage">>;
 def note_equivalent_internal_linkage_decl : Note<
   "declared here%select{ in module '%1'|}0">;
+
+def note_redefinition_modules_same_file : Note<
+	"'%0' included multiple times, additional include site in header from module '%1'">;
+def note_redefinition_modules_same_file_modulemap : Note<
+	"consider adding '%0' as part of '%1' definition in">;
+def note_redefinition_include_same_file : Note<
+	"'%0' included multiple times, additional include site here">;
 }
 
 let CategoryName = "Coroutines Issue" in {
@@ -8749,8 +8879,13 @@
 let CategoryName = "Instrumentation Issue" in {
 def warn_profile_data_out_of_date : Warning<
   "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1"
-  " no data and %2 %plural{1:has|:have}2 mismatched data that will be ignored">,
+  " mismatched data that will be ignored">,
   InGroup<ProfileInstrOutOfDate>;
+def warn_profile_data_missing : Warning<
+  "profile data may be incomplete: of %0 function%s0, %1 %plural{1:has|:have}1"
+  " no data">,
+  InGroup<ProfileInstrMissing>,
+  DefaultIgnore;
 def warn_profile_data_unprofiled : Warning<
   "no profile data available for file \"%0\"">,
   InGroup<ProfileInstrUnprofiled>;
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 066a1f5..46adf2c 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -125,6 +125,11 @@
   "duplicate module file extension block name '%0'">,
   InGroup<ModuleFileExtension>;
 
+def warn_module_system_bit_conflict : Warning<
+  "module file '%0' was validated as a system module and is now being imported "
+  "as a non-system module; any difference in diagnostic options will be ignored">,
+  InGroup<ModuleConflict>;
+
 } // let CategoryName
 } // let Component
 
diff --git a/include/clang/Basic/FileSystemOptions.h b/include/clang/Basic/FileSystemOptions.h
index 38f1346..1beb2e2 100644
--- a/include/clang/Basic/FileSystemOptions.h
+++ b/include/clang/Basic/FileSystemOptions.h
@@ -25,6 +25,9 @@
   /// \brief If set, paths are resolved as if the working directory was
   /// set to the value of WorkingDir.
   std::string WorkingDir;
+
+  /// The path to the API notes cache.
+  std::string APINotesCachePath;
 };
 
 } // end namespace clang
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 3001d0b..c6448e6 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -73,9 +73,6 @@
                                    // partially) from an AST file.
   bool ChangedAfterLoad       : 1; // True if identifier has changed from the
                                    // definition loaded from an AST file.
-  bool FEChangedAfterLoad     : 1; // True if identifier's frontend information
-                                   // has changed from the definition loaded
-                                   // from an AST file.
   bool RevertedTokenID        : 1; // True if revertTokenIDToIdentifier was
                                    // called.
   bool OutOfDate              : 1; // True if there may be additional
@@ -83,7 +80,7 @@
                                    // stored externally.
   bool IsModulesImport        : 1; // True if this is the 'import' contextual
                                    // keyword.
-  // 29 bit left in 64-bit word.
+  // 30 bit left in 64-bit word.
 
   void *FETokenInfo;               // Managed by the language front-end.
   llvm::StringMapEntry<IdentifierInfo*> *Entry;
@@ -280,7 +277,11 @@
   bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
 
   /// \brief Return true if this token is a keyword in the specified language.
-  bool isKeyword(const LangOptions &LangOpts);
+  bool isKeyword(const LangOptions &LangOpts) const;
+
+  /// \brief Return true if this token is a C++ keyword in the specified
+  /// language.
+  bool isCPlusPlusKeyword(const LangOptions &LangOpts) const;
 
   /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to
   /// associate arbitrary metadata with this token.
@@ -313,18 +314,6 @@
     ChangedAfterLoad = true;
   }
 
-  /// \brief Determine whether the frontend token information for this
-  /// identifier has changed since it was loaded from an AST file.
-  bool hasFETokenInfoChangedSinceDeserialization() const {
-    return FEChangedAfterLoad;
-  }
-  
-  /// \brief Note that the frontend token information for this identifier has
-  /// changed since it was loaded from an AST file.
-  void setFETokenInfoChangedSinceDeserialization() {
-    FEChangedAfterLoad = true;
-  }
-
   /// \brief Determine whether the information for this identifier is out of
   /// date with respect to the external source.
   bool isOutOfDate() const { return OutOfDate; }
@@ -351,6 +340,19 @@
       RecomputeNeedsHandleIdentifier();
   }
 
+  /// Return true if this identifier is an editor placeholder.
+  ///
+  /// Editor placeholders are produced by the code-completion engine and are
+  /// represented as characters between '<#' and '#>' in the source code. An
+  /// example of auto-completed call with a placeholder parameter is shown
+  /// below:
+  /// \code
+  ///   function(<#int x#>);
+  /// \endcode
+  bool isEditorPlaceholder() const {
+    return getName().startswith("<#") && getName().endswith("#>");
+  }
+
   /// \brief Provide less than operator for lexicographical sorting.
   bool operator<(const IdentifierInfo &RHS) const {
     return getName() < RHS.getName();
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index d944a9d..78a0a20 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -153,6 +153,7 @@
 BENIGN_LANGOPT(ModulesErrorRecovery, 1, 1, "automatically importing modules as needed when performing error recovery")
 BENIGN_LANGOPT(ImplicitModules, 1, 1, "building modules that are not specified via -fmodule-file")
 COMPATIBLE_LANGOPT(ModulesLocalVisibility, 1, 0, "local submodule visibility")
+COMPATIBLE_LANGOPT(ModulesHashErrorDiags, 1, 0, "hash out diagnostic errors as part of the module hash")
 COMPATIBLE_LANGOPT(Optimize          , 1, 0, "__OPTIMIZE__ predefined macro")
 COMPATIBLE_LANGOPT(OptimizeSize      , 1, 0, "__OPTIMIZE_SIZE__ predefined macro")
 COMPATIBLE_LANGOPT(Static            , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)")
@@ -215,7 +216,8 @@
 BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
 LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
 LANGOPT(FastRelaxedMath , 1, 0, "OpenCL fast relaxed math")
-LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT")
+/// \brief FP_CONTRACT mode (on/off/fast).
+ENUM_LANGOPT(DefaultFPContractMode, FPContractModeKind, 2, FPC_Off, "FP contraction type")
 LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment")
 LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility")
 LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting")
@@ -256,11 +258,16 @@
 LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
 
 LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
+LANGOPT(APINotes, 1, 0, "use external API notes")
+LANGOPT(APINotesModules, 1, 0, "use external API notes")
 
 LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
                                            "field padding (0: none, 1:least "
                                            "aggressive, 2: more aggressive)")
 
+BENIGN_LANGOPT(AllowEditorPlaceholders, 1, 0,
+               "allow editor placeholders in source")
+
 #undef LANGOPT
 #undef COMPATIBLE_LANGOPT
 #undef BENIGN_LANGOPT
diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h
index 10635b1..9066916 100644
--- a/include/clang/Basic/LangOptions.h
+++ b/include/clang/Basic/LangOptions.h
@@ -88,6 +88,12 @@
     MSVC2015 = 19
   };
 
+  enum FPContractModeKind {
+    FPC_Off,        // Form fused FP ops only where result will not be affected.
+    FPC_On,         // Form fused FP ops according to FP_CONTRACT rules.
+    FPC_Fast        // Aggressively fuse FP ops (E.g. FMA).
+  };
+
 public:
   /// \brief Set of enabled sanitizers.
   SanitizerSet Sanitize;
@@ -170,17 +176,45 @@
   /// \brief Is this a libc/libm function that is no longer recognized as a
   /// builtin because a -fno-builtin-* option has been specified?
   bool isNoBuiltinFunc(StringRef Name) const;
+
+  /// \brief True if any ObjC types may have non-trivial lifetime qualifiers.
+  bool allowsNonTrivialObjCLifetimeQualifiers() const {
+    return ObjCAutoRefCount || ObjCWeak;
+  }
 };
 
 /// \brief Floating point control options
 class FPOptions {
 public:
-  unsigned fp_contract : 1;
+  FPOptions() : fp_contract(LangOptions::FPC_Off) {}
 
-  FPOptions() : fp_contract(0) {}
+  // Used for serializing.
+  explicit FPOptions(unsigned I)
+      : fp_contract(static_cast<LangOptions::FPContractModeKind>(I)) {}
 
-  FPOptions(const LangOptions &LangOpts) :
-    fp_contract(LangOpts.DefaultFPContract) {}
+  explicit FPOptions(const LangOptions &LangOpts)
+      : fp_contract(LangOpts.getDefaultFPContractMode()) {}
+
+  bool allowFPContractWithinStatement() const {
+    return fp_contract == LangOptions::FPC_On;
+  }
+  bool allowFPContractAcrossStatement() const {
+    return fp_contract == LangOptions::FPC_Fast;
+  }
+  void setAllowFPContractWithinStatement() {
+    fp_contract = LangOptions::FPC_On;
+  }
+  void setAllowFPContractAcrossStatement() {
+    fp_contract = LangOptions::FPC_Fast;
+  }
+  void setDisallowFPContract() { fp_contract = LangOptions::FPC_Off; }
+
+  /// Used to serialize this.
+  unsigned getInt() const { return fp_contract; }
+
+private:
+  /// Adjust BinaryOperator::FPFeatures to match the bit-field size of this.
+  unsigned fp_contract : 2;
 };
 
 /// \brief Describes the kind of translation unit being processed.
diff --git a/include/clang/Basic/MemoryBufferCache.h b/include/clang/Basic/MemoryBufferCache.h
new file mode 100644
index 0000000..c79c3c4
--- /dev/null
+++ b/include/clang/Basic/MemoryBufferCache.h
@@ -0,0 +1,80 @@
+//===- MemoryBufferCache.h - Cache for loaded memory buffers ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
+#define LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
+
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
+#include "llvm/ADT/StringMap.h"
+#include <memory>
+
+namespace llvm {
+class MemoryBuffer;
+} // end namespace llvm
+
+namespace clang {
+
+/// Manage memory buffers across multiple users.
+///
+/// Ensures that multiple users have a consistent view of each buffer.  This is
+/// used by \a CompilerInstance when building PCMs to ensure that each \a
+/// ModuleManager sees the same files.
+///
+/// \a finalizeCurrentBuffers() should be called before creating a new user.
+/// This locks in the current buffers, ensuring that no buffer that has already
+/// been accessed can be purged, preventing use-after-frees.
+class MemoryBufferCache : public llvm::RefCountedBase<MemoryBufferCache> {
+  struct BufferEntry {
+    std::unique_ptr<llvm::MemoryBuffer> Buffer;
+
+    /// Track the timeline of when this was added to the cache.
+    unsigned Index;
+  };
+
+  /// Cache of buffers.
+  llvm::StringMap<BufferEntry> Buffers;
+
+  /// Monotonically increasing index.
+  unsigned NextIndex = 0;
+
+  /// Bumped to prevent "older" buffers from being removed.
+  unsigned FirstRemovableIndex = 0;
+
+public:
+  /// Store the Buffer under the Filename.
+  ///
+  /// \pre There is not already buffer is not already in the cache.
+  /// \return a reference to the buffer as a convenience.
+  llvm::MemoryBuffer &addBuffer(llvm::StringRef Filename,
+                                std::unique_ptr<llvm::MemoryBuffer> Buffer);
+
+  /// Try to remove a buffer from the cache.
+  ///
+  /// \return false on success, iff \c !isBufferFinal().
+  bool tryToRemoveBuffer(llvm::StringRef Filename);
+
+  /// Get a pointer to the buffer if it exists; else nullptr.
+  llvm::MemoryBuffer *lookupBuffer(llvm::StringRef Filename);
+
+  /// Check whether the buffer is final.
+  ///
+  /// \return true iff \a finalizeCurrentBuffers() has been called since the
+  /// buffer was added.  This prevents buffers from being removed.
+  bool isBufferFinal(llvm::StringRef Filename);
+
+  /// Finalize the current buffers in the cache.
+  ///
+  /// Should be called when creating a new user to ensure previous uses aren't
+  /// invalidated.
+  void finalizeCurrentBuffers();
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_MEMORYBUFFERCACHE_H
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 31c5c7e..38004fc 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -42,7 +42,17 @@
   
 /// \brief Describes the name of a module.
 typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId;
-  
+
+/// The signature of a module, which is a hash of the AST content.
+struct ASTFileSignature : std::array<uint32_t, 5> {
+  ASTFileSignature(std::array<uint32_t, 5> S = {{0}})
+      : std::array<uint32_t, 5>(std::move(S)) {}
+
+  explicit operator bool() const {
+    return *this != std::array<uint32_t, 5>({{0}});
+  }
+};
+
 /// \brief Describes a module or submodule.
 class Module {
 public:
@@ -65,7 +75,7 @@
   llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
 
   /// \brief The module signature.
-  uint64_t Signature;
+  ASTFileSignature Signature;
 
   /// \brief The name of the umbrella entry, as written in the module map.
   std::string UmbrellaAsWritten;
@@ -147,6 +157,9 @@
   /// will be false to indicate that this (sub)module is not available.
   SmallVector<Requirement, 2> Requirements;
 
+  /// \brief A module with the same name that shadows this module.
+  Module *ShadowingModule = nullptr;
+
   /// \brief Whether this module is missing a feature from \c Requirements.
   unsigned IsMissingRequirement : 1;
 
@@ -180,6 +193,9 @@
   /// \brief Whether this is an inferred submodule (module * { ... }).
   unsigned IsInferred : 1;
 
+  /// \brief Whether this is a module who has its swift_names inferred.
+  unsigned IsSwiftInferImportAsMember : 1;
+
   /// \brief Whether we should infer submodules for this module based on 
   /// the headers.
   ///
@@ -325,13 +341,20 @@
   ///
   /// \param Target The target options used for the current translation unit.
   ///
-  /// \param Req If this module is unavailable, this parameter
-  /// will be set to one of the requirements that is not met for use of
-  /// this module.
+  /// \param Req If this module is unavailable because of a missing requirement,
+  /// this parameter will be set to one of the requirements that is not met for
+  /// use of this module.
+  ///
+  /// \param MissingHeader If this module is unavailable because of a missing
+  /// header, this parameter will be set to one of the missing headers.
+  ///
+  /// \param ShadowingModule If this module is unavailable because it is
+  /// shadowed, this parameter will be set to the shadowing module.
   bool isAvailable(const LangOptions &LangOpts, 
                    const TargetInfo &Target,
                    Requirement &Req,
-                   UnresolvedHeaderDirective &MissingHeader) const;
+                   UnresolvedHeaderDirective &MissingHeader,
+                   Module *&ShadowingModule) const;
 
   /// \brief Determine whether this module is a submodule.
   bool isSubModule() const { return Parent != nullptr; }
diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h
index 78fc899..8dc259c 100644
--- a/include/clang/Basic/ObjCRuntime.h
+++ b/include/clang/Basic/ObjCRuntime.h
@@ -326,6 +326,20 @@
     }
   }
 
+  /// Are the empty collection symbols available?
+  bool hasEmptyCollections() const {
+    switch (getKind()) {
+    default:
+      return false;
+    case MacOSX:
+      return getVersion() >= VersionTuple(10, 11);
+    case iOS:
+      return getVersion() >= VersionTuple(9);
+    case WatchOS:
+      return getVersion() >= VersionTuple(2);
+    }
+  }
+
   /// \brief Try to parse an Objective-C runtime specification from the given
   /// string.
   ///
diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index c81273e..c574045 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -64,6 +64,11 @@
 SANITIZER("integer-divide-by-zero", IntegerDivideByZero)
 SANITIZER("nonnull-attribute", NonnullAttribute)
 SANITIZER("null", Null)
+SANITIZER("nullability-arg", NullabilityArg)
+SANITIZER("nullability-assign", NullabilityAssign)
+SANITIZER("nullability-return", NullabilityReturn)
+SANITIZER_GROUP("nullability", Nullability,
+                NullabilityArg | NullabilityAssign | NullabilityReturn)
 SANITIZER("object-size", ObjectSize)
 SANITIZER("return", Return)
 SANITIZER("returns-nonnull-attribute", ReturnsNonnullAttribute)
diff --git a/include/clang/Basic/SourceMgrAdapter.h b/include/clang/Basic/SourceMgrAdapter.h
new file mode 100644
index 0000000..dd7b83f
--- /dev/null
+++ b/include/clang/Basic/SourceMgrAdapter.h
@@ -0,0 +1,85 @@
+//=== SourceMgrAdapter.h - SourceMgr to SourceManager Adapter ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file provides an adapter that maps diagnostics from llvm::SourceMgr
+// to Clang's SourceManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_SOURCEMGRADAPTER_H
+#define LLVM_CLANG_SOURCEMGRADAPTER_H
+
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/SourceMgr.h"
+#include <string>
+#include <utility>
+
+namespace clang {
+
+class DiagnosticsEngine;
+class FileEntry;
+
+/// An adapter that can be used to translate diagnostics from one or more
+/// llvm::SourceMgr instances to a ,
+class SourceMgrAdapter {
+  /// Clang source manager.
+  SourceManager &SrcMgr;
+
+  /// Clang diagnostics engine.
+  DiagnosticsEngine &Diag;
+
+  /// Diagnostic IDs for errors, warnings, and notes.
+  unsigned ErrorDiagID, WarningDiagID, NoteDiagID;
+
+  /// The default file to use when mapping buffers.
+  const FileEntry *DefaultFile;
+
+  /// A mapping from (LLVM source manager, buffer ID) pairs to the
+  /// corresponding file ID within the Clang source manager.
+  llvm::DenseMap<std::pair<const llvm::SourceMgr *, unsigned>, FileID>
+    FileIDMapping;
+
+  /// Diagnostic handler.
+  static void handleDiag(const llvm::SMDiagnostic &diag, void *context);
+
+public:
+  /// Create a new \c SourceMgr adaptor that maps to the given source
+  /// manager and diagnostics engine.
+  SourceMgrAdapter(SourceManager &srcMgr, DiagnosticsEngine &diag,
+                   unsigned errorDiagID, unsigned warningDiagID,
+                   unsigned noteDiagID, const FileEntry *defaultFile = nullptr);
+
+  ~SourceMgrAdapter();
+
+  /// Map a source location in the given LLVM source manager to its
+  /// corresponding location in the Clang source manager.
+  SourceLocation mapLocation(const llvm::SourceMgr &llvmSrcMgr,llvm::SMLoc loc);
+
+  /// Map a source range in the given LLVM source manager to its corresponding
+  /// range in the Clang source manager.
+  SourceRange mapRange(const llvm::SourceMgr &llvmSrcMgr, llvm::SMRange range);
+
+  /// Handle the given diagnostic from an LLVM source manager.
+  void handleDiag(const llvm::SMDiagnostic &diag);
+
+  /// Retrieve the diagnostic handler to use with the underlying SourceMgr.
+  llvm::SourceMgr::DiagHandlerTy getDiagHandler() {
+    return &SourceMgrAdapter::handleDiag;
+  }
+
+  /// Retrieve the context to use with the diagnostic handler produced by
+  /// \c getDiagHandler().
+  void *getDiagContext() { return this; }
+};
+
+
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 208f8e8..46db895 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -1032,6 +1032,21 @@
     return LangAS::opencl_global;
   }
 
+  /// \returns Target specific vtbl ptr address space.
+  virtual unsigned getVtblPtrAddressSpace() const {
+    return 0;
+  }
+
+  /// \returns If a target requires an address within a target specific address
+  /// space \p AddressSpace to be converted in order to be used, then return the
+  /// corresponding target specific DWARF address space.
+  ///
+  /// \returns Otherwise return None and no conversion will be emitted in the
+  /// DWARF.
+  virtual Optional<unsigned> getDWARFAddressSpace(unsigned AddressSpace) const {
+    return None;
+  }
+
   /// \brief Check the target is valid after it is fully initialized.
   virtual bool validateTarget(DiagnosticsEngine &Diags) const {
     return true;
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index 104b053..895c3d4 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -787,6 +787,11 @@
 // handles #pragma loop ... directives.
 ANNOTATION(pragma_loop_hint)
 
+ANNOTATION(pragma_fp)
+
+// Annotation for the attribute pragma directives - #pragma clang attribute ...
+ANNOTATION(pragma_attribute)
+
 // Annotations for module import translated from #include etc.
 ANNOTATION(module_include)
 ANNOTATION(module_begin)
diff --git a/include/clang/Basic/VersionTuple.h b/include/clang/Basic/VersionTuple.h
index da3b019..07315f0 100644
--- a/include/clang/Basic/VersionTuple.h
+++ b/include/clang/Basic/VersionTuple.h
@@ -17,6 +17,7 @@
 
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/DenseMapInfo.h"
 #include <string>
 #include <tuple>
 
@@ -70,6 +71,9 @@
     return Major == 0 && Minor == 0 && Subminor == 0 && Build == 0;
   }
 
+  /// Whether this is a non-empty version tuple.
+  explicit operator bool () const { return !empty(); }
+
   /// \brief Retrieve the major version number.
   unsigned getMajor() const { return Major; }
 
@@ -165,4 +169,35 @@
 raw_ostream& operator<<(raw_ostream &Out, const VersionTuple &V);
 
 } // end namespace clang
+
+namespace llvm {
+  // Provide DenseMapInfo for version tuples.
+  template<>
+  struct DenseMapInfo<clang::VersionTuple> {
+    static inline clang::VersionTuple getEmptyKey() {
+      return clang::VersionTuple(0x7FFFFFFF);
+    }
+    static inline clang::VersionTuple getTombstoneKey() {
+      return clang::VersionTuple(0x7FFFFFFE);
+    }
+    static unsigned getHashValue(const clang::VersionTuple& value) {
+      unsigned result = value.getMajor();
+      if (auto minor = value.getMinor())
+        result = combineHashValue(result, *minor);
+      if (auto subminor = value.getSubminor())
+        result = combineHashValue(result, *subminor);
+      if (auto build = value.getBuild())
+        result = combineHashValue(result, *build);
+
+      return result;
+    }
+
+    static bool isEqual(const clang::VersionTuple &lhs,
+                        const clang::VersionTuple &rhs) {
+      return lhs == rhs;
+    }
+  };
+
+} // end namespace llvm
+
 #endif // LLVM_CLANG_BASIC_VERSIONTUPLE_H
diff --git a/include/clang/Basic/VirtualFileSystem.h b/include/clang/Basic/VirtualFileSystem.h
index 39dab6c..e52b345 100644
--- a/include/clang/Basic/VirtualFileSystem.h
+++ b/include/clang/Basic/VirtualFileSystem.h
@@ -161,7 +161,7 @@
   directory_iterator &increment(std::error_code &EC) {
     assert(Impl && "attempting to increment past end");
     EC = Impl->increment();
-    if (EC || !Impl->CurrentEntry.isStatusKnown())
+    if (!Impl->CurrentEntry.isStatusKnown())
       Impl.reset(); // Normalize the end iterator to Impl == nullptr.
     return *this;
   }
diff --git a/include/clang/CodeGen/ConstantInitBuilder.h b/include/clang/CodeGen/ConstantInitBuilder.h
new file mode 100644
index 0000000..113d86d
--- /dev/null
+++ b/include/clang/CodeGen/ConstantInitBuilder.h
@@ -0,0 +1,561 @@
+//===- ConstantInitBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class provides a convenient interface for building complex
+// global initializers of the sort that are frequently required for
+// language ABIs.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
+#define LLVM_CLANG_CODEGEN_CONSTANTINITBUILDER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/GlobalValue.h"
+#include "clang/AST/CharUnits.h"
+#include "clang/CodeGen/ConstantInitFuture.h"
+
+#include <vector>
+
+namespace clang {
+namespace CodeGen {
+
+class CodeGenModule;
+
+/// A convenience builder class for complex constant initializers,
+/// especially for anonymous global structures used by various language
+/// runtimes.
+///
+/// The basic usage pattern is expected to be something like:
+///    ConstantInitBuilder builder(CGM);
+///    auto toplevel = builder.beginStruct();
+///    toplevel.addInt(CGM.SizeTy, widgets.size());
+///    auto widgetArray = builder.beginArray();
+///    for (auto &widget : widgets) {
+///      auto widgetDesc = widgetArray.beginStruct();
+///      widgetDesc.addInt(CGM.SizeTy, widget.getPower());
+///      widgetDesc.add(CGM.GetAddrOfConstantString(widget.getName()));
+///      widgetDesc.add(CGM.GetAddrOfGlobal(widget.getInitializerDecl()));
+///      widgetDesc.finishAndAddTo(widgetArray);
+///    }
+///    widgetArray.finishAndAddTo(toplevel);
+///    auto global = toplevel.finishAndCreateGlobal("WIDGET_LIST", Align,
+///                                                 /*constant*/ true);
+class ConstantInitBuilderBase {
+  struct SelfReference {
+    llvm::GlobalVariable *Dummy;
+    llvm::SmallVector<llvm::Constant*, 4> Indices;
+
+    SelfReference(llvm::GlobalVariable *dummy) : Dummy(dummy) {}
+  };
+  CodeGenModule &CGM;
+  llvm::SmallVector<llvm::Constant*, 16> Buffer;
+  std::vector<SelfReference> SelfReferences;
+  bool Frozen = false;
+
+  friend class ConstantInitFuture;
+  friend class ConstantAggregateBuilderBase;
+  template <class, class>
+  friend class ConstantAggregateBuilderTemplateBase;
+
+protected:
+  explicit ConstantInitBuilderBase(CodeGenModule &CGM) : CGM(CGM) {}
+
+  ~ConstantInitBuilderBase() {
+    assert(Buffer.empty() && "didn't claim all values out of buffer");
+    assert(SelfReferences.empty() && "didn't apply all self-references");
+  }
+
+private:
+  llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,
+                                     const llvm::Twine &name,
+                                     CharUnits alignment,
+                                     bool constant = false,
+                                     llvm::GlobalValue::LinkageTypes linkage
+                                       = llvm::GlobalValue::InternalLinkage,
+                                     unsigned addressSpace = 0);
+
+  ConstantInitFuture createFuture(llvm::Constant *initializer);
+
+  void setGlobalInitializer(llvm::GlobalVariable *GV,
+                            llvm::Constant *initializer);
+
+  void resolveSelfReferences(llvm::GlobalVariable *GV);
+
+  void abandon(size_t newEnd);
+};
+
+/// A concrete base class for struct and array aggregate
+/// initializer builders.
+class ConstantAggregateBuilderBase {
+protected:
+  ConstantInitBuilderBase &Builder;
+  ConstantAggregateBuilderBase *Parent;
+  size_t Begin;
+  mutable size_t CachedOffsetEnd = 0;
+  bool Finished = false;
+  bool Frozen = false;
+  bool Packed = false;
+  mutable CharUnits CachedOffsetFromGlobal;
+
+  llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() {
+    return Builder.Buffer;
+  }
+
+  const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const {
+    return Builder.Buffer;
+  }
+
+  ConstantAggregateBuilderBase(ConstantInitBuilderBase &builder,
+                               ConstantAggregateBuilderBase *parent)
+      : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {
+    if (parent) {
+      assert(!parent->Frozen && "parent already has child builder active");
+      parent->Frozen = true;
+    } else {
+      assert(!builder.Frozen && "builder already has child builder active");
+      builder.Frozen = true;
+    }
+  }
+
+  ~ConstantAggregateBuilderBase() {
+    assert(Finished && "didn't finish aggregate builder");
+  }
+
+  void markFinished() {
+    assert(!Frozen && "child builder still active");
+    assert(!Finished && "builder already finished");
+    Finished = true;
+    if (Parent) {
+      assert(Parent->Frozen &&
+             "parent not frozen while child builder active");
+      Parent->Frozen = false;
+    } else {
+      assert(Builder.Frozen &&
+             "builder not frozen while child builder active");
+      Builder.Frozen = false;
+    }
+  }
+
+public:
+  // Not copyable.
+  ConstantAggregateBuilderBase(const ConstantAggregateBuilderBase &) = delete;
+  ConstantAggregateBuilderBase &operator=(const ConstantAggregateBuilderBase &)
+    = delete;
+
+  // Movable, mostly to allow returning.  But we have to write this out
+  // properly to satisfy the assert in the destructor.
+  ConstantAggregateBuilderBase(ConstantAggregateBuilderBase &&other)
+    : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),
+      CachedOffsetEnd(other.CachedOffsetEnd),
+      Finished(other.Finished), Frozen(other.Frozen), Packed(other.Packed),
+      CachedOffsetFromGlobal(other.CachedOffsetFromGlobal) {
+    other.Finished = true;
+  }
+  ConstantAggregateBuilderBase &operator=(ConstantAggregateBuilderBase &&other)
+    = delete;
+
+  /// Return the number of elements that have been added to
+  /// this struct or array.
+  size_t size() const {
+    assert(!this->Finished && "cannot query after finishing builder");
+    assert(!this->Frozen && "cannot query while sub-builder is active");
+    assert(this->Begin <= this->getBuffer().size());
+    return this->getBuffer().size() - this->Begin;
+  }
+
+  /// Return true if no elements have yet been added to this struct or array.
+  bool empty() const {
+    return size() == 0;
+  }
+
+  /// Abandon this builder completely.
+  void abandon() {
+    markFinished();
+    Builder.abandon(Begin);
+  }
+
+  /// Add a new value to this initializer.
+  void add(llvm::Constant *value) {
+    assert(value && "adding null value to constant initializer");
+    assert(!Finished && "cannot add more values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    Builder.Buffer.push_back(value);
+  }
+
+  /// Add an integer value of type size_t.
+  void addSize(CharUnits size);
+
+  /// Add an integer value of a specific type.
+  void addInt(llvm::IntegerType *intTy, uint64_t value,
+              bool isSigned = false) {
+    add(llvm::ConstantInt::get(intTy, value, isSigned));
+  }
+
+  /// Add a null pointer of a specific type.
+  void addNullPointer(llvm::PointerType *ptrTy) {
+    add(llvm::ConstantPointerNull::get(ptrTy));
+  }
+
+  /// Add a bitcast of a value to a specific type.
+  void addBitCast(llvm::Constant *value, llvm::Type *type) {
+    add(llvm::ConstantExpr::getBitCast(value, type));
+  }
+
+  /// Add a bunch of new values to this initializer.
+  void addAll(llvm::ArrayRef<llvm::Constant *> values) {
+    assert(!Finished && "cannot add more values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    Builder.Buffer.append(values.begin(), values.end());
+  }
+
+  /// Add a relative offset to the given target address, i.e. the
+  /// static difference between the target address and the address
+  /// of the relative offset.  The target must be known to be defined
+  /// in the current linkage unit.  The offset will have the given
+  /// integer type, which must be no wider than intptr_t.  Some
+  /// targets may not fully support this operation.
+  void addRelativeOffset(llvm::IntegerType *type, llvm::Constant *target) {
+    add(getRelativeOffset(type, target));
+  }
+
+  /// Add a relative offset to the target address, plus a small
+  /// constant offset.  This is primarily useful when the relative
+  /// offset is known to be a multiple of (say) four and therefore
+  /// the tag can be used to express an extra two bits of information.
+  void addTaggedRelativeOffset(llvm::IntegerType *type,
+                               llvm::Constant *address,
+                               unsigned tag) {
+    llvm::Constant *offset = getRelativeOffset(type, address);
+    if (tag) {
+      offset = llvm::ConstantExpr::getAdd(offset,
+                                          llvm::ConstantInt::get(type, tag));
+    }
+    add(offset);
+  }
+
+  /// Return the offset from the start of the initializer to the
+  /// next position, assuming no padding is required prior to it.
+  ///
+  /// This operation will not succeed if any unsized placeholders are
+  /// currently in place in the initializer.
+  CharUnits getNextOffsetFromGlobal() const {
+    assert(!Finished && "cannot add more values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    return getOffsetFromGlobalTo(Builder.Buffer.size());
+  }
+
+  /// An opaque class to hold the abstract position of a placeholder.
+  class PlaceholderPosition {
+    size_t Index;
+    friend class ConstantAggregateBuilderBase;
+    PlaceholderPosition(size_t index) : Index(index) {}
+  };
+
+  /// Add a placeholder value to the structure.  The returned position
+  /// can be used to set the value later; it will not be invalidated by
+  /// any intermediate operations except (1) filling the same position or
+  /// (2) finishing the entire builder.
+  ///
+  /// This is useful for emitting certain kinds of structure which
+  /// contain some sort of summary field, generaly a count, before any
+  /// of the data.  By emitting a placeholder first, the structure can
+  /// be emitted eagerly.
+  PlaceholderPosition addPlaceholder() {
+    assert(!Finished && "cannot add more values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    Builder.Buffer.push_back(nullptr);
+    return Builder.Buffer.size() - 1;
+  }
+
+  /// Add a placeholder, giving the expected type that will be filled in.
+  PlaceholderPosition addPlaceholderWithSize(llvm::Type *expectedType);
+
+  /// Fill a previously-added placeholder.
+  void fillPlaceholderWithInt(PlaceholderPosition position,
+                              llvm::IntegerType *type, uint64_t value,
+                              bool isSigned = false) {
+    fillPlaceholder(position, llvm::ConstantInt::get(type, value, isSigned));
+  }
+
+  /// Fill a previously-added placeholder.
+  void fillPlaceholder(PlaceholderPosition position, llvm::Constant *value) {
+    assert(!Finished && "cannot change values after finishing builder");
+    assert(!Frozen && "cannot add values while subbuilder is active");
+    llvm::Constant *&slot = Builder.Buffer[position.Index];
+    assert(slot == nullptr && "placeholder already filled");
+    slot = value;
+  }
+
+  /// Produce an address which will eventually point to the the next
+  /// position to be filled.  This is computed with an indexed
+  /// getelementptr rather than by computing offsets.
+  ///
+  /// The returned pointer will have type T*, where T is the given
+  /// position.
+  llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type);
+
+  llvm::ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
+                           llvm::SmallVectorImpl<llvm::Constant*> &indices) {
+    getGEPIndicesTo(indices, Builder.Buffer.size());
+    return indices;
+  }
+
+protected:
+  llvm::Constant *finishArray(llvm::Type *eltTy);
+  llvm::Constant *finishStruct(llvm::StructType *structTy);
+
+private:
+  void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
+                       size_t position) const;
+
+  llvm::Constant *getRelativeOffset(llvm::IntegerType *offsetType,
+                                    llvm::Constant *target);
+
+  CharUnits getOffsetFromGlobalTo(size_t index) const;
+};
+
+template <class Impl, class Traits>
+class ConstantAggregateBuilderTemplateBase
+    : public Traits::AggregateBuilderBase {
+  using super = typename Traits::AggregateBuilderBase;
+public:
+  using InitBuilder = typename Traits::InitBuilder;
+  using ArrayBuilder = typename Traits::ArrayBuilder;
+  using StructBuilder = typename Traits::StructBuilder;
+  using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
+
+protected:
+  ConstantAggregateBuilderTemplateBase(InitBuilder &builder,
+                                       AggregateBuilderBase *parent)
+    : super(builder, parent) {}
+
+  Impl &asImpl() { return *static_cast<Impl*>(this); }
+
+public:
+  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
+    return ArrayBuilder(static_cast<InitBuilder&>(this->Builder), this, eltTy);
+  }
+
+  StructBuilder beginStruct(llvm::StructType *ty = nullptr) {
+    return StructBuilder(static_cast<InitBuilder&>(this->Builder), this, ty);
+  }
+
+  /// Given that this builder was created by beginning an array or struct
+  /// component on the given parent builder, finish the array/struct
+  /// component and add it to the parent.
+  ///
+  /// It is an intentional choice that the parent is passed in explicitly
+  /// despite it being redundant with information already kept in the
+  /// builder.  This aids in readability by making it easier to find the
+  /// places that add components to a builder, as well as "bookending"
+  /// the sub-builder more explicitly.
+  void finishAndAddTo(AggregateBuilderBase &parent) {
+    assert(this->Parent == &parent && "adding to non-parent builder");
+    parent.add(asImpl().finishImpl());
+  }
+
+  /// Given that this builder was created by beginning an array or struct
+  /// directly on a ConstantInitBuilder, finish the array/struct and
+  /// create a global variable with it as the initializer.
+  template <class... As>
+  llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
+    assert(!this->Parent && "finishing non-root builder");
+    return this->Builder.createGlobal(asImpl().finishImpl(),
+                                      std::forward<As>(args)...);
+  }
+
+  /// Given that this builder was created by beginning an array or struct
+  /// directly on a ConstantInitBuilder, finish the array/struct and
+  /// set it as the initializer of the given global variable.
+  void finishAndSetAsInitializer(llvm::GlobalVariable *global) {
+    assert(!this->Parent && "finishing non-root builder");
+    return this->Builder.setGlobalInitializer(global, asImpl().finishImpl());
+  }
+
+  /// Given that this builder was created by beginning an array or struct
+  /// directly on a ConstantInitBuilder, finish the array/struct and
+  /// return a future which can be used to install the initializer in
+  /// a global later.
+  ///
+  /// This is useful for allowing a finished initializer to passed to
+  /// an API which will build the global.  However, the "future" preserves
+  /// a dependency on the original builder; it is an error to pass it aside.
+  ConstantInitFuture finishAndCreateFuture() {
+    assert(!this->Parent && "finishing non-root builder");
+    return this->Builder.createFuture(asImpl().finishImpl());
+  }
+};
+
+template <class Traits>
+class ConstantArrayBuilderTemplateBase
+  : public ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder,
+                                                Traits> {
+  using super =
+    ConstantAggregateBuilderTemplateBase<typename Traits::ArrayBuilder, Traits>;
+
+public:
+  using InitBuilder = typename Traits::InitBuilder;
+  using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
+
+private:
+  llvm::Type *EltTy;
+
+  template <class, class>
+  friend class ConstantAggregateBuilderTemplateBase;
+
+protected:
+  ConstantArrayBuilderTemplateBase(InitBuilder &builder,
+                                   AggregateBuilderBase *parent,
+                                   llvm::Type *eltTy)
+    : super(builder, parent), EltTy(eltTy) {}
+
+private:
+  /// Form an array constant from the values that have been added to this
+  /// builder.
+  llvm::Constant *finishImpl() {
+    return AggregateBuilderBase::finishArray(EltTy);
+  }
+};
+
+/// A template class designed to allow other frontends to
+/// easily customize the builder classes used by ConstantInitBuilder,
+/// and thus to extend the API to work with the abstractions they
+/// prefer.  This would probably not be necessary if C++ just
+/// supported extension methods.
+template <class Traits>
+class ConstantStructBuilderTemplateBase
+  : public ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,
+                                                Traits> {
+  using super =
+    ConstantAggregateBuilderTemplateBase<typename Traits::StructBuilder,Traits>;
+
+public:
+  using InitBuilder = typename Traits::InitBuilder;
+  using AggregateBuilderBase = typename Traits::AggregateBuilderBase;
+
+private:
+  llvm::StructType *StructTy;
+
+  template <class, class>
+  friend class ConstantAggregateBuilderTemplateBase;
+
+protected:
+  ConstantStructBuilderTemplateBase(InitBuilder &builder,
+                                    AggregateBuilderBase *parent,
+                                    llvm::StructType *structTy)
+    : super(builder, parent), StructTy(structTy) {
+    if (structTy) this->Packed = structTy->isPacked();
+  }
+
+public:
+  void setPacked(bool packed) {
+    this->Packed = packed;
+  }
+
+  /// Use the given type for the struct if its element count is correct.
+  /// Don't add more elements after calling this.
+  void suggestType(llvm::StructType *structTy) {
+    if (this->size() == structTy->getNumElements()) {
+      StructTy = structTy;
+    }
+  }
+
+private:
+  /// Form an array constant from the values that have been added to this
+  /// builder.
+  llvm::Constant *finishImpl() {
+    return AggregateBuilderBase::finishStruct(StructTy);
+  }
+};
+
+/// A template class designed to allow other frontends to
+/// easily customize the builder classes used by ConstantInitBuilder,
+/// and thus to extend the API to work with the abstractions they
+/// prefer.  This would probably not be necessary if C++ just
+/// supported extension methods.
+template <class Traits>
+class ConstantInitBuilderTemplateBase : public ConstantInitBuilderBase {
+protected:
+  ConstantInitBuilderTemplateBase(CodeGenModule &CGM)
+    : ConstantInitBuilderBase(CGM) {}
+
+public:
+  using InitBuilder = typename Traits::InitBuilder;
+  using ArrayBuilder = typename Traits::ArrayBuilder;
+  using StructBuilder = typename Traits::StructBuilder;
+
+  ArrayBuilder beginArray(llvm::Type *eltTy = nullptr) {
+    return ArrayBuilder(static_cast<InitBuilder&>(*this), nullptr, eltTy);
+  }
+
+  StructBuilder beginStruct(llvm::StructType *structTy = nullptr) {
+    return StructBuilder(static_cast<InitBuilder&>(*this), nullptr, structTy);
+  }
+};
+
+class ConstantInitBuilder;
+class ConstantStructBuilder;
+class ConstantArrayBuilder;
+
+struct ConstantInitBuilderTraits {
+  using InitBuilder = ConstantInitBuilder;
+  using AggregateBuilderBase = ConstantAggregateBuilderBase;
+  using ArrayBuilder = ConstantArrayBuilder;
+  using StructBuilder = ConstantStructBuilder;
+};
+
+/// The standard implementation of ConstantInitBuilder used in Clang.
+class ConstantInitBuilder
+    : public ConstantInitBuilderTemplateBase<ConstantInitBuilderTraits> {
+public:
+  explicit ConstantInitBuilder(CodeGenModule &CGM) :
+    ConstantInitBuilderTemplateBase(CGM) {}
+};
+
+/// A helper class of ConstantInitBuilder, used for building constant
+/// array initializers.
+class ConstantArrayBuilder
+    : public ConstantArrayBuilderTemplateBase<ConstantInitBuilderTraits> {
+  template <class Traits>
+  friend class ConstantInitBuilderTemplateBase;
+
+  // The use of explicit qualification is a GCC workaround.
+  template <class Impl, class Traits>
+  friend class CodeGen::ConstantAggregateBuilderTemplateBase;
+
+  ConstantArrayBuilder(ConstantInitBuilder &builder,
+                       ConstantAggregateBuilderBase *parent,
+                       llvm::Type *eltTy)
+    : ConstantArrayBuilderTemplateBase(builder, parent, eltTy) {}
+};
+
+/// A helper class of ConstantInitBuilder, used for building constant
+/// struct initializers.
+class ConstantStructBuilder
+    : public ConstantStructBuilderTemplateBase<ConstantInitBuilderTraits> {
+  template <class Traits>
+  friend class ConstantInitBuilderTemplateBase;
+
+  // The use of explicit qualification is a GCC workaround.
+  template <class Impl, class Traits>
+  friend class CodeGen::ConstantAggregateBuilderTemplateBase;
+
+  ConstantStructBuilder(ConstantInitBuilder &builder,
+                        ConstantAggregateBuilderBase *parent,
+                        llvm::StructType *structTy)
+    : ConstantStructBuilderTemplateBase(builder, parent, structTy) {}
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+#endif
diff --git a/include/clang/CodeGen/ConstantInitFuture.h b/include/clang/CodeGen/ConstantInitFuture.h
new file mode 100644
index 0000000..ef1a5d2
--- /dev/null
+++ b/include/clang/CodeGen/ConstantInitFuture.h
@@ -0,0 +1,111 @@
+//===- ConstantInitFuture.h - "Future" constant initializers ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class defines the ConstantInitFuture class.  This is split out
+// from ConstantInitBuilder.h in order to allow APIs to work with it
+// without having to include that entire header.  This is particularly
+// important because it is often useful to be able to default-construct
+// a future in, say, a default argument.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
+#define LLVM_CLANG_CODEGEN_CONSTANTINITFUTURE_H
+
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/IR/Constant.h"
+
+// Forward-declare ConstantInitBuilderBase and give it a
+// PointerLikeTypeTraits specialization so that we can safely use it
+// in a PointerUnion below.
+namespace clang {
+namespace CodeGen {
+class ConstantInitBuilderBase;
+}
+}
+namespace llvm {
+template <>
+class PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitBuilderBase*> {
+public:
+  using T = ::clang::CodeGen::ConstantInitBuilderBase*;
+
+  static inline void *getAsVoidPointer(T p) { return p; }
+  static inline T getFromVoidPointer(void *p) {return static_cast<T>(p);}
+  enum { NumLowBitsAvailable = 2 };
+};
+}
+
+namespace clang {
+namespace CodeGen {
+
+/// A "future" for a completed constant initializer, which can be passed
+/// around independently of any sub-builders (but not the original parent).
+class ConstantInitFuture {
+  using PairTy = llvm::PointerUnion<ConstantInitBuilderBase*, llvm::Constant*>;
+
+  PairTy Data;
+
+  friend class ConstantInitBuilderBase;
+  explicit ConstantInitFuture(ConstantInitBuilderBase *builder);
+
+public:
+  ConstantInitFuture() {}
+
+  /// A future can be explicitly created from a fixed initializer.
+  explicit ConstantInitFuture(llvm::Constant *initializer) : Data(initializer) {
+    assert(initializer && "creating null future");
+  }
+
+  /// Is this future non-null?
+  explicit operator bool() const { return bool(Data); }
+
+  /// Return the type of the initializer.
+  llvm::Type *getType() const;
+
+  /// Abandon this initializer.
+  void abandon();
+
+  /// Install the initializer into a global variable.  This cannot
+  /// be called multiple times.
+  void installInGlobal(llvm::GlobalVariable *global);
+
+  void *getOpaqueValue() const { return Data.getOpaqueValue(); }
+  static ConstantInitFuture getFromOpaqueValue(void *value) {
+    ConstantInitFuture result;
+    result.Data = PairTy::getFromOpaqueValue(value);
+    return result;
+  }
+  enum {
+    NumLowBitsAvailable =
+      llvm::PointerLikeTypeTraits<PairTy>::NumLowBitsAvailable
+  };
+};
+
+}  // end namespace CodeGen
+}  // end namespace clang
+
+namespace llvm {
+
+template <>
+class PointerLikeTypeTraits< ::clang::CodeGen::ConstantInitFuture> {
+public:
+  using T = ::clang::CodeGen::ConstantInitFuture;
+
+  static inline void *getAsVoidPointer(T future) {
+    return future.getOpaqueValue();
+  }
+  static inline T getFromVoidPointer(void *p) {
+    return T::getFromOpaqueValue(p);
+  }
+  enum { NumLowBitsAvailable = T::NumLowBitsAvailable };
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index 55f0ca9..6971b4e 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -38,6 +38,9 @@
 /* Define if we have libxml2 */
 #cmakedefine CLANG_HAVE_LIBXML ${CLANG_HAVE_LIBXML}
 
+/* Define if we have z3 and want to build it */
+#cmakedefine CLANG_ANALYZER_WITH_Z3 ${CLANG_ANALYZER_WITH_Z3}
+
 /* Define if we have sys/resource.h (rlimits) */
 #cmakedefine CLANG_HAVE_RLIMITS ${CLANG_HAVE_RLIMITS}
 
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index ab296eb..8853a65 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -432,6 +432,8 @@
 def fmodule_format_EQ : Joined<["-"], "fmodule-format=">,
   HelpText<"Select the container format for clang modules and PCH. "
            "Supported options are 'raw' and 'obj'.">;
+def fmodules_hash_error_diagnostics : Flag<["-"], "fmodules-hash-error-diagnostics">,
+  HelpText<"Use a separate module cache for modules compiled with conflicting -Werror options">;
 def ftest_module_file_extension_EQ :
   Joined<["-"], "ftest-module-file-extension=">,
   HelpText<"introduce a module file extension for testing purposes. "
@@ -579,6 +581,8 @@
   HelpText<"File is for a position independent executable">;
 def fno_validate_pch : Flag<["-"], "fno-validate-pch">,
   HelpText<"Disable validation of precompiled headers">;
+def fallow_pch_with_errors : Flag<["-"], "fallow-pch-with-compiler-errors">,
+  HelpText<"Accept a PCH file that was created with compiler errors">;
 def dump_deserialized_pch_decls : Flag<["-"], "dump-deserialized-decls">,
   HelpText<"Dump declarations that are deserialized from PCH, for testing">;
 def error_on_deserialized_pch_decl : Separate<["-"], "error-on-deserialized-decl">,
@@ -658,6 +662,8 @@
   HelpText<"Disable standard system #include directories">;
 def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">,
   HelpText<"Disable the module hash">;
+def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">,
+  HelpText<"Enable hashing the content of a module file">;
 def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">,
   HelpText<"Add directory to the C SYSTEM include search path">;
 def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
diff --git a/include/clang/Driver/Driver.h b/include/clang/Driver/Driver.h
index 0ce461c..3791476 100644
--- a/include/clang/Driver/Driver.h
+++ b/include/clang/Driver/Driver.h
@@ -215,6 +215,11 @@
   /// Use lazy precompiled headers for PCH support.
   unsigned CCCUsePCH : 1;
 
+  /// Force clang to emit reproducer for driver invocation. This is enabled
+  /// indirectly by setting FORCE_CLANG_DIAGNOSTICS_CRASH environment variable
+  /// or when using the -gen-reproducer driver flag.
+  unsigned GenReproducer : 1;
+
 private:
   /// Certain options suppress the 'no input files' warning.
   unsigned SuppressMissingInputWarning : 1;
@@ -304,13 +309,8 @@
   bool isSaveTempsObj() const { return SaveTemps == SaveTempsObj; }
 
   bool embedBitcodeEnabled() const { return BitcodeEmbed != EmbedNone; }
-  bool embedBitcodeInObject() const {
-    // LTO has no object file output so ignore embed bitcode option in LTO.
-    return (BitcodeEmbed == EmbedBitcode) && !isUsingLTO();
-  }
-  bool embedBitcodeMarkerOnly() const {
-    return (BitcodeEmbed == EmbedMarker) && !isUsingLTO();
-  }
+  bool embedBitcodeInObject() const { return (BitcodeEmbed == EmbedBitcode); }
+  bool embedBitcodeMarkerOnly() const { return (BitcodeEmbed == EmbedMarker); }
 
   /// Compute the desired OpenMP runtime from the flags provided.
   OpenMPRuntimeKind getOpenMPRuntime(const llvm::opt::ArgList &Args) const;
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 6be159f..bbf9091 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -184,6 +184,8 @@
 def arcmt_migrate_emit_arc_errors : Flag<["-"], "arcmt-migrate-emit-errors">,
   HelpText<"Emit ARC errors even if the migrator can fix them">,
   Flags<[CC1Option]>;
+def gen_reproducer: Flag<["-"], "gen-reproducer">, InternalDebugOpt,
+  HelpText<"Auto-generates preprocessed source files and a reproduction script">;
 
 def _migrate : Flag<["--"], "migrate">, Flags<[DriverOption]>,
   HelpText<"Run the migrator">;
@@ -556,6 +558,21 @@
 def fno_profile_use : Flag<["-"], "fno-profile-use">,
     Alias<fno_profile_instr_use>;
 
+def fapinotes : Flag<["-"], "fapinotes">, Group<f_clang_Group>,
+  Flags<[CC1Option]>, HelpText<"Enable external API notes support">;
+def fapinotes_modules : Flag<["-"], "fapinotes-modules">, Group<f_clang_Group>,
+  Flags<[CC1Option]>, HelpText<"Enable module-based external API notes support">;
+def fno_apinotes : Flag<["-"], "fno-apinotes">, Group<f_clang_Group>,
+  Flags<[CC1Option]>, HelpText<"Disable external API notes support">;
+def fno_apinotes_modules : Flag<["-"], "fno-apinotes-modules">, Group<f_clang_Group>,
+  Flags<[CC1Option]>, HelpText<"Disable module-based external API notes support">;
+def fapinotes_cache_path : Joined<["-"], "fapinotes-cache-path=">,
+  Group<i_Group>, Flags<[DriverOption, CC1Option]>, MetaVarName<"<directory>">,
+  HelpText<"Specify the API notes cache path">;
+def fapinotes_swift_version : Joined<["-"], "fapinotes-swift-version=">,
+  Group<f_clang_Group>, Flags<[CC1Option]>, MetaVarName<"<version>">,
+  HelpText<"Specify the Swift version to use when filtering API notes">;
+
 def fblocks : Flag<["-"], "fblocks">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable the 'blocks' language feature">;
 def fbootclasspath_EQ : Joined<["-"], "fbootclasspath=">, Group<f_Group>;
@@ -585,7 +602,8 @@
 def fconstexpr_steps_EQ : Joined<["-"], "fconstexpr-steps=">, Group<f_Group>;
 def fconstexpr_backtrace_limit_EQ : Joined<["-"], "fconstexpr-backtrace-limit=">,
                                     Group<f_Group>;
-def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>;
+def fno_crash_diagnostics : Flag<["-"], "fno-crash-diagnostics">, Group<f_clang_Group>, Flags<[NoArgumentUnused]>,
+  HelpText<"Disable auto-generation of preprocessed source files and a script for reproduction during a clang crash">;
 def fcreate_profile : Flag<["-"], "fcreate-profile">, Group<f_Group>;
 def fcxx_exceptions: Flag<["-"], "fcxx-exceptions">, Group<f_Group>,
   HelpText<"Enable C++ exceptions">, Flags<[CC1Option]>;
@@ -1340,6 +1358,12 @@
 def fno_strict_return : Flag<["-"], "fno-strict-return">, Group<f_Group>,
   Flags<[CC1Option]>;
 
+def fallow_editor_placeholders : Flag<["-"], "fallow-editor-placeholders">,
+  Group<f_Group>, Flags<[CC1Option]>,
+  HelpText<"Treat editor placeholders as valid source code">;
+def fno_allow_editor_placeholders : Flag<["-"],
+  "fno-allow-editor-placeholders">, Group<f_Group>;
+
 def fdebug_types_section: Flag <["-"], "fdebug-types-section">, Group<f_Group>,
   Flags<[CC1Option]>, HelpText<"Place debug types in their own section (ELF Only)">;
 def fno_debug_types_section: Flag<["-"], "fno-debug-types-section">, Group<f_Group>,
@@ -1407,10 +1431,17 @@
   HelpText<"Display available options">;
 def index_header_map : Flag<["-"], "index-header-map">, Flags<[CC1Option]>,
   HelpText<"Make the next included directory (-I or -F) an indexer header map">;
+def iapinotes_modules : JoinedOrSeparate<["-"], "iapinotes-modules">, Group<clang_i_Group>, Flags<[CC1Option]>,
+  HelpText<"Add directory to the API notes search path referenced by module name">, MetaVarName<"<directory>">;
 def idirafter : JoinedOrSeparate<["-"], "idirafter">, Group<clang_i_Group>, Flags<[CC1Option]>,
   HelpText<"Add directory to AFTER include search path">;
 def iframework : JoinedOrSeparate<["-"], "iframework">, Group<clang_i_Group>, Flags<[CC1Option]>,
   HelpText<"Add directory to SYSTEM framework search path">;
+def iframeworkwithsysroot : JoinedOrSeparate<["-"], "iframeworkwithsysroot">,
+  Group<clang_i_Group>,
+  HelpText<"Add directory to SYSTEM framework search path, "
+           "absolute paths are relative to -isysroot">,
+  MetaVarName<"<directory>">, Flags<[CC1Option]>;
 def imacros : JoinedOrSeparate<["-", "--"], "imacros">, Group<clang_i_Group>, Flags<[CC1Option]>,
   HelpText<"Include macros from file before parsing">, MetaVarName<"<file>">;
 def image__base : Separate<["-"], "image_base">;
@@ -1484,11 +1515,11 @@
 def mno_pure_code : Flag<["-"], "mno-pure-code">, Alias<mno_execute_only>;
 def mtvos_version_min_EQ : Joined<["-"], "mtvos-version-min=">, Group<m_Group>;
 def mappletvos_version_min_EQ : Joined<["-"], "mappletvos-version-min=">, Alias<mtvos_version_min_EQ>;
-def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">, Alias<mtvos_version_min_EQ>;
-def mappletvsimulator_version_min_EQ : Joined<["-"], "mappletvsimulator-version-min=">, Alias<mtvos_version_min_EQ>;
+def mtvos_simulator_version_min_EQ : Joined<["-"], "mtvos-simulator-version-min=">;
+def mappletvsimulator_version_min_EQ : Joined<["-"], "mappletvsimulator-version-min=">, Alias<mtvos_simulator_version_min_EQ>;
 def mwatchos_version_min_EQ : Joined<["-"], "mwatchos-version-min=">, Group<m_Group>;
-def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-version-min=">, Alias<mwatchos_version_min_EQ>;
-def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias<mwatchos_version_min_EQ>;
+def mwatchos_simulator_version_min_EQ : Joined<["-"], "mwatchos-simulator-version-min=">;
+def mwatchsimulator_version_min_EQ : Joined<["-"], "mwatchsimulator-version-min=">, Alias<mwatchos_simulator_version_min_EQ>;
 def march_EQ : Joined<["-"], "march=">, Group<m_Group>;
 def masm_EQ : Joined<["-"], "masm=">, Group<m_Group>, Flags<[DriverOption]>;
 def mcmodel_EQ : Joined<["-"], "mcmodel=">, Group<m_Group>;
@@ -1517,8 +1548,8 @@
 def miphoneos_version_min_EQ : Joined<["-"], "miphoneos-version-min=">, Group<m_Group>;
 def mios_version_min_EQ : Joined<["-"], "mios-version-min=">,
   Alias<miphoneos_version_min_EQ>, HelpText<"Set iOS deployment target">;
-def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">, Alias<miphoneos_version_min_EQ>;
-def miphonesimulator_version_min_EQ : Joined<["-"], "miphonesimulator-version-min=">, Alias<miphoneos_version_min_EQ>;
+def mios_simulator_version_min_EQ : Joined<["-"], "mios-simulator-version-min=">;
+def miphonesimulator_version_min_EQ : Joined<["-"], "miphonesimulator-version-min=">, Alias<mios_simulator_version_min_EQ>;
 def mkernel : Flag<["-"], "mkernel">, Group<m_Group>;
 def mlinker_version_EQ : Joined<["-"], "mlinker-version=">,
   Flags<[DriverOption]>;
@@ -1526,6 +1557,8 @@
   HelpText<"Additional arguments to forward to LLVM's option processing">;
 def mmacosx_version_min_EQ : Joined<["-"], "mmacosx-version-min=">,
   Group<m_Group>, HelpText<"Set Mac OS X deployment target">;
+def mmacos_version_min_EQ : Joined<["-"], "mmacos-version-min=">,
+  Group<m_Group>, Alias<mmacosx_version_min_EQ>;
 def mms_bitfields : Flag<["-"], "mms-bitfields">, Group<m_Group>, Flags<[CC1Option]>,
   HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard">;
 def mno_ms_bitfields : Flag<["-"], "mno-ms-bitfields">, Group<m_Group>,
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index 6206680..2df8077 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -34,7 +34,7 @@
   bool CfiCrossDso = false;
   int AsanFieldPadding = 0;
   bool AsanSharedRuntime = false;
-  bool AsanUseAfterScope = false;
+  bool AsanUseAfterScope = true;
   bool LinkCXXRuntimes = false;
   bool NeedPIE = false;
   bool Stats = false;
diff --git a/include/clang/Edit/EditedSource.h b/include/clang/Edit/EditedSource.h
index b6ec8b8..b082e4e 100644
--- a/include/clang/Edit/EditedSource.h
+++ b/include/clang/Edit/EditedSource.h
@@ -65,7 +65,7 @@
 
   bool commit(const Commit &commit);
   
-  void applyRewrites(EditsReceiver &receiver);
+  void applyRewrites(EditsReceiver &receiver, bool adjustRemovals = true);
   void clearRewrites();
 
   StringRef copyString(StringRef str) { return str.copy(StrAlloc); }
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 3f9a76f..46469bd 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -465,8 +465,6 @@
     LK_Java,
     /// Should be used for JavaScript.
     LK_JavaScript,
-    /// Should be used for ObjC code.
-    LK_ObjC,
     /// Should be used for Protocol Buffers
     /// (https://developers.google.com/protocol-buffers/).
     LK_Proto,
@@ -855,16 +853,13 @@
 /// == "file".
 /// \param[in] FallbackStyle The name of a predefined style used to fallback to
 /// in case the style can't be determined from \p StyleName.
-/// \param[in] Code The actual code to be formatted. Used to determine the
-/// language if the filename isn't sufficient.
 /// \param[in] FS The underlying file system, in which the file resides. By
 /// default, the file system is the real file system.
 ///
 /// \returns FormatStyle as specified by ``StyleName``. If no style could be
 /// determined, the default is LLVM Style (see ``getLLVMStyle()``).
 FormatStyle getStyle(StringRef StyleName, StringRef FileName,
-                     StringRef FallbackStyle, StringRef Code = "",
-                     vfs::FileSystem *FS = nullptr);
+                     StringRef FallbackStyle, vfs::FileSystem *FS = nullptr);
 
 // \brief Returns a string representation of ``Language``.
 inline StringRef getLanguageName(FormatStyle::LanguageKind Language) {
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h
index b1cdb46..2a8df1b 100644
--- a/include/clang/Frontend/ASTUnit.h
+++ b/include/clang/Frontend/ASTUnit.h
@@ -51,6 +51,7 @@
 class FileEntry;
 class FileManager;
 class HeaderSearch;
+class MemoryBufferCache;
 class Preprocessor;
 class PCHContainerOperations;
 class PCHContainerReader;
@@ -84,6 +85,7 @@
   IntrusiveRefCntPtr<DiagnosticsEngine>   Diagnostics;
   IntrusiveRefCntPtr<FileManager>         FileMgr;
   IntrusiveRefCntPtr<SourceManager>       SourceMgr;
+  IntrusiveRefCntPtr<MemoryBufferCache>   PCMCache;
   std::unique_ptr<HeaderSearch>           HeaderInfo;
   IntrusiveRefCntPtr<TargetInfo>          Target;
   std::shared_ptr<Preprocessor>           PP;
@@ -519,6 +521,8 @@
 
   const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
 
+  IntrusiveRefCntPtr<ASTReader> getASTReader() const;
+
   StringRef getOriginalSourceFileName() {
     return OriginalSourceFile;
   }
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 964a6cc..4863f1c 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -65,8 +65,6 @@
 CODEGENOPT(EmitGcovNotes     , 1, 0) ///< Emit coverage "notes" files, aka GCNO.
 CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata.
 CODEGENOPT(EmulatedTLS       , 1, 0) ///< Set when -femulated-tls is enabled.
-/// \brief FP_CONTRACT mode (on/off/fast).
-ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On)
 /// \brief Embed Bitcode mode (off/all/bitcode/marker).
 ENUM_CODEGENOPT(EmbedBitcode, EmbedBitcodeKind, 2, Embed_Off)
 CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 52bd1c5..47f7147 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -69,12 +69,6 @@
     LocalExecTLSModel
   };
 
-  enum FPContractModeKind {
-    FPC_Off,        // Form fused FP ops only where result will not be affected.
-    FPC_On,         // Form fused FP ops according to FP_CONTRACT rules.
-    FPC_Fast        // Aggressively fuse FP ops (E.g. FMA).
-  };
-
   enum StructReturnConventionKind {
     SRCK_Default,  // No special option was passed.
     SRCK_OnStack,  // Small structs on the stack (-fpcc-struct-return).
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 3ebbc61..2a5ea8f 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -44,6 +44,7 @@
 class FileEntry;
 class FileManager;
 class FrontendAction;
+class MemoryBufferCache;
 class Module;
 class Preprocessor;
 class Sema;
@@ -90,6 +91,9 @@
   /// The source manager.
   IntrusiveRefCntPtr<SourceManager> SourceMgr;
 
+  /// The cache of PCM files.
+  IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
+
   /// The preprocessor.
   std::shared_ptr<Preprocessor> PP;
 
@@ -142,13 +146,13 @@
 
   /// \brief Whether we should (re)build the global module index once we
   /// have finished with this translation unit.
-  bool BuildGlobalModuleIndex;
+  bool BuildGlobalModuleIndex = false;
 
   /// \brief We have a full global module index, with all modules.
-  bool HaveFullGlobalModuleIndex;
+  bool HaveFullGlobalModuleIndex = false;
 
   /// \brief One or more modules failed to build.
-  bool ModuleBuildFailed;
+  bool ModuleBuildFailed = false;
 
   /// \brief Holds information about the output file.
   ///
@@ -178,7 +182,7 @@
   explicit CompilerInstance(
       std::shared_ptr<PCHContainerOperations> PCHContainerOps =
           std::make_shared<PCHContainerOperations>(),
-      bool BuildingModule = false);
+      MemoryBufferCache *SharedPCMCache = nullptr);
   ~CompilerInstance() override;
 
   /// @name High-Level Operations
@@ -292,6 +296,13 @@
     return Invocation->getHeaderSearchOptsPtr();
   }
 
+  APINotesOptions &getAPINotesOpts() {
+    return Invocation->getAPINotesOpts();
+  }
+  const APINotesOptions &getAPINotesOpts() const {
+    return Invocation->getAPINotesOpts();
+  }
+
   LangOptions &getLangOpts() {
     return *Invocation->getLangOpts();
   }
@@ -658,6 +669,8 @@
       bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
       const PCHContainerReader &PCHContainerRdr,
       ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
+      DependencyFileGenerator *DependencyFile,
+      ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
       void *DeserializationListener, bool OwnDeserializationListener,
       bool Preamble, bool UseGlobalModuleIndex);
 
@@ -783,6 +796,8 @@
   }
 
   void setExternalSemaSource(IntrusiveRefCntPtr<ExternalSemaSource> ESS);
+
+  MemoryBufferCache &getPCMCache() const { return *PCMCache; }
 };
 
 } // end namespace clang
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index cef7f73..872cdc2 100644
--- a/include/clang/Frontend/CompilerInvocation.h
+++ b/include/clang/Frontend/CompilerInvocation.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
 #define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_
 
+#include "clang/APINotes/APINotesOptions.h"
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileSystemOptions.h"
 #include "clang/Basic/LangOptions.h"
@@ -113,6 +114,9 @@
 
   MigratorOptions MigratorOpts;
   
+  /// Options controlling API notes.
+  APINotesOptions APINotesOpts;
+
   /// Options controlling IRgen and the backend.
   CodeGenOptions CodeGenOpts;
 
@@ -170,7 +174,7 @@
   
   /// \brief Retrieve a module hash string that is suitable for uniquely 
   /// identifying the conditions under which the module was built.
-  std::string getModuleHash() const;
+  std::string getModuleHash(DiagnosticsEngine &Diags) const;
   
   /// @}
   /// @name Option Subgroups
@@ -184,6 +188,11 @@
   const MigratorOptions &getMigratorOpts() const {
     return MigratorOpts;
   }
+
+  APINotesOptions &getAPINotesOpts() { return APINotesOpts; }
+  const APINotesOptions &getAPINotesOpts() const {
+    return APINotesOpts;
+  }
   
   CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; }
   const CodeGenOptions &getCodeGenOpts() const {
diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h
index 20fddc4..778b40b 100644
--- a/include/clang/Frontend/FrontendActions.h
+++ b/include/clang/Frontend/FrontendActions.h
@@ -80,6 +80,8 @@
 
   bool hasASTFileSupport() const override { return false; }
 
+  bool shouldEraseOutputFiles() override;
+
 public:
   /// \brief Compute the AST consumer arguments that will be used to
   /// create the PCHGenerator instance returned by CreateASTConsumer.
diff --git a/include/clang/Frontend/PCHContainerOperations.h b/include/clang/Frontend/PCHContainerOperations.h
index d323fb3..f9a7350 100644
--- a/include/clang/Frontend/PCHContainerOperations.h
+++ b/include/clang/Frontend/PCHContainerOperations.h
@@ -10,6 +10,7 @@
 #ifndef LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
 #define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
 
+#include "clang/Basic/Module.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -29,7 +30,7 @@
 class CompilerInstance;
 
 struct PCHBuffer {
-  uint64_t Signature;
+  ASTFileSignature Signature;
   llvm::SmallVector<char, 0> Data;
   bool IsComplete;
 };
diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h
index d19e5eb..6989aa3 100644
--- a/include/clang/Index/IndexSymbol.h
+++ b/include/clang/Index/IndexSymbol.h
@@ -51,12 +51,16 @@
   Constructor,
   Destructor,
   ConversionFunction,
+
+  Parameter,
+  CommentTag,
 };
 
 enum class SymbolLanguage {
   C,
   ObjC,
   CXX,
+  Swift,
 };
 
 /// Language specific sub-kinds.
@@ -66,6 +70,26 @@
   CXXMoveConstructor,
   AccessorGetter,
   AccessorSetter,
+
+  // Swift sub-kinds
+
+  SwiftAccessorWillSet,
+  SwiftAccessorDidSet,
+  SwiftAccessorAddressor,
+  SwiftAccessorMutableAddressor,
+
+  SwiftExtensionOfStruct,
+  SwiftExtensionOfClass,
+  SwiftExtensionOfEnum,
+  SwiftExtensionOfProtocol,
+
+  SwiftPrefixOperator,
+  SwiftPostfixOperator,
+  SwiftInfixOperator,
+
+  SwiftSubscript,
+  SwiftAssociatedType,
+  SwiftGenericTypeParam,
 };
 
 /// Set of properties that provide additional info about a symbol.
@@ -77,8 +101,9 @@
   IBAnnotated                   = 1 << 4,
   IBOutletCollection            = 1 << 5,
   GKInspectable                 = 1 << 6,
+  Local                         = 1 << 7,
 };
-static const unsigned SymbolPropertyBitNum = 7;
+static const unsigned SymbolPropertyBitNum = 8;
 typedef unsigned SymbolPropertySet;
 
 /// Set of roles that are attributed to symbol occurrences.
@@ -103,8 +128,9 @@
   RelationAccessorOf  = 1 << 15,
   RelationContainedBy = 1 << 16,
   RelationIBTypeOf    = 1 << 17,
+  RelationSpecializationOf = 1 << 18,
 };
-static const unsigned SymbolRoleBitNum = 18;
+static const unsigned SymbolRoleBitNum = 19;
 typedef unsigned SymbolRoleSet;
 
 /// Represents a relation to another symbol for a symbol occurrence.
@@ -125,8 +151,12 @@
 
 SymbolInfo getSymbolInfo(const Decl *D);
 
+bool isFunctionLocalSymbol(const Decl *D);
+
 void applyForEachSymbolRole(SymbolRoleSet Roles,
                             llvm::function_ref<void(SymbolRole)> Fn);
+bool applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
+                            llvm::function_ref<bool(SymbolRole)> Fn);
 void printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS);
 
 /// \returns true if no name was printed, false otherwise.
diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h
index e2e63dc..8eed33c 100644
--- a/include/clang/Index/IndexingAction.h
+++ b/include/clang/Index/IndexingAction.h
@@ -14,9 +14,14 @@
 #include <memory>
 
 namespace clang {
+  class ASTReader;
   class ASTUnit;
   class FrontendAction;
 
+namespace serialization {
+  class ModuleFile;
+}
+
 namespace index {
   class IndexDataConsumer;
 
@@ -42,6 +47,11 @@
                   std::shared_ptr<IndexDataConsumer> DataConsumer,
                   IndexingOptions Opts);
 
+void indexModuleFile(serialization::ModuleFile &Mod,
+                     ASTReader &Reader,
+                     std::shared_ptr<IndexDataConsumer> DataConsumer,
+                     IndexingOptions Opts);
+
 } // namespace index
 } // namespace clang
 
diff --git a/include/clang/Index/USRGeneration.h b/include/clang/Index/USRGeneration.h
index be89068..8c661bd 100644
--- a/include/clang/Index/USRGeneration.h
+++ b/include/clang/Index/USRGeneration.h
@@ -16,6 +16,7 @@
 namespace clang {
 class Decl;
 class MacroDefinitionRecord;
+class SourceLocation;
 class SourceManager;
 
 namespace index {
@@ -29,10 +30,14 @@
 bool generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf);
 
 /// \brief Generate a USR fragment for an Objective-C class.
-void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS);
+void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
+                             StringRef ExtSymbolDefinedIn = "",
+                             StringRef CategoryContextExtSymbolDefinedIn = "");
 
 /// \brief Generate a USR fragment for an Objective-C class category.
-void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS);
+void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS,
+                                StringRef ClsExtSymbolDefinedIn = "",
+                                StringRef CatExtSymbolDefinedIn = "");
 
 /// \brief Generate a USR fragment for an Objective-C instance variable.  The
 /// complete USR can be created by concatenating the USR for the
@@ -47,13 +52,23 @@
 void generateUSRForObjCProperty(StringRef Prop, bool isClassProp, raw_ostream &OS);
 
 /// \brief Generate a USR fragment for an Objective-C protocol.
-void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS);
+void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
+                                StringRef ExtSymbolDefinedIn = "");
+
+/// Generate USR fragment for a global (non-nested) enum.
+void generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
+                              StringRef ExtSymbolDefinedIn = "");
+
+/// Generate a USR fragment for an enum constant.
+void generateUSRForEnumConstant(StringRef EnumConstantName, raw_ostream &OS);
 
 /// \brief Generate a USR for a macro, including the USR prefix.
 ///
 /// \returns true on error, false on success.
 bool generateUSRForMacro(const MacroDefinitionRecord *MD,
                          const SourceManager &SM, SmallVectorImpl<char> &Buf);
+bool generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
+                         const SourceManager &SM, SmallVectorImpl<char> &Buf);
 
 } // namespace index
 } // namespace clang
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 51983b9..165c6fc 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -375,13 +375,16 @@
   /// \param SuggestedModule If non-null, and the file found is semantically
   /// part of a known module, this will be set to the module that should
   /// be imported instead of preprocessing/parsing the file found.
+  ///
+  /// \param IsMapped If non-null, and the search involved header maps, set to
+  /// true.
   const FileEntry *LookupFile(
       StringRef Filename, SourceLocation IncludeLoc, bool isAngled,
       const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir,
       ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
       SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
       Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
-      bool SkipCache = false, bool BuildSystemModule = false);
+      bool *IsMapped, bool SkipCache = false, bool BuildSystemModule = false);
 
   /// \brief Look up a subframework for the specified \#include file.
   ///
@@ -406,8 +409,7 @@
   /// \return false if \#including the file will have no effect or true
   /// if we should include it.
   bool ShouldEnterIncludeFile(Preprocessor &PP, const FileEntry *File,
-                              bool isImport, bool ModulesEnabled,
-                              Module *CorrespondingModule);
+                              bool isImport, Module *CorrespondingModule);
 
   /// \brief Return whether the specified file is a normal header,
   /// a system header, or a C++ friendly system header.
diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h
index e999805..ca3a84e 100644
--- a/include/clang/Lex/HeaderSearchOptions.h
+++ b/include/clang/Lex/HeaderSearchOptions.h
@@ -178,6 +178,8 @@
 
   unsigned ModulesValidateDiagnosticOptions : 1;
 
+  unsigned ModulesHashContent : 1;
+
   HeaderSearchOptions(StringRef _Sysroot = "/")
       : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(0),
         ImplicitModuleMaps(0), ModuleMapFileHomeIsCwd(0),
@@ -186,8 +188,8 @@
         UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
         UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
         ModulesValidateOncePerBuildSession(false),
-        ModulesValidateSystemHeaders(false),
-        UseDebugInfo(false), ModulesValidateDiagnosticOptions(true) {}
+        ModulesValidateSystemHeaders(false), UseDebugInfo(false),
+        ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {}
 
   /// AddPath - Add the \p Path path to the specified \p Group list.
   void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 830c25a..02b3855 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -133,15 +133,17 @@
   /// from.  Currently this is only used by _Pragma handling.
   SourceLocation getFileLoc() const { return FileLoc; }
 
-private:
   /// Lex - Return the next token in the file.  If this is the end of file, it
   /// return the tok::eof token.  This implicitly involves the preprocessor.
   bool Lex(Token &Result);
 
-public:
   /// isPragmaLexer - Returns true if this Lexer is being used to lex a pragma.
   bool isPragmaLexer() const { return Is_PragmaLexer; }
 
+  /// Note that this Lexer is being used to lex a pragma, or something like it
+  /// that has simple end-of-file behavior.
+  void setIsPragmaLexer(bool value) { Is_PragmaLexer = value; }
+
 private:
   /// IndirectLex - An indirect call to 'Lex' that can be invoked via
   ///  the PreprocessorLexer interface.
@@ -478,6 +480,11 @@
     return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
   }
 
+  /// Returns the leading whitespace for line that corresponds to the given
+  /// location \p Loc.
+  static StringRef getIndentationForLine(SourceLocation Loc,
+                                         const SourceManager &SM);
+
   //===--------------------------------------------------------------------===//
   // Internal implementation interfaces.
 private:
@@ -638,6 +645,8 @@
   bool IsStartOfConflictMarker(const char *CurPtr);
   bool HandleEndOfConflictMarker(const char *CurPtr);
 
+  bool lexEditorPlaceholder(Token &Result, const char *CurPtr);
+
   bool isCodeCompletionPoint(const char *CurPtr) const;
   void cutOffLexing() { BufferPtr = BufferEnd; }
 
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 4613672..e5400c6 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -92,7 +92,7 @@
   // named LangOpts::CurrentModule, if we've loaded it).
   Module *SourceModule;
 
-  /// \brief The top-level modules that are known.
+  /// \brief The unshadowed top-level modules that are known.
   llvm::StringMap<Module *> Modules;
 
   /// \brief The number of modules we have created in total.
@@ -174,6 +174,15 @@
   /// header.
   llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs;
 
+  /// \brief A generation counter that is used to test whether modules of the
+  /// same name may shadow or are illegal redefintions.
+  ///
+  /// Modules from earlier scopes may shadow modules from later ones.
+  /// Modules from the same scope may not have the same name.
+  unsigned CurrentModuleScopeID = 0;
+
+  llvm::DenseMap<Module *, unsigned> ModuleScopeIDs;
+
   /// \brief The set of attributes that can be attached to a module.
   struct Attributes {
     Attributes()
@@ -188,6 +197,9 @@
     /// \brief Whether this is an exhaustive set of configuration macros.
     unsigned IsExhaustive : 1;
 
+    /// \brief Whether this is a module who has its swift_names inferred.
+    unsigned IsSwiftInferImportAsMember : 1;
+
     /// \brief Whether files in this module can only include non-modular headers
     /// and headers from used modules.
     unsigned NoUndeclaredIncludes : 1;
@@ -316,14 +328,6 @@
     BuiltinIncludeDir = Dir;
   }
 
-  /// \brief Get the directory that contains Clang-supplied include files.
-  const DirectoryEntry *getBuiltinDir() const {
-    return BuiltinIncludeDir;
-  }
-
-  /// \brief Is this a compiler builtin header?
-  static bool isBuiltinHeader(StringRef FileName);
-
   /// \brief Add a module map callback.
   void addModuleMapCallbacks(std::unique_ptr<ModuleMapCallbacks> Callback) {
     Callbacks.push_back(std::move(Callback));
@@ -440,6 +444,24 @@
   Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir,
                                bool IsSystem, Module *Parent);
 
+  /// \brief Create a new top-level module that is shadowed by
+  /// \p ShadowingModule.
+  Module *createShadowedModule(StringRef Name, bool IsFramework,
+                               Module *ShadowingModule);
+
+  /// \brief Creates a new declaration scope for module names, allowing
+  /// previously defined modules to shadow definitions from the new scope.
+  ///
+  /// \note Module names from earlier scopes will shadow names from the new
+  /// scope, which is the opposite of how shadowing works for variables.
+  void finishModuleDeclarationScope() { CurrentModuleScopeID += 1; }
+
+  bool mayShadowNewModule(Module *ExistingModule) {
+    assert(!ExistingModule->Parent && "expected top-level module");
+    assert(ModuleScopeIDs.count(ExistingModule) && "unknown module");
+    return ModuleScopeIDs[ExistingModule] < CurrentModuleScopeID;
+  }
+
   /// \brief Retrieve the module map file containing the definition of the given
   /// module.
   ///
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 7ce1aad..67b947b 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -47,6 +47,7 @@
 class FileManager;
 class FileEntry;
 class HeaderSearch;
+class MemoryBufferCache;
 class PragmaNamespace;
 class PragmaHandler;
 class CommentHandler;
@@ -102,6 +103,7 @@
   const TargetInfo  *AuxTarget;
   FileManager       &FileMgr;
   SourceManager     &SourceMgr;
+  MemoryBufferCache &PCMCache;
   std::unique_ptr<ScratchBuffer> ScratchBuf;
   HeaderSearch      &HeaderInfo;
   ModuleLoader      &TheModuleLoader;
@@ -652,6 +654,7 @@
 public:
   Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
                DiagnosticsEngine &diags, LangOptions &opts, SourceManager &SM,
+               MemoryBufferCache &PCMCache,
                HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
                IdentifierInfoLookup *IILookup = nullptr,
                bool OwnsHeaderSearch = false,
@@ -691,6 +694,7 @@
   const TargetInfo *getAuxTargetInfo() const { return AuxTarget; }
   FileManager &getFileManager() const { return FileMgr; }
   SourceManager &getSourceManager() const { return SourceMgr; }
+  MemoryBufferCache &getPCMCache() const { return PCMCache; }
   HeaderSearch &getHeaderSearchInfo() const { return HeaderInfo; }
 
   IdentifierTable &getIdentifierTable() { return Identifiers; }
@@ -1077,6 +1081,24 @@
   /// \brief Disable the last EnableBacktrackAtThisPos call.
   void CommitBacktrackedTokens();
 
+  struct CachedTokensRange {
+    CachedTokensTy::size_type Begin, End;
+  };
+
+private:
+  /// \brief A range of cached tokens that should be erased after lexing
+  /// when backtracking requires the erasure of such cached tokens.
+  Optional<CachedTokensRange> CachedTokenRangeToErase;
+
+public:
+  /// \brief Returns the range of cached tokens that were lexed since
+  /// EnableBacktrackAtThisPos() was previously called.
+  CachedTokensRange LastCachedTokenRange();
+
+  /// \brief Erase the range of cached tokens that were lexed since
+  /// EnableBacktrackAtThisPos() was previously called.
+  void EraseCachedTokens(CachedTokensRange TokenRange);
+
   /// \brief Make Preprocessor re-lex the tokens that were lexed since
   /// EnableBacktrackAtThisPos() was previously called.
   void Backtrack();
@@ -1580,6 +1602,7 @@
                  *Ident_AbnormalTermination;
 
   const char *getCurLexerEndPos();
+  void diagnoseMissingHeaderInUmbrellaDir(const Module &Mod);
 
 public:
   void PoisonSEHIdentifiers(bool Poison = true); // Borland
@@ -1664,7 +1687,7 @@
                               SmallVectorImpl<char> *SearchPath,
                               SmallVectorImpl<char> *RelativePath,
                               ModuleMap::KnownHeader *SuggestedModule,
-                              bool SkipCache = false);
+                              bool *IsMapped, bool SkipCache = false);
 
   /// \brief Get the DirectoryLookup structure used to find the current
   /// FileEntry, if CurLexer is non-null and if applicable. 
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 4393e20..02a1fef 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -84,6 +84,7 @@
     StringifiedInMacro = 0x100, // This string or character literal is formed by
                                 // macro stringizing or charizing operator.
     CommaAfterElided = 0x200, // The comma following this token was elided (MS).
+    IsEditorPlaceholder = 0x400, // This identifier is a placeholder.
   };
 
   tok::TokenKind getKind() const { return Kind; }
@@ -298,6 +299,13 @@
 
   /// Returns true if the comma after this token was elided.
   bool commaAfterElided() const { return getFlag(CommaAfterElided); }
+
+  /// Returns true if this token is an editor placeholder.
+  ///
+  /// Editor placeholders are produced by the code-completion engine and are
+  /// represented as characters between '<#' and '#>' in the source code. The
+  /// lexer uses identifier tokens to represent placeholders.
+  bool isEditorPlaceholder() const { return getFlag(IsEditorPlaceholder); }
 };
 
 /// \brief Information about the conditional stack (\#if directives)
diff --git a/include/clang/Parse/CMakeLists.txt b/include/clang/Parse/CMakeLists.txt
index ec75f7b..2cc7e54 100644
--- a/include/clang/Parse/CMakeLists.txt
+++ b/include/clang/Parse/CMakeLists.txt
@@ -2,3 +2,9 @@
   -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
   SOURCE ../Basic/Attr.td
   TARGET ClangAttrParserStringSwitches)
+
+clang_tablegen(AttrSubMatchRulesParserStringSwitches.inc
+  -gen-clang-attr-subject-match-rules-parser-string-switches
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE ../Basic/Attr.td
+  TARGET ClangAttrSubMatchRulesParserStringSwitches)
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index fe15902..a221dba 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -142,6 +142,10 @@
   /// \brief Identifier for "replacement".
   IdentifierInfo *Ident_replacement;
 
+  /// Identifiers used by the 'external_source_symbol' attribute.
+  IdentifierInfo *Ident_language, *Ident_defined_in,
+      *Ident_generated_declaration;
+
   /// C++0x contextual keywords.
   mutable IdentifierInfo *Ident_final;
   mutable IdentifierInfo *Ident_GNU_final;
@@ -179,6 +183,8 @@
   std::unique_ptr<PragmaHandler> LoopHintHandler;
   std::unique_ptr<PragmaHandler> UnrollHintHandler;
   std::unique_ptr<PragmaHandler> NoUnrollHintHandler;
+  std::unique_ptr<PragmaHandler> FPHandler;
+  std::unique_ptr<PragmaHandler> AttributePragmaHandler;
 
   std::unique_ptr<CommentHandler> CommentSemaHandler;
 
@@ -545,6 +551,10 @@
   void HandlePragmaFPContract();
 
   /// \brief Handle the annotation token produced for
+  /// #pragma clang fp ...
+  void HandlePragmaFP();
+
+  /// \brief Handle the annotation token produced for
   /// #pragma OPENCL EXTENSION...
   void HandlePragmaOpenCLExtension();
 
@@ -556,6 +566,12 @@
   /// #pragma clang loop and #pragma unroll.
   bool HandlePragmaLoopHint(LoopHint &Hint);
 
+  bool ParsePragmaAttributeSubjectMatchRuleSet(
+      attr::ParsedSubjectMatchRuleSet &SubjectMatchRules,
+      SourceLocation &AnyLoc, SourceLocation &LastMatchRuleEndLoc);
+
+  void HandlePragmaAttribute();
+
   /// GetLookAheadToken - This peeks ahead N tokens and returns that token
   /// without consuming any tokens.  LookAhead(0) returns 'Tok', LookAhead(1)
   /// returns the token after Tok, etc.
@@ -791,6 +807,14 @@
   /// \brief Consume any extra semi-colons until the end of the line.
   void ConsumeExtraSemi(ExtraSemiKind Kind, unsigned TST = TST_unspecified);
 
+  /// Return false if the next token is an identifier. An 'expected identifier'
+  /// error is emitted otherwise.
+  ///
+  /// The parser tries to recover from the error by checking if the next token
+  /// is a C++ keyword when parsing Objective-C++. Return false if the recovery
+  /// was successful.
+  bool expectIdentifier();
+
 public:
   //===--------------------------------------------------------------------===//
   // Scope manipulation
@@ -2177,6 +2201,12 @@
                              Declarator *D);
   IdentifierLoc *ParseIdentifierLoc();
 
+  unsigned
+  ParseClangAttributeArgs(IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+                          ParsedAttributes &Attrs, SourceLocation *EndLoc,
+                          IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
+                          AttributeList::Syntax Syntax);
+
   void MaybeParseCXX11Attributes(Declarator &D) {
     if (getLangOpts().CPlusPlus11 && isCXX11AttributeSpecifier()) {
       ParsedAttributesWithRange attrs(AttrFactory);
@@ -2266,6 +2296,14 @@
   Optional<AvailabilitySpec> ParseAvailabilitySpec();
   ExprResult ParseAvailabilityCheckExpr(SourceLocation StartLoc);
 
+  void ParseExternalSourceSymbolAttribute(IdentifierInfo &ExternalSourceSymbol,
+                                          SourceLocation Loc,
+                                          ParsedAttributes &Attrs,
+                                          SourceLocation *EndLoc,
+                                          IdentifierInfo *ScopeName,
+                                          SourceLocation ScopeLoc,
+                                          AttributeList::Syntax Syntax);
+
   void ParseObjCBridgeRelatedAttribute(IdentifierInfo &ObjCBridgeRelated,
                                        SourceLocation ObjCBridgeRelatedLoc,
                                        ParsedAttributes &attrs,
@@ -2282,6 +2320,14 @@
                                         SourceLocation ScopeLoc,
                                         AttributeList::Syntax Syntax);
 
+  void ParseSwiftNewtypeAttribute(IdentifierInfo &SwiftNewtype,
+                                  SourceLocation SwiftNewtypeLoc,
+                                  ParsedAttributes &attrs,
+                                  SourceLocation *endLoc,
+                                  IdentifierInfo *ScopeName,
+                                  SourceLocation ScopeLoc,
+                                  AttributeList::Syntax Syntax);
+
   void ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
                                  SourceLocation AttrNameLoc,
                                  ParsedAttributes &Attrs,
@@ -2365,10 +2411,10 @@
                                 AR_DeclspecAttributesParsed
   };
 
-  void ParseTypeQualifierListOpt(DeclSpec &DS,
-                                 unsigned AttrReqs = AR_AllAttributesParsed,
-                                 bool AtomicAllowed = true,
-                                 bool IdentifierRequired = false);
+  void ParseTypeQualifierListOpt(
+      DeclSpec &DS, unsigned AttrReqs = AR_AllAttributesParsed,
+      bool AtomicAllowed = true, bool IdentifierRequired = false,
+      Optional<llvm::function_ref<void()>> CodeCompletionHandler = None);
   void ParseDirectDeclarator(Declarator &D);
   void ParseDecompositionDeclarator(Declarator &D);
   void ParseParenDeclarator(Declarator &D);
@@ -2706,7 +2752,19 @@
   //===--------------------------------------------------------------------===//
   // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
   ExprResult ParseTypeTrait();
-  
+
+  /// Parse the given string as a type.
+  ///
+  /// This is a dangerous utility function currently employed only by API notes.
+  /// It is not a general entry-point for safely parsing types from strings.
+  ///
+  /// \param typeStr The string to be parsed as a type.
+  /// \param context The name of the context in which this string is being
+  /// parsed, which will be used in diagnostics.
+  /// \param includeLoc The location at which this parse was triggered.
+  TypeResult parseTypeFromString(StringRef typeStr, StringRef context,
+                                 SourceLocation includeLoc);
+
   //===--------------------------------------------------------------------===//
   // Embarcadero: Arary and Expression Traits
   ExprResult ParseArrayTypeTrait();
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index e74bf6a..6bdd9d5 100644
--- a/include/clang/Sema/AttributeList.h
+++ b/include/clang/Sema/AttributeList.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
 #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
 
+#include "clang/Basic/AttrSubjectMatchRules.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/VersionTuple.h"
@@ -509,9 +510,14 @@
   unsigned getMaxArgs() const;
   bool hasVariadicArg() const;
   bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
+  bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
+  void getMatchRules(const LangOptions &LangOpts,
+                     SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
+                         &MatchRules) const;
   bool diagnoseLangOpts(class Sema &S) const;
   bool existsInTarget(const TargetInfo &Target) const;
   bool isKnownToGCC() const;
+  bool isSupportedByPragmaAttribute() const;
 
   /// \brief If the parsed attribute has a semantic equivalent, and it would
   /// have a semantic Spelling enumeration (due to having semantically-distinct
@@ -774,6 +780,8 @@
   void clear() { list = nullptr; pool.clear(); }
   AttributeList *getList() const { return list; }
 
+  void clearListOnly() { list = nullptr; }
+
   /// Returns a reference to the attribute list.  Try not to introduce
   /// dependencies on this method, it may not be long-lived.
   AttributeList *&getListRef() { return list; }
@@ -907,6 +915,7 @@
   ExpectedTypeOrNamespace,
   ExpectedObjectiveCInterface,
   ExpectedMethodOrProperty,
+  ExpectedFunctionOrMethodOrProperty,
   ExpectedStructOrUnion,
   ExpectedStructOrUnionOrClass,
   ExpectedType,
@@ -927,6 +936,7 @@
   ExpectedStructClassVariableFunctionOrInlineNamespace,
   ExpectedForMaybeUnused,
   ExpectedEnumOrClass,
+  ExpectedNamedDecl,
 };
 
 }  // end namespace clang
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 331fd0d..6503b51 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -859,11 +859,19 @@
 
   const IdentifierInfo *getGetterName() const { return GetterName; }
   IdentifierInfo *getGetterName() { return GetterName; }
-  void setGetterName(IdentifierInfo *name) { GetterName = name; }
+  SourceLocation getGetterNameLoc() const { return GetterNameLoc; }
+  void setGetterName(IdentifierInfo *name, SourceLocation loc) {
+    GetterName = name;
+    GetterNameLoc = loc;
+  }
 
   const IdentifierInfo *getSetterName() const { return SetterName; }
   IdentifierInfo *getSetterName() { return SetterName; }
-  void setSetterName(IdentifierInfo *name) { SetterName = name; }
+  SourceLocation getSetterNameLoc() const { return SetterNameLoc; }
+  void setSetterName(IdentifierInfo *name, SourceLocation loc) {
+    SetterName = name;
+    SetterNameLoc = loc;
+  }
 
 private:
   // FIXME: These two are unrelated and mutually exclusive. So perhaps
@@ -880,6 +888,9 @@
 
   IdentifierInfo *GetterName;    // getter name or NULL if no getter
   IdentifierInfo *SetterName;    // setter name or NULL if no setter
+  SourceLocation GetterNameLoc; // location of the getter attribute's value
+  SourceLocation SetterNameLoc; // location of the setter attribute's value
+
 };
 
 /// \brief Represents a C++ unqualified-id that has been parsed. 
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index 94be58a..918244d 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -70,6 +70,9 @@
     /// \brief The entity being initialized is a field of block descriptor for
     /// the copied-in c++ object.
     EK_BlockElement,
+    /// The entity being initialized is a field of block descriptor for the
+    /// copied-in lambda object that's used in the lambda to block conversion.
+    EK_LambdaToBlockConversionBlockElement,
     /// \brief The entity being initialized is the real or imaginary part of a
     /// complex number.
     EK_ComplexElement,
@@ -260,7 +263,13 @@
                                            QualType Type, bool NRVO) {
     return InitializedEntity(EK_BlockElement, BlockVarLoc, Type, NRVO);
   }
-  
+
+  static InitializedEntity InitializeLambdaToBlock(SourceLocation BlockVarLoc,
+                                                   QualType Type, bool NRVO) {
+    return InitializedEntity(EK_LambdaToBlockConversionBlockElement,
+                             BlockVarLoc, Type, NRVO);
+  }
+
   /// \brief Create the initialization entity for an exception object.
   static InitializedEntity InitializeException(SourceLocation ThrowLoc,
                                                QualType Type, bool NRVO) {
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 63d0784..be946ff 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -27,6 +27,7 @@
 #include "clang/AST/NSAPI.h"
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/APINotes/APINotesManager.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/ExpressionTraits.h"
 #include "clang/Basic/LangOptions.h"
@@ -54,6 +55,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include <deque>
+#include <functional>
 #include <memory>
 #include <string>
 #include <vector>
@@ -304,6 +306,7 @@
   ASTConsumer &Consumer;
   DiagnosticsEngine &Diags;
   SourceManager &SourceMgr;
+  api_notes::APINotesManager APINotes;
 
   /// \brief Flag indicating whether or not to collect detailed statistics.
   bool CollectStats;
@@ -435,6 +438,20 @@
   /// VisContext - Manages the stack for \#pragma GCC visibility.
   void *VisContext; // Really a "PragmaVisStack*"
 
+  /// \brief This represents the stack of attributes that were pushed by
+  /// \#pragma clang attribute.
+  struct PragmaAttributeEntry {
+    SourceLocation Loc;
+    AttributeList *Attribute;
+    SmallVector<attr::SubjectMatchRule, 4> MatchRules;
+    bool IsUsed;
+  };
+  SmallVector<PragmaAttributeEntry, 2> PragmaAttributeStack;
+
+  /// \brief The declaration that is currently receiving an attribute from the
+  /// #pragma attribute stack.
+  const Decl *PragmaAttributeCurrentTargetDecl;
+
   /// \brief This represents the last location of a "#pragma clang optimize off"
   /// directive if such a directive has not been closed by an "on" yet. If
   /// optimizations are currently "on", this is set to an invalid location.
@@ -573,6 +590,10 @@
     OpaqueParser = P;
   }
 
+  /// \brief Callback to the parser to parse a type expressed as a string.
+  std::function<TypeResult(StringRef, StringRef, SourceLocation)>
+    ParseTypeFromStringCallback;
+
   class DelayedDiagnostics;
 
   class DelayedDiagnosticsState {
@@ -1038,6 +1059,12 @@
   /// same special member, we should act as if it is not yet declared.
   llvm::SmallSet<SpecialMemberDecl, 4> SpecialMembersBeingDeclared;
 
+  /// The function definitions which were renamed as part of typo-correction
+  /// to match their respective declarations. We want to keep track of them
+  /// to ensure that we don't emit a "redefinition" error if we encounter a
+  /// correctly named definition after the renamed definition.
+  llvm::SmallPtrSet<const NamedDecl *, 4> TypoCorrectedFunctionDefinitions;
+
   void ReadMethodPool(Selector Sel);
   void updateOutOfDateSelector(Selector Sel);
 
@@ -1054,14 +1081,12 @@
   /// statements.
   class FPContractStateRAII {
   public:
-    FPContractStateRAII(Sema& S)
-      : S(S), OldFPContractState(S.FPFeatures.fp_contract) {}
-    ~FPContractStateRAII() {
-      S.FPFeatures.fp_contract = OldFPContractState;
-    }
+    FPContractStateRAII(Sema &S) : S(S), OldFPFeaturesState(S.FPFeatures) {}
+    ~FPContractStateRAII() { S.FPFeatures = OldFPFeaturesState; }
+
   private:
     Sema& S;
-    bool OldFPContractState : 1;
+    FPOptions OldFPFeaturesState;
   };
 
   void addImplicitTypedef(StringRef Name, QualType T);
@@ -1235,9 +1260,11 @@
   sema::BlockScopeInfo *getCurBlock();
 
   /// Retrieve the current lambda scope info, if any.
-  /// \param IgnoreCapturedRegions true if should find the top-most lambda scope
-  /// info ignoring all inner captured regions scope infos.
-  sema::LambdaScopeInfo *getCurLambda(bool IgnoreCapturedRegions = false);
+  /// \param IgnoreNonLambdaCapturingScope true if should find the top-most
+  /// lambda scope info ignoring all inner capturing scopes that are not
+  /// lambda scopes.
+  sema::LambdaScopeInfo *
+  getCurLambda(bool IgnoreNonLambdaCapturingScope = false);
 
   /// \brief Retrieve the current generic lambda info, if any.
   sema::LambdaScopeInfo *getCurGenericLambda();
@@ -1409,6 +1436,24 @@
     }
   };
 
+  /// Do a check to make sure \p Name looks like a legal swift_name
+  /// attribute for the decl \p D. Raise a diagnostic if the name is invalid
+  /// for the given declaration.
+  ///
+  /// For a function, this will validate a compound Swift name,
+  /// e.g. <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>,
+  /// and the function will output the number of parameter names, and whether
+  /// this is a single-arg initializer.
+  ///
+  /// For a type, enum constant, property, or variable declaration, this will
+  /// validate either a simple identifier, or a qualified
+  /// <code>context.identifier</code> name.
+  ///
+  /// \returns true if the name is a valid swift name for \p D, false otherwise.
+  bool DiagnoseSwiftName(Decl *D, StringRef Name,
+                         SourceLocation ArgLoc,
+                         IdentifierInfo *AttrName);
+
 private:
   bool RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
                                TypeDiagnoser *Diagnoser);
@@ -1777,6 +1822,8 @@
   ParmVarDecl *BuildParmVarDeclForTypedef(DeclContext *DC,
                                           SourceLocation Loc,
                                           QualType T);
+  QualType adjustParameterTypeForObjCAutoRefCount(QualType T,
+                                                  SourceLocation Loc);
   ParmVarDecl *CheckParameter(DeclContext *DC, SourceLocation StartLoc,
                               SourceLocation NameLoc, IdentifierInfo *Name,
                               QualType T, TypeSourceInfo *TSInfo,
@@ -2263,6 +2310,9 @@
                                 unsigned AttrSpellingListIndex);
   OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, SourceRange Range,
                                           unsigned AttrSpellingListIndex);
+  SwiftNameAttr *mergeSwiftNameAttr(Decl *D, SourceRange Range,
+                                    StringRef Name, bool Override,
+                                    unsigned AttrSpellingListIndex);
   InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, SourceRange Range,
                                                 IdentifierInfo *Ident,
                                                 unsigned AttrSpellingListIndex);
@@ -2282,6 +2332,7 @@
   void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld);
   void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
   bool checkVarDeclRedefinition(VarDecl *OldDefn, VarDecl *NewDefn);
+  void notePreviousDefinition(SourceLocation Old, SourceLocation New);
   bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
 
   // AssignmentAction - This is used by all the assignment diagnostic functions
@@ -2642,7 +2693,7 @@
   /// of a function.
   ///
   /// Returns true if any errors were emitted.
-  bool diagnoseArgIndependentDiagnoseIfAttrs(const FunctionDecl *Function,
+  bool diagnoseArgIndependentDiagnoseIfAttrs(const NamedDecl *ND,
                                              SourceLocation Loc);
 
   /// Returns whether the given function's address can be taken or not,
@@ -2998,7 +3049,8 @@
                           bool IncludeGlobalScope = true);
   void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
                           VisibleDeclConsumer &Consumer,
-                          bool IncludeGlobalScope = true);
+                          bool IncludeGlobalScope = true,
+                          bool IncludeDependentBases = false);
 
   enum CorrectTypoKind {
     CTK_NonError,     // CorrectTypo used in a non error recovery situation.
@@ -3072,6 +3124,8 @@
                     const PartialDiagnostic &PrevNote,
                     bool ErrorRecovery = true);
 
+  void MarkTypoCorrectedFunctionDefinition(const NamedDecl *F);
+
   void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc,
                                           ArrayRef<Expr *> Args,
                                    AssociatedNamespaceSet &AssociatedNamespaces,
@@ -3105,6 +3159,12 @@
 
   void checkUnusedDeclAttributes(Declarator &D);
 
+  /// Map any API notes provided for this declaration to attributes on the
+  /// declaration.
+  ///
+  /// Triggered by declaration-attribute processing.
+  void ProcessAPINotes(Decl *D);
+
   /// Determine if type T is a valid subject for a nonnull and similar
   /// attributes. By default, we look through references (the behavior used by
   /// nonnull), but if the second parameter is true, then we treat a reference
@@ -3159,11 +3219,16 @@
   /// \param allowArrayTypes Whether to accept nullability specifiers on an
   /// array type (e.g., because it will decay to a pointer).
   ///
+  /// \param overrideExisting Whether to override an existing, locally-specified
+  /// nullability specifier rather than complaining about the conflict.
+  ///
   /// \returns true if nullability cannot be applied, false otherwise.
   bool checkNullabilityTypeSpecifier(QualType &type, NullabilityKind nullability,
                                      SourceLocation nullabilityLoc,
                                      bool isContextSensitive,
-                                     bool allowArrayTypes);
+                                     bool allowArrayTypes,
+                                     bool implicit,
+                                     bool overrideExisting = false);
 
   /// \brief Stmt attributes - this routine is the top level dispatcher.
   StmtResult ProcessStmtAttributes(Stmt *Stmt, AttributeList *Attrs,
@@ -3237,7 +3302,9 @@
                       SourceLocation LParenLoc,
                       FieldDeclarator &FD,
                       Selector GetterSel,
+                      SourceLocation GetterNameLoc,
                       Selector SetterSel,
+                      SourceLocation SetterNameLoc,
                       const bool isReadWrite,
                       unsigned &Attributes,
                       const unsigned AttributesAsWritten,
@@ -3253,7 +3320,9 @@
                                        SourceLocation LParenLoc,
                                        FieldDeclarator &FD,
                                        Selector GetterSel,
+                                       SourceLocation GetterNameLoc,
                                        Selector SetterSel,
+                                       SourceLocation SetterNameLoc,
                                        const bool isReadWrite,
                                        const unsigned Attributes,
                                        const unsigned AttributesAsWritten,
@@ -7139,6 +7208,8 @@
 
   void PrintInstantiationStack();
 
+  void PrintPragmaAttributeInstantiationPoint();
+
   /// \brief Determines whether we are currently in a context where
   /// template argument substitution failures are not considered
   /// errors.
@@ -7436,6 +7507,12 @@
                         LateInstantiatedAttrVec *LateAttrs = nullptr,
                         LocalInstantiationScope *OuterMostScope = nullptr);
 
+  void
+  InstantiateAttrsForDecl(const MultiLevelTemplateArgumentList &TemplateArgs,
+                          const Decl *Pattern, Decl *Inst,
+                          LateInstantiatedAttrVec *LateAttrs = nullptr,
+                          LocalInstantiationScope *OuterMostScope = nullptr);
+
   bool
   InstantiateClassTemplateSpecialization(SourceLocation PointOfInstantiation,
                            ClassTemplateSpecializationDecl *ClassTemplateSpec,
@@ -7597,7 +7674,8 @@
                                     Decl * const *ProtoRefs,
                                     unsigned NumProtoRefs,
                                     const SourceLocation *ProtoLocs,
-                                    SourceLocation EndProtoLoc);
+                                    SourceLocation EndProtoLoc,
+                                    AttributeList *AttrList);
 
   Decl *ActOnStartClassImplementation(
                     SourceLocation AtClassImplLoc,
@@ -7928,6 +8006,12 @@
     RTC_Unknown
   };
 
+  /// Check whether the declared result type of the given Objective-C
+  /// method declaration is compatible with the method's class.
+  ResultTypeCompatibilityKind
+  checkRelatedResultTypeCompatibility(const ObjCMethodDecl *Method,
+                                      const ObjCInterfaceDecl *CurrentClass);
+
   void CheckObjCMethodOverrides(ObjCMethodDecl *ObjCMethod,
                                 ObjCInterfaceDecl *CurrentClass,
                                 ResultTypeCompatibilityKind RTC);
@@ -8039,8 +8123,9 @@
                             SourceLocation AliasNameLoc);
 
   /// ActOnPragmaFPContract - Called on well formed
-  /// \#pragma {STDC,OPENCL} FP_CONTRACT
-  void ActOnPragmaFPContract(tok::OnOffSwitch OOS);
+  /// \#pragma {STDC,OPENCL} FP_CONTRACT and
+  /// \#pragma clang fp contract
+  void ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC);
 
   /// AddAlignmentAttributesForRecord - Adds any needed alignment attributes to
   /// a the record decl, to handle '\#pragma pack' and '\#pragma options align'.
@@ -8073,6 +8158,20 @@
   /// the appropriate attribute.
   void AddCFAuditedAttribute(Decl *D);
 
+  /// \brief Called on well-formed '\#pragma clang attribute push'.
+  void ActOnPragmaAttributePush(AttributeList &Attribute,
+                                SourceLocation PragmaLoc,
+                                attr::ParsedSubjectMatchRuleSet Rules);
+
+  /// \brief Called on well-formed '\#pragma clang attribute pop'.
+  void ActOnPragmaAttributePop(SourceLocation PragmaLoc);
+
+  /// \brief Adds the attributes that have been specified using the
+  /// '\#pragma clang attribute push' directives to the given declaration.
+  void AddPragmaAttributes(Scope *S, Decl *D);
+
+  void DiagnoseUnterminatedPragmaAttribute();
+
   /// \brief Called on well formed \#pragma clang optimize.
   void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc);
 
@@ -9265,14 +9364,14 @@
   enum ARCConversionResult { ACR_okay, ACR_unbridged, ACR_error };
 
   /// \brief Checks for invalid conversions and casts between
-  /// retainable pointers and other pointer kinds.
-  ARCConversionResult CheckObjCARCConversion(SourceRange castRange,
-                                             QualType castType, Expr *&op,
-                                             CheckedConversionKind CCK,
-                                             bool Diagnose = true,
-                                             bool DiagnoseCFAudited = false,
-                                             BinaryOperatorKind Opc = BO_PtrMemD
-                                             );
+  /// retainable pointers and other pointer kinds for ARC and Weak.
+  ARCConversionResult CheckObjCConversion(SourceRange castRange,
+                                          QualType castType, Expr *&op,
+                                          CheckedConversionKind CCK,
+                                          bool Diagnose = true,
+                                          bool DiagnoseCFAudited = false,
+                                          BinaryOperatorKind Opc = BO_PtrMemD
+                                          );
 
   Expr *stripARCUnbridgedCast(Expr *e);
   void diagnoseARCUnbridgedCast(Expr *e);
@@ -9777,6 +9876,8 @@
   void CodeCompletePostfixExpression(Scope *S, ExprResult LHS);
   void CodeCompleteTag(Scope *S, unsigned TagSpec);
   void CodeCompleteTypeQualifiers(DeclSpec &DS);
+  void CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D,
+                                      const VirtSpecifiers *VS = nullptr);
   void CodeCompleteBracketDeclarator(Scope *S);
   void CodeCompleteCase(Scope *S);
   void CodeCompleteCall(Scope *S, Expr *Fn, ArrayRef<Expr *> Args);
@@ -9863,6 +9964,7 @@
                                              MacroInfo *MacroInfo,
                                              unsigned Argument);
   void CodeCompleteNaturalLanguage();
+  void CodeCompleteAvailabilityPlatformName();
   void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
                                    CodeCompletionTUInfo &CCTUInfo,
                   SmallVectorImpl<CodeCompletionResult> &Results);
@@ -10107,6 +10209,7 @@
 
   /// The struct behind the CFErrorRef pointer.
   RecordDecl *CFError = nullptr;
+  bool isCFError(RecordDecl *D);
 
   /// Retrieve the identifier "NSError".
   IdentifierInfo *getNSErrorIdent();
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index acbd6d1..295c527 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -226,7 +226,7 @@
 
       /// \brief The block containing the detailed preprocessing record.
       PREPROCESSOR_DETAIL_BLOCK_ID,
-      
+
       /// \brief The block containing the submodule structure.
       SUBMODULE_BLOCK_ID,
 
@@ -253,6 +253,10 @@
 
       /// \brief A block containing a module file extension.
       EXTENSION_BLOCK_ID,
+
+      /// A block containing unhashed contents. It currently holds Diagnostic
+      /// Options and Signature.
+      UNHASHED_CONTROL_BLOCK_ID,
     };
 
     /// \brief Record types that occur within the control block.
@@ -288,9 +292,6 @@
       /// AST file.
       MODULE_MAP_FILE,
 
-      /// \brief Record code for the signature that identifiers this AST file.
-      SIGNATURE,
-
       /// \brief Record code for the module build directory.
       MODULE_DIRECTORY,
     };
@@ -309,9 +310,6 @@
       /// \brief Record code for the target options table.
       TARGET_OPTIONS,
 
-      /// \brief Record code for the diagnostic options table.
-      DIAGNOSTIC_OPTIONS,
-
       /// \brief Record code for the filesystem options table.
       FILE_SYSTEM_OPTIONS,
 
@@ -322,6 +320,18 @@
       PREPROCESSOR_OPTIONS,
     };
 
+    /// Record codes for the unhashed control block.
+    enum UnhashedControlBlockRecordTypes {
+      /// Record code for the signature that identifiers this AST file.
+      SIGNATURE = 1,
+
+      /// Record code for the diagnostic options table.
+      DIAGNOSTIC_OPTIONS,
+
+      /// Record code for \#pragma diagnostic mappings.
+      DIAG_PRAGMA_MAPPINGS,
+    };
+
     /// \brief Record code for extension blocks.
     enum ExtensionBlockRecordTypes {
       /// Metadata describing this particular extension.
@@ -493,8 +503,7 @@
 
       // ID 31 used to be a list of offsets to DECL_CXX_BASE_SPECIFIERS records.
 
-      /// \brief Record code for \#pragma diagnostic mappings.
-      DIAG_PRAGMA_MAPPINGS = 32,
+      // ID 32 used to be the code for \#pragma diagnostic mappings.
 
       /// \brief Record code for special CUDA declarations.
       CUDA_SPECIAL_DECL_REFS = 33,
@@ -591,6 +600,9 @@
 
       /// \brief Record code for declarations associated with OpenCL extensions.
       OPENCL_EXTENSION_DECLS = 59,
+
+      /// \brief Record code for \#pragma pack options.
+      PACK_PRAGMA_OPTIONS = 61,
     };
 
     /// \brief Record types used within a source manager block.
@@ -914,7 +926,9 @@
       /// \brief A PipeType record.
       TYPE_PIPE                  = 43,
       /// \brief An ObjCTypeParamType record.
-      TYPE_OBJC_TYPE_PARAM       = 44
+      TYPE_OBJC_TYPE_PARAM       = 44,
+      /// \brief A DependentSizedExtVectorType record.
+      TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46
     };
 
     /// \brief The type IDs for special types constructed by semantic
diff --git a/include/clang/Serialization/ASTDeserializationListener.h b/include/clang/Serialization/ASTDeserializationListener.h
index 4b10c39..c26f3e0 100644
--- a/include/clang/Serialization/ASTDeserializationListener.h
+++ b/include/clang/Serialization/ASTDeserializationListener.h
@@ -26,6 +26,7 @@
 class MacroDefinitionRecord;
 class MacroInfo;
 class Module;
+class SourceLocation;
 
 class ASTDeserializationListener {
 public:
@@ -52,6 +53,9 @@
                                    MacroDefinitionRecord *MD) {}
   /// \brief A module definition was read from the AST file.
   virtual void ModuleRead(serialization::SubmoduleID ID, Module *Mod) {}
+  /// \brief A module import was read from the AST file.
+  virtual void ModuleImportRead(serialization::SubmoduleID ID,
+                                SourceLocation ImportLoc) {}
 };
 }
 
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 93994e2..f9113bd 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -408,6 +408,9 @@
   /// \brief The module manager which manages modules and their dependencies
   ModuleManager ModuleMgr;
 
+  /// The cache that manages memory buffers for PCM files.
+  MemoryBufferCache &PCMCache;
+
   /// \brief A dummy identifier resolver used to merge TU-scope declarations in
   /// C, for the cases where we don't have a Sema object to provide a real
   /// identifier resolver.
@@ -808,6 +811,17 @@
   int PragmaMSPointersToMembersState = -1;
   SourceLocation PointersToMembersPragmaLocation;
 
+  /// \brief The pragma pack state.
+  Optional<unsigned> PragmaPackCurrentValue;
+  SourceLocation PragmaPackCurrentLocation;
+  struct PragmaPackStackEntry {
+    unsigned Value;
+    SourceLocation Location;
+    StringRef SlotLabel;
+  };
+  llvm::SmallVector<PragmaPackStackEntry, 2> PragmaPackStack;
+  llvm::SmallVector<std::string, 2> PragmaPackStrings;
+
   /// \brief The OpenCL extension settings.
   OpenCLOptions OpenCLExtensions;
 
@@ -970,14 +984,26 @@
   /// \brief The generation number of each identifier, which keeps track of
   /// the last time we loaded information about this identifier.
   llvm::DenseMap<IdentifierInfo *, unsigned> IdentifierGeneration;
-  
-  /// \brief Contains declarations and definitions that will be
+
+  class InterestingDecl {
+    Decl *D;
+    bool DeclHasPendingBody;
+
+  public:
+    InterestingDecl(Decl *D, bool HasBody)
+        : D(D), DeclHasPendingBody(HasBody) {}
+    Decl *getDecl() { return D; }
+    /// Whether the declaration has a pending body.
+    bool hasPendingBody() { return DeclHasPendingBody; }
+  };
+
+  /// \brief Contains declarations and definitions that could be
   /// "interesting" to the ASTConsumer, when we get that AST consumer.
   ///
   /// "Interesting" declarations are those that have data that may
   /// need to be emitted, such as inline function definitions or
   /// Objective-C protocols.
-  std::deque<Decl *> InterestingDecls;
+  std::deque<InterestingDecl> PotentiallyInterestingDecls;
 
   /// \brief The list of redeclaration chains that still need to be 
   /// reconstructed, and the local offset to the corresponding list
@@ -1174,7 +1200,7 @@
                             SourceLocation ImportLoc, ModuleFile *ImportedBy,
                             SmallVectorImpl<ImportedModule> &Loaded,
                             off_t ExpectedSize, time_t ExpectedModTime,
-                            serialization::ASTFileSignature ExpectedSignature,
+                            ASTFileSignature ExpectedSignature,
                             unsigned ClientLoadCapabilities);
   ASTReadResult ReadControlBlock(ModuleFile &F,
                                  SmallVectorImpl<ImportedModule> &Loaded,
@@ -1183,7 +1209,22 @@
   static ASTReadResult ReadOptionsBlock(
       llvm::BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
       bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
-      std::string &SuggestedPredefines, bool ValidateDiagnosticOptions);
+      std::string &SuggestedPredefines);
+
+  /// Read the unhashed control block.
+  ///
+  /// This has no effect on \c F.Stream, instead creating a fresh cursor from
+  /// \c F.Data and reading ahead.
+  ASTReadResult readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
+                                         unsigned ClientLoadCapabilities);
+
+  static ASTReadResult
+  readUnhashedControlBlockImpl(ModuleFile *F, llvm::StringRef StreamData,
+                               unsigned ClientLoadCapabilities,
+                               bool AllowCompatibleConfigurationMismatch,
+                               ASTReaderListener *Listener,
+                               bool ValidateDiagnosticOptions);
+
   ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);
   ASTReadResult ReadExtensionBlock(ModuleFile &F);
   bool ParseLineTable(ModuleFile &F, const RecordData &Record);
@@ -1268,6 +1309,7 @@
   llvm::iterator_range<PreprocessingRecord::iterator>
   getModulePreprocessedEntities(ModuleFile &Mod) const;
 
+public:
   class ModuleDeclIterator
       : public llvm::iterator_adaptor_base<
             ModuleDeclIterator, const serialization::LocalDeclID *,
@@ -1298,6 +1340,7 @@
   llvm::iterator_range<ModuleDeclIterator>
   getModuleFileLevelDecls(ModuleFile &Mod);
 
+private:
   void PassInterestingDeclsToConsumer();
   void PassInterestingDeclToConsumer(Decl *D);
 
@@ -1633,7 +1676,7 @@
     unsigned Result = 0;
     for (ModuleConstIterator I = ModuleMgr.begin(),
         E = ModuleMgr.end(); I != E; ++I) {
-      Result += (*I)->NumPreprocessedEntities;
+      Result += I->NumPreprocessedEntities;
     }
 
     return Result;
@@ -2189,6 +2232,12 @@
   /// \brief Loads comments ranges.
   void ReadComments() override;
 
+  /// Visit all the input files of the given module file.
+  void visitInputFiles(serialization::ModuleFile &MF,
+                       bool IncludeSystem, bool Complain,
+          llvm::function_ref<void(const serialization::InputFile &IF,
+                                  bool isSystem)> Visitor);
+
   bool isProcessingUpdateRecords() { return ProcessingUpdateRecords; }
 };
 
diff --git a/include/clang/Serialization/ASTWriter.h b/include/clang/Serialization/ASTWriter.h
index 0d6b026..ad81241 100644
--- a/include/clang/Serialization/ASTWriter.h
+++ b/include/clang/Serialization/ASTWriter.h
@@ -54,6 +54,7 @@
 class OpaqueValueExpr;
 class OpenCLOptions;
 class ASTReader;
+class MemoryBufferCache;
 class Module;
 class ModuleFileExtension;
 class ModuleFileExtensionWriter;
@@ -106,6 +107,12 @@
   /// \brief The bitstream writer used to emit this precompiled header.
   llvm::BitstreamWriter &Stream;
 
+  /// The buffer associated with the bitstream.
+  const SmallVectorImpl<char> &Buffer;
+
+  /// \brief The PCM manager which manages memory buffers for pcm files.
+  MemoryBufferCache &PCMCache;
+
   /// \brief The ASTContext we're writing.
   ASTContext *Context = nullptr;
 
@@ -424,8 +431,16 @@
   void WriteSubStmt(Stmt *S);
 
   void WriteBlockInfoBlock();
-  uint64_t WriteControlBlock(Preprocessor &PP, ASTContext &Context,
-                             StringRef isysroot, const std::string &OutputFile);
+  void WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+                         StringRef isysroot, const std::string &OutputFile);
+
+  /// Write out the signature and diagnostic options, and return the signature.
+  ASTFileSignature writeUnhashedControlBlock(Preprocessor &PP,
+                                             ASTContext &Context);
+
+  /// Calculate hash of the pcm content.
+  static ASTFileSignature createSignature(StringRef Bytes);
+
   void WriteInputFiles(SourceManager &SourceMgr, HeaderSearchOptions &HSOpts,
                        bool Modules);
   void WriteSourceManagerBlock(SourceManager &SourceMgr,
@@ -469,6 +484,7 @@
   void WriteOptimizePragmaOptions(Sema &SemaRef);
   void WriteMSStructPragmaOptions(Sema &SemaRef);
   void WriteMSPointersToMembersPragmaOptions(Sema &SemaRef);
+  void WritePackPragmaOptions(Sema &SemaRef);
   void WriteModuleFileExtension(Sema &SemaRef,
                                 ModuleFileExtensionWriter &Writer);
 
@@ -492,14 +508,15 @@
   void WriteDeclAbbrevs();
   void WriteDecl(ASTContext &Context, Decl *D);
 
-  uint64_t WriteASTCore(Sema &SemaRef,
-                        StringRef isysroot, const std::string &OutputFile,
-                        Module *WritingModule);
+  ASTFileSignature WriteASTCore(Sema &SemaRef, StringRef isysroot,
+                                const std::string &OutputFile,
+                                Module *WritingModule);
 
 public:
   /// \brief Create a new precompiled header writer that outputs to
   /// the given bitstream.
-  ASTWriter(llvm::BitstreamWriter &Stream,
+  ASTWriter(llvm::BitstreamWriter &Stream, SmallVectorImpl<char> &Buffer,
+            MemoryBufferCache &PCMCache,
             ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
             bool IncludeTimestamps = true);
   ~ASTWriter() override;
@@ -525,9 +542,9 @@
   ///
   /// \return the module signature, which eventually will be a hash of
   /// the module but currently is merely a random 32-bit number.
-  uint64_t WriteAST(Sema &SemaRef, const std::string &OutputFile,
-                    Module *WritingModule, StringRef isysroot,
-                    bool hasErrors = false);
+  ASTFileSignature WriteAST(Sema &SemaRef, const std::string &OutputFile,
+                            Module *WritingModule, StringRef isysroot,
+                            bool hasErrors = false);
 
   /// \brief Emit a token.
   void AddToken(const Token &Tok, RecordDataImpl &Record);
diff --git a/include/clang/Serialization/Module.h b/include/clang/Serialization/Module.h
index 58b3149..d28a2f3 100644
--- a/include/clang/Serialization/Module.h
+++ b/include/clang/Serialization/Module.h
@@ -16,6 +16,7 @@
 #define LLVM_CLANG_SERIALIZATION_MODULE_H
 
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/Module.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Serialization/ASTBitCodes.h"
 #include "clang/Serialization/ContinuousRangeMap.h"
@@ -89,8 +90,6 @@
   bool isNotFound() const { return Val.getInt() == NotFound; }
 };
 
-typedef unsigned ASTFileSignature;
-
 /// \brief Information about a module that has been loaded by the ASTReader.
 ///
 /// Each instance of the Module class corresponds to a single AST file, which
@@ -100,13 +99,14 @@
 /// other modules.
 class ModuleFile {
 public:
-  ModuleFile(ModuleKind Kind, unsigned Generation);
+  ModuleFile(ModuleKind Kind, unsigned Generation)
+      : Kind(Kind), Generation(Generation) {}
   ~ModuleFile();
 
   // === General information ===
 
   /// \brief The index of this module in the list of modules.
-  unsigned Index;
+  unsigned Index = 0;
 
   /// \brief The type of this module.
   ModuleKind Kind;
@@ -144,34 +144,34 @@
   std::string ModuleMapPath;
 
   /// \brief Whether this precompiled header is a relocatable PCH file.
-  bool RelocatablePCH;
+  bool RelocatablePCH = false;
 
   /// \brief Whether timestamps are included in this module file.
-  bool HasTimestamps;
+  bool HasTimestamps = false;
 
   /// \brief The file entry for the module file.
-  const FileEntry *File;
+  const FileEntry *File = nullptr;
 
-  /// \brief The signature of the module file, which may be used along with size
+  /// The signature of the module file, which may be used instead of the size
   /// and modification time to identify this particular file.
   ASTFileSignature Signature;
 
   /// \brief Whether this module has been directly imported by the
   /// user.
-  bool DirectlyImported;
+  bool DirectlyImported = false;
 
   /// \brief The generation of which this module file is a part.
   unsigned Generation;
   
-  /// \brief The memory buffer that stores the data associated with
-  /// this AST file.
-  std::unique_ptr<llvm::MemoryBuffer> Buffer;
+  /// The memory buffer that stores the data associated with
+  /// this AST file, owned by the PCMCache in the ModuleManager.
+  llvm::MemoryBuffer *Buffer;
 
   /// \brief The size of this file, in bits.
-  uint64_t SizeInBits;
+  uint64_t SizeInBits = 0;
 
   /// \brief The global bit offset (or base) of this module
-  uint64_t GlobalBitOffset;
+  uint64_t GlobalBitOffset = 0;
 
   /// \brief The serialized bitstream data for this file.
   StringRef Data;
@@ -205,16 +205,20 @@
   llvm::BitstreamCursor InputFilesCursor;
 
   /// \brief Offsets for all of the input file entries in the AST file.
-  const llvm::support::unaligned_uint64_t *InputFileOffsets;
+  const llvm::support::unaligned_uint64_t *InputFileOffsets = nullptr;
 
   /// \brief The input files that have been loaded from this AST file.
   std::vector<InputFile> InputFilesLoaded;
 
+  // All user input files reside at the index range [0, NumUserInputFiles), and
+  // system input files reside at [NumUserInputFiles, InputFilesLoaded.size()).
+  unsigned NumUserInputFiles = 0;
+
   /// \brief If non-zero, specifies the time when we last validated input
   /// files.  Zero means we never validated them.
   ///
   /// The time is specified in seconds since the start of the Epoch.
-  uint64_t InputFilesValidationTimestamp;
+  uint64_t InputFilesValidationTimestamp = 0;
 
   // === Source Locations ===
 
@@ -222,17 +226,17 @@
   llvm::BitstreamCursor SLocEntryCursor;
 
   /// \brief The number of source location entries in this AST file.
-  unsigned LocalNumSLocEntries;
+  unsigned LocalNumSLocEntries = 0;
 
   /// \brief The base ID in the source manager's view of this module.
-  int SLocEntryBaseID;
+  int SLocEntryBaseID = 0;
 
   /// \brief The base offset in the source manager's view of this module.
-  unsigned SLocEntryBaseOffset;
+  unsigned SLocEntryBaseOffset = 0;
 
   /// \brief Offsets for all of the source location entries in the
   /// AST file.
-  const uint32_t *SLocEntryOffsets;
+  const uint32_t *SLocEntryOffsets = nullptr;
 
   /// \brief SLocEntries that we're going to preload.
   SmallVector<uint64_t, 4> PreloadSLocEntries;
@@ -243,17 +247,17 @@
   // === Identifiers ===
 
   /// \brief The number of identifiers in this AST file.
-  unsigned LocalNumIdentifiers;
+  unsigned LocalNumIdentifiers = 0;
 
   /// \brief Offsets into the identifier table data.
   ///
   /// This array is indexed by the identifier ID (-1), and provides
   /// the offset into IdentifierTableData where the string data is
   /// stored.
-  const uint32_t *IdentifierOffsets;
+  const uint32_t *IdentifierOffsets = nullptr;
 
   /// \brief Base identifier ID for identifiers local to this module.
-  serialization::IdentID BaseIdentifierID;
+  serialization::IdentID BaseIdentifierID = 0;
 
   /// \brief Remapping table for identifier IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap;
@@ -262,11 +266,11 @@
   ///
   /// This pointer points into a memory buffer, where the on-disk hash
   /// table for identifiers actually lives.
-  const char *IdentifierTableData;
+  const char *IdentifierTableData = nullptr;
 
   /// \brief A pointer to an on-disk hash table of opaque type
   /// IdentifierHashTable.
-  void *IdentifierLookupTable;
+  void *IdentifierLookupTable = nullptr;
 
   /// \brief Offsets of identifiers that we're going to preload within
   /// IdentifierTableData.
@@ -279,23 +283,23 @@
   llvm::BitstreamCursor MacroCursor;
 
   /// \brief The number of macros in this AST file.
-  unsigned LocalNumMacros;
+  unsigned LocalNumMacros = 0;
 
   /// \brief Offsets of macros in the preprocessor block.
   ///
   /// This array is indexed by the macro ID (-1), and provides
   /// the offset into the preprocessor block where macro definitions are
   /// stored.
-  const uint32_t *MacroOffsets;
+  const uint32_t *MacroOffsets = nullptr;
 
   /// \brief Base macro ID for macros local to this module.
-  serialization::MacroID BaseMacroID;
+  serialization::MacroID BaseMacroID = 0;
 
   /// \brief Remapping table for macro IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> MacroRemap;
 
   /// \brief The offset of the start of the set of defined macros.
-  uint64_t MacroStartOffset;
+  uint64_t MacroStartOffset = 0;
 
   // === Detailed PreprocessingRecord ===
 
@@ -304,40 +308,40 @@
   llvm::BitstreamCursor PreprocessorDetailCursor;
 
   /// \brief The offset of the start of the preprocessor detail cursor.
-  uint64_t PreprocessorDetailStartOffset;
+  uint64_t PreprocessorDetailStartOffset = 0;
 
   /// \brief Base preprocessed entity ID for preprocessed entities local to
   /// this module.
-  serialization::PreprocessedEntityID BasePreprocessedEntityID;
+  serialization::PreprocessedEntityID BasePreprocessedEntityID = 0;
 
   /// \brief Remapping table for preprocessed entity IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> PreprocessedEntityRemap;
 
-  const PPEntityOffset *PreprocessedEntityOffsets;
-  unsigned NumPreprocessedEntities;
+  const PPEntityOffset *PreprocessedEntityOffsets = nullptr;
+  unsigned NumPreprocessedEntities = 0;
 
   // === Header search information ===
 
   /// \brief The number of local HeaderFileInfo structures.
-  unsigned LocalNumHeaderFileInfos;
+  unsigned LocalNumHeaderFileInfos = 0;
 
   /// \brief Actual data for the on-disk hash table of header file
   /// information.
   ///
   /// This pointer points into a memory buffer, where the on-disk hash
   /// table for header file information actually lives.
-  const char *HeaderFileInfoTableData;
+  const char *HeaderFileInfoTableData = nullptr;
 
   /// \brief The on-disk hash table that contains information about each of
   /// the header files.
-  void *HeaderFileInfoTable;
+  void *HeaderFileInfoTable = nullptr;
 
   // === Submodule information ===  
   /// \brief The number of submodules in this module.
-  unsigned LocalNumSubmodules;
+  unsigned LocalNumSubmodules = 0;
   
   /// \brief Base submodule ID for submodules local to this module.
-  serialization::SubmoduleID BaseSubmoduleID;
+  serialization::SubmoduleID BaseSubmoduleID = 0;
   
   /// \brief Remapping table for submodule IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> SubmoduleRemap;
@@ -347,14 +351,14 @@
   /// \brief The number of selectors new to this file.
   ///
   /// This is the number of entries in SelectorOffsets.
-  unsigned LocalNumSelectors;
+  unsigned LocalNumSelectors = 0;
 
   /// \brief Offsets into the selector lookup table's data array
   /// where each selector resides.
-  const uint32_t *SelectorOffsets;
+  const uint32_t *SelectorOffsets = nullptr;
 
   /// \brief Base selector ID for selectors local to this module.
-  serialization::SelectorID BaseSelectorID;
+  serialization::SelectorID BaseSelectorID = 0;
 
   /// \brief Remapping table for selector IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> SelectorRemap;
@@ -362,14 +366,14 @@
   /// \brief A pointer to the character data that comprises the selector table
   ///
   /// The SelectorOffsets table refers into this memory.
-  const unsigned char *SelectorLookupTableData;
+  const unsigned char *SelectorLookupTableData = nullptr;
 
   /// \brief A pointer to an on-disk hash table of opaque type
   /// ASTSelectorLookupTable.
   ///
   /// This hash table provides the IDs of all selectors, and the associated
   /// instance and factory methods.
-  void *SelectorLookupTable;
+  void *SelectorLookupTable = nullptr;
 
   // === Declarations ===
 
@@ -379,14 +383,14 @@
   llvm::BitstreamCursor DeclsCursor;
 
   /// \brief The number of declarations in this AST file.
-  unsigned LocalNumDecls;
+  unsigned LocalNumDecls = 0;
 
   /// \brief Offset of each declaration within the bitstream, indexed
   /// by the declaration ID (-1).
-  const DeclOffset *DeclOffsets;
+  const DeclOffset *DeclOffsets = nullptr;
 
   /// \brief Base declaration ID for declarations local to this module.
-  serialization::DeclID BaseDeclID;
+  serialization::DeclID BaseDeclID = 0;
 
   /// \brief Remapping table for declaration IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> DeclRemap;
@@ -401,15 +405,15 @@
   llvm::DenseMap<ModuleFile *, serialization::DeclID> GlobalToLocalDeclIDs;
 
   /// \brief Array of file-level DeclIDs sorted by file.
-  const serialization::DeclID *FileSortedDecls;
-  unsigned NumFileSortedDecls;
+  const serialization::DeclID *FileSortedDecls = nullptr;
+  unsigned NumFileSortedDecls = 0;
 
   /// \brief Array of category list location information within this 
   /// module file, sorted by the definition ID.
-  const serialization::ObjCCategoriesInfo *ObjCCategoriesMap;
+  const serialization::ObjCCategoriesInfo *ObjCCategoriesMap = nullptr;
   
   /// \brief The number of redeclaration info entries in ObjCCategoriesMap.
-  unsigned LocalNumObjCCategoriesInMap;
+  unsigned LocalNumObjCCategoriesInMap = 0;
   
   /// \brief The Objective-C category lists for categories known to this
   /// module.
@@ -418,15 +422,15 @@
   // === Types ===
 
   /// \brief The number of types in this AST file.
-  unsigned LocalNumTypes;
+  unsigned LocalNumTypes = 0;
 
   /// \brief Offset of each type within the bitstream, indexed by the
   /// type ID, or the representation of a Type*.
-  const uint32_t *TypeOffsets;
+  const uint32_t *TypeOffsets = nullptr;
 
   /// \brief Base type ID for types local to this module as represented in
   /// the global type ID space.
-  serialization::TypeID BaseTypeIndex;
+  serialization::TypeID BaseTypeIndex = 0;
 
   /// \brief Remapping table for type IDs in this module.
   ContinuousRangeMap<uint32_t, int, 2> TypeRemap;
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index 1c4d88e..da6bedc 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -19,10 +19,12 @@
 #include "clang/Serialization/Module.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/iterator.h"
 
 namespace clang { 
 
 class GlobalModuleIndex;
+class MemoryBufferCache;
 class ModuleMap;
 class PCHContainerReader;
 
@@ -32,7 +34,7 @@
 class ModuleManager {
   /// \brief The chain of AST files, in the order in which we started to load
   /// them (this order isn't really useful for anything).
-  SmallVector<ModuleFile *, 2> Chain;
+  SmallVector<std::unique_ptr<ModuleFile>, 2> Chain;
 
   /// \brief The chain of non-module PCH files. The first entry is the one named
   /// by the user, the last one is the one that doesn't depend on anything
@@ -50,6 +52,9 @@
   /// FileEntry *.
   FileManager &FileMgr;
 
+  /// Cache of PCM files.
+  IntrusiveRefCntPtr<MemoryBufferCache> PCMCache;
+
   /// \brief Knows how to unwrap module containers.
   const PCHContainerReader &PCHContainerRdr;
 
@@ -111,12 +116,18 @@
   void returnVisitState(VisitState *State);
 
 public:
-  typedef SmallVectorImpl<ModuleFile*>::iterator ModuleIterator;
-  typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator;
-  typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator;
+  typedef llvm::pointee_iterator<
+      SmallVectorImpl<std::unique_ptr<ModuleFile>>::iterator>
+      ModuleIterator;
+  typedef llvm::pointee_iterator<
+      SmallVectorImpl<std::unique_ptr<ModuleFile>>::const_iterator>
+      ModuleConstIterator;
+  typedef llvm::pointee_iterator<
+      SmallVectorImpl<std::unique_ptr<ModuleFile>>::reverse_iterator>
+      ModuleReverseIterator;
   typedef std::pair<uint32_t, StringRef> ModuleOffset;
 
-  explicit ModuleManager(FileManager &FileMgr,
+  explicit ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
                          const PCHContainerReader &PCHContainerRdr);
   ~ModuleManager();
 
@@ -136,7 +147,8 @@
   ModuleReverseIterator rend() { return Chain.rend(); }
 
   /// \brief A range covering the PCH and preamble module files loaded.
-  llvm::iterator_range<ModuleConstIterator> pch_modules() const {
+  llvm::iterator_range<SmallVectorImpl<ModuleFile *>::const_iterator>
+  pch_modules() const {
     return llvm::make_range(PCHChain.begin(), PCHChain.end());
   }
 
@@ -220,8 +232,8 @@
                             ModuleFile *&Module,
                             std::string &ErrorStr);
 
-  /// \brief Remove the given set of modules.
-  void removeModules(ModuleIterator first, ModuleIterator last,
+  /// \brief Remove the modules starting from First (to the end).
+  void removeModules(ModuleIterator First,
                      llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
                      ModuleMap *modMap);
 
@@ -282,6 +294,8 @@
 
   /// \brief View the graphviz representation of the module graph.
   void viewGraph();
+
+  MemoryBufferCache &getPCMCache() const { return *PCMCache; }
 };
 
 } } // end namespace clang::serialization
diff --git a/include/clang/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 6957891..790ba5c 100644
--- a/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -45,7 +45,6 @@
 def CplusplusOptIn : Package<"cplusplus">, InPackage<OptIn>;
 
 def Valist : Package<"valist">;
-def ValistAlpha : Package<"valist">, InPackage<Alpha>, Hidden;
 
 def DeadCode : Package<"deadcode">;
 def DeadCodeAlpha : Package<"deadcode">, InPackage<Alpha>, Hidden;
@@ -280,6 +279,11 @@
 
 let ParentPackage = CplusplusAlpha in {
 
+def MisusedMovedObjectChecker: Checker<"MisusedMovedObject">,
+     HelpText<"Method calls on a moved-from object and copying a moved-from "
+              "object will be reported">,
+     DescFile<"MisusedMovedObjectChecker.cpp">;
+
 def IteratorPastEndChecker : Checker<"IteratorPastEnd">,
   HelpText<"Check iterators used past end">,
   DescFile<"IteratorPastEndChecker.cpp">;
@@ -291,7 +295,7 @@
 // Valist checkers.
 //===----------------------------------------------------------------------===//
 
-let ParentPackage = ValistAlpha in {
+let ParentPackage = Valist in {
 
 def UninitializedChecker : Checker<"Uninitialized">,
   HelpText<"Check for usages of uninitialized (or already released) va_lists.">,
@@ -305,7 +309,7 @@
   HelpText<"Check for va_lists which are copied onto itself.">,
   DescFile<"ValistChecker.cpp">;
 
-} // end : "alpha.valist"
+} // end : "valist"
 
 //===----------------------------------------------------------------------===//
 // Deadcode checkers.
diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def
index 3355f4b..04bf41b 100644
--- a/include/clang/StaticAnalyzer/Core/Analyses.def
+++ b/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -22,6 +22,7 @@
 #endif
 
 ANALYSIS_CONSTRAINTS(RangeConstraints, "range", "Use constraint tracking of concrete value ranges", CreateRangeConstraintManager)
+ANALYSIS_CONSTRAINTS(Z3Constraints, "z3", "Use Z3 contraint solver", CreateZ3ConstraintManager)
 
 #ifndef ANALYSIS_DIAGNOSTICS
 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
index 8df2bc3..0e80e7b 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
@@ -17,6 +17,7 @@
       extern const char * const CoreFoundationObjectiveC;
       extern const char * const LogicError;
       extern const char * const MemoryCoreFoundationObjectiveC;
+      extern const char * const MemoryError;
       extern const char * const UnixAPI;
     }
   }
diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h
index dd7a6c8..f947776 100644
--- a/include/clang/StaticAnalyzer/Core/Checker.h
+++ b/include/clang/StaticAnalyzer/Core/Checker.h
@@ -321,9 +321,11 @@
                       const InvalidatedSymbols *invalidated,
                       ArrayRef<const MemRegion *> Explicits,
                       ArrayRef<const MemRegion *> Regions,
+                      const LocationContext *LCtx,
                       const CallEvent *Call) {
-    return ((const CHECKER *)checker)->checkRegionChanges(state, invalidated,
-                                                      Explicits, Regions, Call);
+    return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
+                                                           Explicits, Regions,
+                                                           LCtx, Call);
   }
 
 public:
diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h
index 0316c8f..52ed260 100644
--- a/include/clang/StaticAnalyzer/Core/CheckerManager.h
+++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h
@@ -338,6 +338,7 @@
                               const InvalidatedSymbols *invalidated,
                               ArrayRef<const MemRegion *> ExplicitRegions,
                               ArrayRef<const MemRegion *> Regions,
+                              const LocationContext *LCtx,
                               const CallEvent *Call);
 
   /// \brief Run checkers when pointers escape.
@@ -443,10 +444,11 @@
   typedef CheckerFn<void (ProgramStateRef,SymbolReaper &)> CheckLiveSymbolsFunc;
   
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
-                                const InvalidatedSymbols *symbols,
-                                ArrayRef<const MemRegion *> ExplicitRegions,
-                                ArrayRef<const MemRegion *> Regions,
-                                const CallEvent *Call)>
+                                     const InvalidatedSymbols *symbols,
+                                     ArrayRef<const MemRegion *> ExplicitRegions,
+                                     ArrayRef<const MemRegion *> Regions,
+                                     const LocationContext *LCtx,
+                                     const CallEvent *Call)>
       CheckRegionChangesFunc;
   
   typedef CheckerFn<ProgramStateRef (ProgramStateRef,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
index 0d1a120..fb427f6 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
@@ -20,6 +20,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
 
 namespace clang {
 namespace ento {
@@ -29,8 +30,9 @@
   llvm::ImmutableList<SVal> L;
 
 public:
-  CompoundValData(QualType t, llvm::ImmutableList<SVal> l)
-    : T(t), L(l) {}
+  CompoundValData(QualType t, llvm::ImmutableList<SVal> l) : T(t), L(l) {
+    assert(NonLoc::isCompoundType(t));
+  }
 
   typedef llvm::ImmutableList<SVal>::iterator iterator;
   iterator begin() const { return L.begin(); }
@@ -47,7 +49,9 @@
   const TypedValueRegion *region;
 public:
   LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r)
-    : store(st), region(r) {}
+      : store(st), region(r) {
+    assert(NonLoc::isCompoundType(r->getValueType()));
+  }
 
   const void *getStore() const { return store.getStore(); }
   const TypedValueRegion *getRegion() const { return region; }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 89610ef..aaecf38 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -55,6 +55,7 @@
 class CallDescription {
   friend CallEvent;
   mutable IdentifierInfo *II;
+  mutable bool IsLookupDone;
   StringRef FuncName;
   unsigned RequiredArgs;
 
@@ -68,7 +69,8 @@
   /// call. Omit this parameter to match every occurance of call with a given
   /// name regardless the number of arguments.
   CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement)
-      : II(nullptr), FuncName(FuncName), RequiredArgs(RequiredArgs) {}
+      : II(nullptr), IsLookupDone(false), FuncName(FuncName),
+        RequiredArgs(RequiredArgs) {}
 
   /// \brief Get the name of the function that this object matches.
   StringRef getFunctionName() const { return FuncName; }
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
index 6651382..c01600d 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
@@ -139,6 +139,8 @@
     return nullptr;
   }
 
+  /// Scan all symbols referenced by the constraints. If the symbol is not
+  /// alive, remove it.
   virtual ProgramStateRef removeDeadBindings(ProgramStateRef state,
                                                  SymbolReaper& SymReaper) = 0;
 
@@ -182,6 +184,9 @@
 CreateRangeConstraintManager(ProgramStateManager &statemgr,
                              SubEngine *subengine);
 
+std::unique_ptr<ConstraintManager>
+CreateZ3ConstraintManager(ProgramStateManager &statemgr, SubEngine *subengine);
+
 } // end GR namespace
 
 } // end clang namespace
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 591b112..1a20074 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -293,6 +293,7 @@
                        const InvalidatedSymbols *invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) override;
 
   /// printState - Called by ProgramStateManager to print checker-specific data.
@@ -522,7 +523,9 @@
 
   /// Call PointerEscape callback when a value escapes as a result of bind.
   ProgramStateRef processPointerEscapedOnBind(ProgramStateRef State,
-                                              SVal Loc, SVal Val) override;
+                                              SVal Loc,
+                                              SVal Val,
+                                              const LocationContext *LCtx) override;
   /// Call PointerEscape callback when a value escapes as a result of
   /// region invalidation.
   /// \param[in] ITraits Specifies invalidation traits for regions/symbols.
@@ -618,16 +621,16 @@
   void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
                           const CallEvent &Call);
 
-  /// If the value of the given expression is a NonLoc, copy it into a new
-  /// temporary object region, and replace the value of the expression with
-  /// that.
+  /// If the value of the given expression \p InitWithAdjustments is a NonLoc,
+  /// copy it into a new temporary object region, and replace the value of the
+  /// expression with that.
   ///
-  /// If \p ResultE is provided, the new region will be bound to this expression
-  /// instead of \p E.
+  /// If \p Result is provided, the new region will be bound to this expression
+  /// instead of \p InitWithAdjustments.
   ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State,
                                                 const LocationContext *LC,
-                                                const Expr *E,
-                                                const Expr *ResultE = nullptr);
+                                                const Expr *InitWithAdjustments,
+                                                const Expr *Result = nullptr);
 
   /// For a DeclStmt or CXXInitCtorInitializer, walk backward in the current CFG
   /// block to find the constructor expression that directly constructed into
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index da4b964..29b1c4c 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -182,6 +182,7 @@
 
   MemSpaceRegion(MemRegionManager *mgr, Kind k) : MemRegion(k), Mgr(mgr) {
     assert(classof(this));
+    assert(mgr);
   }
 
   MemRegionManager* getMemRegionManager() const override { return Mgr; }
@@ -215,9 +216,12 @@
 
 class GlobalsSpaceRegion : public MemSpaceRegion {
   virtual void anchor();
+
 protected:
-  GlobalsSpaceRegion(MemRegionManager *mgr, Kind k)
-    : MemSpaceRegion(mgr, k) {}
+  GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) : MemSpaceRegion(mgr, k) {
+    assert(classof(this));
+  }
+
 public:
   static bool classof(const MemRegion *R) {
     Kind k = R->getKind();
@@ -236,7 +240,9 @@
   const CodeTextRegion *CR;
   
   StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr)
-    : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {}
+    : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {
+    assert(cr);
+  }
 
 public:
   void Profile(llvm::FoldingSetNodeID &ID) const override;
@@ -257,9 +263,13 @@
 /// RegionStoreManager::invalidateRegions (instead of finding all the dependent
 /// globals, we invalidate the whole parent region).
 class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion {
+  virtual void anchor() override;
+
 protected:
   NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k)
-    : GlobalsSpaceRegion(mgr, k) {}
+      : GlobalsSpaceRegion(mgr, k) {
+    assert(classof(this));
+  }
 
 public:
 
@@ -326,7 +336,6 @@
 };
 
 class HeapSpaceRegion : public MemSpaceRegion {
-  virtual void anchor();
   friend class MemRegionManager;
   
   HeapSpaceRegion(MemRegionManager *mgr)
@@ -341,10 +350,10 @@
 };
   
 class UnknownSpaceRegion : public MemSpaceRegion {
-  virtual void anchor();
   friend class MemRegionManager;
   UnknownSpaceRegion(MemRegionManager *mgr)
-    : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
+      : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {}
+
 public:
 
   void dumpToStream(raw_ostream &os) const override;
@@ -355,13 +364,15 @@
 };
 
 class StackSpaceRegion : public MemSpaceRegion {
-private:
+  virtual void anchor();
+
   const StackFrameContext *SFC;
 
 protected:
   StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc)
     : MemSpaceRegion(mgr, k), SFC(sfc) {
     assert(classof(this));
+    assert(sfc);
   }
 
 public:
@@ -376,7 +387,6 @@
 };
 
 class StackLocalsSpaceRegion : public StackSpaceRegion {
-  virtual void anchor();
   friend class MemRegionManager;
   StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
     : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {}
@@ -391,7 +401,6 @@
 
 class StackArgumentsSpaceRegion : public StackSpaceRegion {
 private:
-  virtual void anchor();
   friend class MemRegionManager;
   StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc)
     : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {}
@@ -408,11 +417,15 @@
 /// SubRegion - A region that subsets another larger region.  Most regions
 ///  are subclasses of SubRegion.
 class SubRegion : public MemRegion {
-private:
   virtual void anchor();
+
 protected:
   const MemRegion* superRegion;
-  SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {}
+  SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) {
+    assert(classof(this));
+    assert(sReg);
+  }
+
 public:
   const MemRegion* getSuperRegion() const {
     return superRegion;
@@ -440,13 +453,18 @@
 ///  by a call to 'alloca'.
 class AllocaRegion : public SubRegion {
   friend class MemRegionManager;
-protected:
+
   unsigned Cnt; // Block counter.  Used to distinguish different pieces of
                 // memory allocated by alloca at the same call site.
   const Expr *Ex;
 
-  AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion)
-    : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {}
+  AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
+      : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
+    assert(Ex);
+  }
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
+                            unsigned Cnt, const MemRegion *superRegion);
 
 public:
 
@@ -458,9 +476,6 @@
 
   void Profile(llvm::FoldingSetNodeID& ID) const override;
 
-  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex,
-                            unsigned Cnt, const MemRegion *superRegion);
-
   void dumpToStream(raw_ostream &os) const override;
 
   static bool classof(const MemRegion* R) {
@@ -470,10 +485,12 @@
 
 /// TypedRegion - An abstract class representing regions that are typed.
 class TypedRegion : public SubRegion {
-public:
-  void anchor() override;
+  virtual void anchor() override;
+
 protected:
-  TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
+  TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) {
+    assert(classof(this));
+  }
 
 public:
   virtual QualType getLocationType() const = 0;
@@ -492,10 +509,12 @@
 
 /// TypedValueRegion - An abstract class representing regions having a typed value.
 class TypedValueRegion : public TypedRegion {
-public:
-  void anchor() override;
+  virtual void anchor() override;
+
 protected:
-  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {}
+  TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {
+    assert(classof(this));
+  }
 
 public:
   virtual QualType getValueType() const = 0;
@@ -524,10 +543,13 @@
 
 
 class CodeTextRegion : public TypedRegion {
-public:
-  void anchor() override;
+  virtual void anchor() override;
+
 protected:
-  CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {}
+  CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
+    assert(classof(this));
+  }
+
 public:
   bool isBoundable() const override { return false; }
 
@@ -539,13 +561,19 @@
 
 /// FunctionCodeRegion - A region that represents code texts of function.
 class FunctionCodeRegion : public CodeTextRegion {
+  friend class MemRegionManager;
+
   const NamedDecl *FD;
-public:
-  FunctionCodeRegion(const NamedDecl *fd, const MemRegion* sreg)
+
+  FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
     : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
     assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
   }
 
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
+                            const MemRegion*);
+
+public:
   QualType getLocationType() const override {
     const ASTContext &Ctx = getContext();
     if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) {
@@ -568,9 +596,6 @@
 
   void Profile(llvm::FoldingSetNodeID& ID) const override;
 
-  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD,
-                            const MemRegion*);
-  
   static bool classof(const MemRegion* R) {
     return R->getKind() == FunctionCodeRegionKind;
   }
@@ -591,8 +616,16 @@
   CanQualType locTy;
 
   BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
-                  AnalysisDeclContext *ac, const MemRegion* sreg)
-    : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {}
+                  AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
+      : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
+    assert(bd);
+    assert(ac);
+    assert(lTy->getTypePtr()->isBlockPointerType());
+  }
+
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
+                            CanQualType, const AnalysisDeclContext*,
+                            const MemRegion*);
 
 public:
   QualType getLocationType() const override {
@@ -609,10 +642,6 @@
 
   void Profile(llvm::FoldingSetNodeID& ID) const override;
 
-  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD,
-                            CanQualType, const AnalysisDeclContext*,
-                            const MemRegion*);
-  
   static bool classof(const MemRegion* R) {
     return R->getKind() == BlockCodeRegionKind;
   }
@@ -626,6 +655,7 @@
 ///  variables.
 class BlockDataRegion : public TypedRegion {
   friend class MemRegionManager;
+
   const BlockCodeRegion *BC;
   const LocationContext *LC; // Can be null */
   unsigned BlockCount;
@@ -633,10 +663,19 @@
   void *OriginalVars;
 
   BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
-                  unsigned count, const MemRegion *sreg)
-  : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
-     BlockCount(count),
-    ReferencedVars(nullptr), OriginalVars(nullptr) {}
+                  unsigned count, const MemSpaceRegion *sreg)
+      : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
+        BlockCount(count), ReferencedVars(nullptr), OriginalVars(nullptr) {
+    assert(bc);
+    assert(lc);
+    assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
+           isa<StackLocalsSpaceRegion>(sreg) ||
+           isa<UnknownSpaceRegion>(sreg));
+  }
+
+  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
+                            const LocationContext *, unsigned,
+                            const MemRegion *);
 
 public:
   const BlockCodeRegion *getCodeRegion() const { return BC; }
@@ -686,10 +725,6 @@
 
   void Profile(llvm::FoldingSetNodeID& ID) const override;
 
-  static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
-                            const LocationContext *, unsigned,
-                            const MemRegion *);
-    
   static bool classof(const MemRegion* R) {
     return R->getKind() == BlockDataRegionKind;
   }
@@ -705,13 +740,20 @@
 ///  map the concept of symbolic values into the domain of regions.  Symbolic
 ///  regions do not need to be typed.
 class SymbolicRegion : public SubRegion {
-protected:
+  friend class MemRegionManager;
+
   const SymbolRef sym;
 
-public:
-  SymbolicRegion(const SymbolRef s, const MemRegion* sreg)
-    : SubRegion(sreg, SymbolicRegionKind), sym(s) {}
+  SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
+      : SubRegion(sreg, SymbolicRegionKind), sym(s) {
+    assert(s);
+    assert(s->getType()->isAnyPointerType() ||
+           s->getType()->isReferenceType() ||
+           s->getType()->isBlockPointerType());
+    assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
+  }
 
+public:
   SymbolRef getSymbol() const {
     return sym;
   }
@@ -736,11 +778,13 @@
 /// StringRegion - Region associated with a StringLiteral.
 class StringRegion : public TypedValueRegion {
   friend class MemRegionManager;
-  const StringLiteral* Str;
-protected:
 
-  StringRegion(const StringLiteral* str, const MemRegion* sreg)
-    : TypedValueRegion(sreg, StringRegionKind), Str(str) {}
+  const StringLiteral* Str;
+
+  StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
+      : TypedValueRegion(sreg, StringRegionKind), Str(str) {
+    assert(str);
+  }
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
                             const StringLiteral* Str,
@@ -772,12 +816,15 @@
 /// The region associated with an ObjCStringLiteral.
 class ObjCStringRegion : public TypedValueRegion {
   friend class MemRegionManager;
+
   const ObjCStringLiteral* Str;
-protected:
-  
-  ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg)
-  : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {}
-  
+
+  ObjCStringRegion(const ObjCStringLiteral *str,
+                   const GlobalInternalSpaceRegion *sreg)
+      : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
+    assert(str);
+  }
+
   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
                             const ObjCStringLiteral* Str,
                             const MemRegion* superRegion);
@@ -807,12 +854,17 @@
 ///   Compound literals are essentially temporaries that are stack allocated
 ///   or in the global constant pool.
 class CompoundLiteralRegion : public TypedValueRegion {
-private:
   friend class MemRegionManager;
+
   const CompoundLiteralExpr *CL;
 
-  CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg)
-    : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {}
+  CompoundLiteralRegion(const CompoundLiteralExpr *cl,
+                        const MemSpaceRegion *sReg)
+      : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
+    assert(cl);
+    assert(isa<GlobalInternalSpaceRegion>(sReg) ||
+           isa<StackLocalsSpaceRegion>(sReg));
+  }
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
                             const CompoundLiteralExpr *CL,
@@ -839,8 +891,11 @@
 protected:
   const Decl *D;
 
-  DeclRegion(const Decl *d, const MemRegion* sReg, Kind k)
-    : TypedValueRegion(sReg, k), D(d) {}
+  DeclRegion(const Decl *d, const MemRegion *sReg, Kind k)
+      : TypedValueRegion(sReg, k), D(d) {
+    assert(classof(this));
+    assert(d);
+  }
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D,
                       const MemRegion* superRegion, Kind k);
@@ -859,17 +914,24 @@
   friend class MemRegionManager;
 
   // Constructors and private methods.
-  VarRegion(const VarDecl *vd, const MemRegion* sReg)
-    : DeclRegion(vd, sReg, VarRegionKind) {}
+  VarRegion(const VarDecl *vd, const MemRegion *sReg)
+      : DeclRegion(vd, sReg, VarRegionKind) {
+    // VarRegion appears in unknown space when it's a block variable as seen
+    // from a block using it, when this block is analyzed at top-level.
+    // Other block variables appear within block data regions,
+    // which, unlike everything else on this list, are not memory spaces.
+    assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
+           isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
+  }
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
                             const MemRegion *superRegion) {
     DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind);
   }
 
+public:
   void Profile(llvm::FoldingSetNodeID& ID) const override;
 
-public:
   const VarDecl *getDecl() const { return cast<VarDecl>(D); }
 
   const StackFrameContext *getStackFrame() const;
@@ -895,17 +957,19 @@
 ///  referred to by 'this', but rather 'this' itself.
 class CXXThisRegion : public TypedValueRegion {
   friend class MemRegionManager;
+
   CXXThisRegion(const PointerType *thisPointerTy,
-                const MemRegion *sReg)
-    : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {}
+                const StackArgumentsSpaceRegion *sReg)
+      : TypedValueRegion(sReg, CXXThisRegionKind),
+        ThisPointerTy(thisPointerTy) {}
 
   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
                             const PointerType *PT,
                             const MemRegion *sReg);
 
+public:
   void Profile(llvm::FoldingSetNodeID &ID) const override;
 
-public:
   QualType getValueType() const override {
     return QualType(ThisPointerTy, 0);
   }
@@ -923,9 +987,14 @@
 class FieldRegion : public DeclRegion {
   friend class MemRegionManager;
 
-  FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
+  FieldRegion(const FieldDecl *fd, const SubRegion* sReg)
     : DeclRegion(fd, sReg, FieldRegionKind) {}
 
+  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
+                            const MemRegion* superRegion) {
+    DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
+  }
+
 public:
   const FieldDecl *getDecl() const { return cast<FieldDecl>(D); }
 
@@ -936,11 +1005,6 @@
 
   DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override;
 
-  static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
-                            const MemRegion* superRegion) {
-    DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind);
-  }
-
   static bool classof(const MemRegion* R) {
     return R->getKind() == FieldRegionKind;
   }
@@ -954,10 +1018,9 @@
 };
 
 class ObjCIvarRegion : public DeclRegion {
-
   friend class MemRegionManager;
 
-  ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
+  ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
                             const MemRegion* superRegion);
@@ -982,7 +1045,6 @@
 class ElementRegion;
 
 class RegionRawOffset {
-private:
   friend class ElementRegion;
 
   const MemRegion *Region;
@@ -1007,9 +1069,9 @@
   QualType ElementType;
   NonLoc Index;
 
-  ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
-    : TypedValueRegion(sReg, ElementRegionKind),
-      ElementType(elementType), Index(Idx) {
+  ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
+      : TypedValueRegion(sReg, ElementRegionKind),
+        ElementType(elementType), Index(Idx) {
     assert((!Idx.getAs<nonloc::ConcreteInt>() ||
             Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
            "The index must be signed");
@@ -1047,12 +1109,16 @@
 
   Expr const *Ex;
 
-  CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) 
-    : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {}
+  CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
+      : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
+    assert(E);
+    assert(isa<StackLocalsSpaceRegion>(sReg) ||
+           isa<GlobalInternalSpaceRegion>(sReg));
+  }
 
   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
                             Expr const *E, const MemRegion *sReg);
-  
+
 public:
   const Expr *getExpr() const { return Ex; }
 
@@ -1077,8 +1143,10 @@
   llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
 
   CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
-                      const MemRegion *SReg)
-    : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {}
+                      const SubRegion *SReg)
+      : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
+    assert(RD);
+  }
 
   static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD,
                             bool IsVirtual, const MemRegion *SReg);
@@ -1204,16 +1272,16 @@
 
   /// getVarRegion - Retrieve or create the memory region associated with
   ///  a specified VarDecl and super region.
-  const VarRegion* getVarRegion(const VarDecl *D, const MemRegion *superR);
-  
+  const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR);
+
   /// getElementRegion - Retrieve the memory region associated with the
   ///  associated element type, index, and super region.
   const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
-                                        const MemRegion *superRegion,
+                                        const SubRegion *superRegion,
                                         ASTContext &Ctx);
 
   const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
-                                                 const MemRegion *superRegion) {
+                                                 const SubRegion *superRegion) {
     return getElementRegion(ER->getElementType(), ER->getIndex(),
                             superRegion, ER->getContext());
   }
@@ -1223,10 +1291,10 @@
   ///  memory region (which typically represents the memory representing
   ///  a structure or class).
   const FieldRegion *getFieldRegion(const FieldDecl *fd,
-                                    const MemRegion* superRegion);
+                                    const SubRegion* superRegion);
 
   const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
-                                             const MemRegion *superRegion) {
+                                             const SubRegion *superRegion) {
     return getFieldRegion(FR->getDecl(), superRegion);
   }
 
@@ -1235,7 +1303,7 @@
   ///   to the containing region (which typically represents the Objective-C
   ///   object).
   const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
-                                          const MemRegion* superRegion);
+                                          const SubRegion* superRegion);
 
   const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
                                                     LocationContext const *LC);
@@ -1245,14 +1313,14 @@
   ///
   /// The type of \p Super is assumed be a class deriving from \p BaseClass.
   const CXXBaseObjectRegion *
-  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super,
+  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
                          bool IsVirtual);
 
   /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
   /// super region.
   const CXXBaseObjectRegion *
   getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 
-                                  const MemRegion *superRegion) {
+                                  const SubRegion *superRegion) {
     return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
                                   baseReg->isVirtual());
   }
@@ -1276,17 +1344,22 @@
   const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
 
 private:
-  template <typename RegionTy, typename A1>
-  RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
+  template <typename RegionTy, typename SuperTy,
+            typename Arg1Ty>
+  RegionTy* getSubRegion(const Arg1Ty arg1,
+                         const SuperTy* superRegion);
 
-  template <typename RegionTy, typename A1, typename A2>
-  RegionTy* getSubRegion(const A1 a1, const A2 a2,
-                         const MemRegion* superRegion);
+  template <typename RegionTy, typename SuperTy,
+            typename Arg1Ty, typename Arg2Ty>
+  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+                         const SuperTy* superRegion);
 
-  template <typename RegionTy, typename A1, typename A2, typename A3>
-  RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
-                         const MemRegion* superRegion);
-  
+  template <typename RegionTy, typename SuperTy,
+            typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
+  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+                         const Arg3Ty arg3,
+                         const SuperTy* superRegion);
+
   template <typename REG>
   const REG* LazyAllocate(REG*& region);
   
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
index 463b375..2910ef4 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
@@ -229,11 +229,12 @@
 
   ProgramStateRef bindLoc(Loc location,
                           SVal V,
+                          const LocationContext *LCtx,
                           bool notifyChanges = true) const;
 
-  ProgramStateRef bindLoc(SVal location, SVal V) const;
+  ProgramStateRef bindLoc(SVal location, SVal V, const LocationContext *LCtx) const;
 
-  ProgramStateRef bindDefault(SVal loc, SVal V) const;
+  ProgramStateRef bindDefault(SVal loc, SVal V, const LocationContext *LCtx) const;
 
   ProgramStateRef killBinding(Loc LV) const;
 
@@ -681,9 +682,9 @@
       this, Val.castAs<NonLoc>(), From, To);
 }
 
-inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V) const {
+inline ProgramStateRef ProgramState::bindLoc(SVal LV, SVal V, const LocationContext *LCtx) const {
   if (Optional<Loc> L = LV.getAs<Loc>())
-    return bindLoc(*L, V);
+    return bindLoc(*L, V, LCtx);
   return this;
 }
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
index a4c01fc..14aa3af 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h
@@ -112,6 +112,11 @@
   /// Evaluates a given SVal. If the SVal has only one possible (integer) value,
   /// that value is returned. Otherwise, returns NULL.
   virtual const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal val) = 0;
+
+  /// Simplify symbolic expressions within a given SVal. Return an SVal
+  /// that represents the same value, but is hopefully easier to work with
+  /// than the original SVal.
+  virtual SVal simplifySVal(ProgramStateRef State, SVal Val) = 0;
   
   /// Constructs a symbolic expression for two non-location values.
   SVal makeSymExprValNN(ProgramStateRef state, BinaryOperator::Opcode op,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index cc3c02a..935f001 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -41,6 +41,22 @@
 class ProgramStateManager;
 class SValBuilder;
 
+namespace nonloc {
+/// Sub-kinds for NonLoc values.
+enum Kind {
+#define NONLOC_SVAL(Id, Parent) Id ## Kind,
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
+};
+}
+
+namespace loc {
+/// Sub-kinds for Loc values.
+enum Kind {
+#define LOC_SVAL(Id, Parent) Id ## Kind,
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
+};
+}
+
 /// SVal - This represents a symbolic expression, which can be either
 ///  an L-value or an R-value.
 ///
@@ -75,10 +91,7 @@
   template<typename T>
   T castAs() const {
     assert(T::isKind(*this));
-    T t;
-    SVal& sv = t;
-    sv = *this;
-    return t;
+    return *static_cast<const T *>(this);
   }
 
   /// \brief Convert to the specified SVal type, returning None if this SVal is
@@ -87,10 +100,7 @@
   Optional<T> getAs() const {
     if (!T::isKind(*this))
       return None;
-    T t;
-    SVal& sv = t;
-    sv = *this;
-    return t;
+    return *static_cast<const T *>(this);
   }
 
   /// BufferTy - A temporary buffer to hold a set of SVals.
@@ -273,6 +283,11 @@
 public:
   void dumpToStream(raw_ostream &Out) const;
 
+  static inline bool isCompoundType(QualType T) {
+    return T->isArrayType() || T->isRecordType() ||
+           T->isComplexType() || T->isVectorType();
+  }
+
 private:
   friend class SVal;
   static bool isKind(const SVal& V) {
@@ -307,15 +322,11 @@
 
 namespace nonloc {
 
-enum Kind {
-#define NONLOC_SVAL(Id, Parent) Id ## Kind,
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
-};
-
 /// \brief Represents symbolic expression.
 class SymbolVal : public NonLoc {
 public:
-  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {}
+  SymbolVal() = delete;
+  SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) { assert(sym); }
 
   SymbolRef getSymbol() const {
     return (const SymExpr*) Data;
@@ -327,7 +338,6 @@
 
 private:
   friend class SVal;
-  SymbolVal() {}
   static bool isKind(const SVal& V) {
     return V.getBaseKind() == NonLocKind &&
            V.getSubKind() == SymbolValKind;
@@ -373,7 +383,11 @@
 
   explicit LocAsInteger(const std::pair<SVal, uintptr_t> &data)
       : NonLoc(LocAsIntegerKind, &data) {
-    assert (data.first.getAs<Loc>());
+    // We do not need to represent loc::ConcreteInt as LocAsInteger,
+    // as it'd collapse into a nonloc::ConcreteInt instead.
+    assert(data.first.getBaseKind() == LocKind &&
+           (data.first.getSubKind() == loc::MemRegionValKind ||
+            data.first.getSubKind() == loc::GotoLabelKind));
   }
 
 public:
@@ -513,14 +527,11 @@
 
 namespace loc {
 
-enum Kind {
-#define LOC_SVAL(Id, Parent) Id ## Kind,
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
-};
-
 class GotoLabel : public Loc {
 public:
-  explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {}
+  explicit GotoLabel(const LabelDecl *Label) : Loc(GotoLabelKind, Label) {
+    assert(Label);
+  }
 
   const LabelDecl *getLabel() const {
     return static_cast<const LabelDecl*>(Data);
@@ -541,7 +552,9 @@
 
 class MemRegionVal : public Loc {
 public:
-  explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionValKind, r) {}
+  explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionValKind, r) {
+    assert(r);
+  }
 
   /// \brief Get the underlining region.
   const MemRegion* getRegion() const {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
new file mode 100644
index 0000000..2c9802b
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h
@@ -0,0 +1,92 @@
+//== SimpleConstraintManager.h ----------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Simplified constraint manager backend.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SIMPLECONSTRAINTMANAGER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SIMPLECONSTRAINTMANAGER_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+
+namespace clang {
+
+namespace ento {
+
+class SimpleConstraintManager : public ConstraintManager {
+  SubEngine *SU;
+  SValBuilder &SVB;
+
+public:
+  SimpleConstraintManager(SubEngine *subengine, SValBuilder &SB)
+      : SU(subengine), SVB(SB) {}
+
+  ~SimpleConstraintManager() override;
+
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from ConstraintManager.
+  //===------------------------------------------------------------------===//
+
+  /// Ensures that the DefinedSVal conditional is expressed as a NonLoc by
+  /// creating boolean casts to handle Loc's.
+  ProgramStateRef assume(ProgramStateRef State, DefinedSVal Cond,
+                         bool Assumption) override;
+
+  ProgramStateRef assumeInclusiveRange(ProgramStateRef State, NonLoc Value,
+                                       const llvm::APSInt &From,
+                                       const llvm::APSInt &To,
+                                       bool InRange) override;
+
+protected:
+  //===------------------------------------------------------------------===//
+  // Interface that subclasses must implement.
+  //===------------------------------------------------------------------===//
+
+  /// Given a symbolic expression that can be reasoned about, assume that it is
+  /// true/false and generate the new program state.
+  virtual ProgramStateRef assumeSym(ProgramStateRef State, SymbolRef Sym,
+                                    bool Assumption) = 0;
+
+  /// Given a symbolic expression within the range [From, To], assume that it is
+  /// true/false and generate the new program state.
+  /// This function is used to handle case ranges produced by a language
+  /// extension for switch case statements.
+  virtual ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State,
+                                                  SymbolRef Sym,
+                                                  const llvm::APSInt &From,
+                                                  const llvm::APSInt &To,
+                                                  bool InRange) = 0;
+
+  /// Given a symbolic expression that cannot be reasoned about, assume that
+  /// it is zero/nonzero and add it directly to the solver state.
+  virtual ProgramStateRef assumeSymUnsupported(ProgramStateRef State,
+                                               SymbolRef Sym,
+                                               bool Assumption) = 0;
+
+  //===------------------------------------------------------------------===//
+  // Internal implementation.
+  //===------------------------------------------------------------------===//
+
+  BasicValueFactory &getBasicVals() const { return SVB.getBasicValueFactory(); }
+  SymbolManager &getSymbolManager() const { return SVB.getSymbolManager(); }
+
+private:
+  ProgramStateRef assume(ProgramStateRef State, NonLoc Cond, bool Assumption);
+
+  ProgramStateRef assumeAux(ProgramStateRef State, NonLoc Cond,
+                            bool Assumption);
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index fa7d3f7..7619f22 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -59,6 +59,30 @@
   /// \return The value bound to the location \c loc.
   virtual SVal getBinding(Store store, Loc loc, QualType T = QualType()) = 0;
 
+  /// Return the default value bound to a region in a given store. The default
+  /// binding is the value of sub-regions that were not initialized separately
+  /// from their base region. For example, if the structure is zero-initialized
+  /// upon construction, this method retrieves the concrete zero value, even if
+  /// some or all fields were later overwritten manually. Default binding may be
+  /// an unknown, undefined, concrete, or symbolic value.
+  /// \param[in] store The store in which to make the lookup.
+  /// \param[in] R The region to find the default binding for.
+  /// \return The default value bound to the region in the store, if a default
+  /// binding exists.
+  virtual Optional<SVal> getDefaultBinding(Store store, const MemRegion *R) = 0;
+
+  /// Return the default value bound to a LazyCompoundVal. The default binding
+  /// is used to represent the value of any fields or elements within the
+  /// structure represented by the LazyCompoundVal which were not initialized
+  /// explicitly separately from the whole structure. Default binding may be an
+  /// unknown, undefined, concrete, or symbolic value.
+  /// \param[in] lcv The lazy compound value.
+  /// \return The default value bound to the LazyCompoundVal \c lcv, if a
+  /// default binding exists.
+  Optional<SVal> getDefaultBinding(nonloc::LazyCompoundVal lcv) {
+    return getDefaultBinding(lcv.getStore(), lcv.getRegion());
+  }
+
   /// Return a state with the specified value bound to the given location.
   /// \param[in] store The analysis state.
   /// \param[in] loc The symbolic memory location.
@@ -136,7 +160,7 @@
   /// valid only if Failed flag is set to false.
   SVal attemptDownCast(SVal Base, QualType DerivedPtrType, bool &Failed);
 
-  const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
+  const ElementRegion *GetElementZeroRegion(const SubRegion *R, QualType T);
 
   /// castRegion - Used by ExprEngine::VisitCast to handle casts from
   ///  a MemRegion* to a specific location type.  'R' is the region being
@@ -235,8 +259,9 @@
   virtual void iterBindings(Store store, BindingsHandler& f) = 0;
 
 protected:
-  const MemRegion *MakeElementRegion(const MemRegion *baseRegion,
-                                     QualType pointeeTy, uint64_t index = 0);
+  const ElementRegion *MakeElementRegion(const SubRegion *baseRegion,
+                                         QualType pointeeTy,
+                                         uint64_t index = 0);
 
   /// CastRetrievedVal - Used by subclasses of StoreManager to implement
   ///  implicit casts that arise from loads from regions that are reinterpreted
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
index 581ef20..e16df13 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h
@@ -131,17 +131,19 @@
                        const InvalidatedSymbols *invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) = 0;
 
 
   inline ProgramStateRef 
   processRegionChange(ProgramStateRef state,
-                      const MemRegion* MR) {
-    return processRegionChanges(state, nullptr, MR, MR, nullptr);
+                      const MemRegion* MR,
+                      const LocationContext *LCtx) {
+    return processRegionChanges(state, nullptr, MR, MR, LCtx, nullptr);
   }
 
   virtual ProgramStateRef
-  processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val) = 0;
+  processPointerEscapedOnBind(ProgramStateRef State, SVal Loc, SVal Val, const LocationContext *LCtx) = 0;
 
   virtual ProgramStateRef
   notifyCheckersOfPointerEscape(ProgramStateRef State,
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
index 18bc607..f720339 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
@@ -42,6 +42,12 @@
 protected:
   SymExpr(Kind k) : K(k) {}
 
+  static bool isValidTypeForSymbol(QualType T) {
+    // FIXME: Depending on whether we choose to deprecate structural symbols,
+    // this may become much stricter.
+    return !T.isNull() && !T->isVoidType();
+  }
+
 public:
   virtual ~SymExpr() {}
 
@@ -103,7 +109,9 @@
   const SymbolID Sym;
 
 protected:
-  SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {}
+  SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {
+    assert(classof(this));
+  }
 
 public:
   ~SymbolData() override {}
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index f00dce5..e970114 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -44,7 +44,10 @@
 
 public:
   SymbolRegionValue(SymbolID sym, const TypedValueRegion *r)
-    : SymbolData(SymbolRegionValueKind, sym), R(r) {}
+      : SymbolData(SymbolRegionValueKind, sym), R(r) {
+    assert(r);
+    assert(isValidTypeForSymbol(r->getValueType()));
+  }
 
   const TypedValueRegion* getRegion() const { return R; }
 
@@ -81,7 +84,15 @@
   SymbolConjured(SymbolID sym, const Stmt *s, const LocationContext *lctx,
                  QualType t, unsigned count, const void *symbolTag)
       : SymbolData(SymbolConjuredKind, sym), S(s), T(t), Count(count),
-        LCtx(lctx), SymbolTag(symbolTag) {}
+        LCtx(lctx), SymbolTag(symbolTag) {
+    // FIXME: 's' might be a nullptr if we're conducting invalidation
+    // that was caused by a destructor call on a temporary object,
+    // which has no statement associated with it.
+    // Due to this, we might be creating the same invalidation symbol for
+    // two different invalidation passes (for two different temporaries).
+    assert(lctx);
+    assert(isValidTypeForSymbol(t));
+  }
 
   const Stmt *getStmt() const { return S; }
   unsigned getCount() const { return Count; }
@@ -120,7 +131,11 @@
 
 public:
   SymbolDerived(SymbolID sym, SymbolRef parent, const TypedValueRegion *r)
-    : SymbolData(SymbolDerivedKind, sym), parentSymbol(parent), R(r) {}
+      : SymbolData(SymbolDerivedKind, sym), parentSymbol(parent), R(r) {
+    assert(parent);
+    assert(r);
+    assert(isValidTypeForSymbol(r->getValueType()));
+  }
 
   SymbolRef getParentSymbol() const { return parentSymbol; }
   const TypedValueRegion *getRegion() const { return R; }
@@ -155,7 +170,9 @@
   
 public:
   SymbolExtent(SymbolID sym, const SubRegion *r)
-  : SymbolData(SymbolExtentKind, sym), R(r) {}
+      : SymbolData(SymbolExtentKind, sym), R(r) {
+    assert(r);
+  }
 
   const SubRegion *getRegion() const { return R; }
 
@@ -193,7 +210,13 @@
   SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t,
                  const LocationContext *LCtx, unsigned count, const void *tag)
   : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), LCtx(LCtx),
-    Count(count), Tag(tag) {}
+    Count(count), Tag(tag) {
+      assert(r);
+      assert(s);
+      assert(isValidTypeForSymbol(t));
+      assert(LCtx);
+      assert(tag);
+    }
 
   const MemRegion *getRegion() const { return R; }
   const Stmt *getStmt() const { return S; }
@@ -236,8 +259,13 @@
   QualType ToTy;
 
 public:
-  SymbolCast(const SymExpr *In, QualType From, QualType To) :
-    SymExpr(SymbolCastKind), Operand(In), FromTy(From), ToTy(To) { }
+  SymbolCast(const SymExpr *In, QualType From, QualType To)
+      : SymExpr(SymbolCastKind), Operand(In), FromTy(From), ToTy(To) {
+    assert(In);
+    assert(isValidTypeForSymbol(From));
+    // FIXME: GenericTaintChecker creates symbols of void type.
+    // Otherwise, 'To' should also be a valid type.
+  }
 
   QualType getType() const override { return ToTy; }
 
@@ -270,7 +298,10 @@
 
 protected:
   BinarySymExpr(Kind k, BinaryOperator::Opcode op, QualType t)
-    : SymExpr(k), Op(op), T(t) {}
+      : SymExpr(k), Op(op), T(t) {
+    assert(classof(this));
+    assert(isValidTypeForSymbol(t));
+  }
 
 public:
   // FIXME: We probably need to make this out-of-line to avoid redundant
@@ -293,8 +324,10 @@
 
 public:
   SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
-             const llvm::APSInt& rhs, QualType t)
-    : BinarySymExpr(SymIntExprKind, op, t), LHS(lhs), RHS(rhs) {}
+             const llvm::APSInt &rhs, QualType t)
+      : BinarySymExpr(SymIntExprKind, op, t), LHS(lhs), RHS(rhs) {
+    assert(lhs);
+  }
 
   void dumpToStream(raw_ostream &os) const override;
 
@@ -327,9 +360,11 @@
   const SymExpr *RHS;
 
 public:
-  IntSymExpr(const llvm::APSInt& lhs, BinaryOperator::Opcode op,
+  IntSymExpr(const llvm::APSInt &lhs, BinaryOperator::Opcode op,
              const SymExpr *rhs, QualType t)
-    : BinarySymExpr(IntSymExprKind, op, t), LHS(lhs), RHS(rhs) {}
+      : BinarySymExpr(IntSymExprKind, op, t), LHS(lhs), RHS(rhs) {
+    assert(rhs);
+  }
 
   void dumpToStream(raw_ostream &os) const override;
 
@@ -364,7 +399,10 @@
 public:
   SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs,
              QualType t)
-    : BinarySymExpr(SymSymExprKind, op, t), LHS(lhs), RHS(rhs) {}
+      : BinarySymExpr(SymSymExprKind, op, t), LHS(lhs), RHS(rhs) {
+    assert(lhs);
+    assert(rhs);
+  }
 
   const SymExpr *getLHS() const { return LHS; }
   const SymExpr *getRHS() const { return RHS; }
diff --git a/lib/APINotes/APINotesFormat.h b/lib/APINotes/APINotesFormat.h
new file mode 100644
index 0000000..3e1b2d5
--- /dev/null
+++ b/lib/APINotes/APINotesFormat.h
@@ -0,0 +1,308 @@
+//===--- APINotesFormat.h - The internals of API notes files ----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Contains various constants and helper types to deal with API notes
+/// files.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_API_NOTES_FORMAT_H
+#define LLVM_CLANG_API_NOTES_FORMAT_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/PointerEmbeddedInt.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Bitcode/RecordLayout.h"
+
+namespace clang {
+namespace api_notes {
+
+using namespace llvm;
+
+/// Magic number for API notes files.
+const unsigned char API_NOTES_SIGNATURE[] = { 0xE2, 0x9C, 0xA8, 0x01 };
+
+/// API notes file major version number.
+///
+const uint16_t VERSION_MAJOR = 0;
+
+/// API notes file minor version number.
+///
+/// When the format changes IN ANY WAY, this number should be incremented.
+const uint16_t VERSION_MINOR = 24;  // EnumExtensibility+FlagEnum
+
+using IdentifierID = PointerEmbeddedInt<unsigned, 31>;
+using IdentifierIDField = BCVBR<16>;
+
+using SelectorID = PointerEmbeddedInt<unsigned, 31>;
+using SelectorIDField = BCVBR<16>;
+
+using StoredContextID = PointerEmbeddedInt<unsigned, 31>;
+
+/// The various types of blocks that can occur within a API notes file.
+///
+/// These IDs must \em not be renumbered or reordered without incrementing
+/// VERSION_MAJOR.
+enum BlockID {
+  /// The control block, which contains all of the information that needs to
+  /// be validated prior to committing to loading the API notes file.
+  ///
+  /// \sa control_block
+  CONTROL_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+
+  /// The identifier data block, which maps identifier strings to IDs.
+  IDENTIFIER_BLOCK_ID,
+
+  /// The Objective-C context data block, which contains information about
+  /// Objective-C classes and protocols.
+  OBJC_CONTEXT_BLOCK_ID,
+
+  /// The Objective-C property data block, which maps Objective-C
+  /// (class name, property name) pairs to information about the
+  /// property.
+  OBJC_PROPERTY_BLOCK_ID,
+
+  /// The Objective-C property data block, which maps Objective-C
+  /// (class name, selector, is_instance_method) tuples to information
+  /// about the method.
+  OBJC_METHOD_BLOCK_ID,
+
+  /// The Objective-C selector data block, which maps Objective-C
+  /// selector names (# of pieces, identifier IDs) to the selector ID
+  /// used in other tables.
+  OBJC_SELECTOR_BLOCK_ID,
+
+  /// The global variables data block, which maps global variable names to
+  /// information about the global variable.
+  GLOBAL_VARIABLE_BLOCK_ID,
+
+  /// The (global) functions data block, which maps global function names to
+  /// information about the global function.
+  GLOBAL_FUNCTION_BLOCK_ID,
+
+  /// The tag data block, which maps tag names to information about
+  /// the tags.
+  TAG_BLOCK_ID,
+
+  /// The typedef data block, which maps typedef names to information about
+  /// the typedefs.
+  TYPEDEF_BLOCK_ID,
+
+  /// The enum constant data block, which maps enumerator names to
+  /// information about the enumerators.
+  ENUM_CONSTANT_BLOCK_ID,
+};
+
+namespace control_block {
+  // These IDs must \em not be renumbered or reordered without incrementing
+  // VERSION_MAJOR.
+  enum {
+    METADATA = 1,
+    MODULE_NAME = 2,
+    MODULE_OPTIONS = 3,
+    SOURCE_FILE = 4,
+  };
+
+  using MetadataLayout = BCRecordLayout<
+    METADATA, // ID
+    BCFixed<16>, // Module format major version
+    BCFixed<16>  // Module format minor version
+  >;
+
+  using ModuleNameLayout = BCRecordLayout<
+    MODULE_NAME,
+    BCBlob       // Module name
+  >;
+
+  using ModuleOptionsLayout = BCRecordLayout<
+    MODULE_OPTIONS,
+    BCFixed<1> // SwiftInferImportAsMember
+  >;
+
+  using SourceFileLayout = BCRecordLayout<
+    SOURCE_FILE,
+    BCVBR<16>, // file size
+    BCVBR<16>  // creation time
+  >;
+}
+
+namespace identifier_block {
+  enum {
+    IDENTIFIER_DATA = 1,
+  };
+
+  using IdentifierDataLayout = BCRecordLayout<
+    IDENTIFIER_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from identifier strings to decl kinds / decl IDs
+  >;
+}
+
+namespace objc_context_block {
+  enum {
+    OBJC_CONTEXT_ID_DATA = 1,
+    OBJC_CONTEXT_INFO_DATA = 2,
+  };
+
+  using ObjCContextIDLayout = BCRecordLayout<
+    OBJC_CONTEXT_ID_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from ObjC class names/protocol (as IDs) to context IDs
+  >;
+
+  using ObjCContextInfoLayout = BCRecordLayout<
+    OBJC_CONTEXT_INFO_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob      // map from ObjC context IDs to context information.
+  >;
+}
+
+namespace objc_property_block {
+  enum {
+    OBJC_PROPERTY_DATA = 1,
+  };
+
+  using ObjCPropertyDataLayout = BCRecordLayout<
+    OBJC_PROPERTY_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from ObjC (class name, property name) pairs to ObjC
+            // property information
+  >;
+}
+
+namespace objc_method_block {
+  enum {
+    OBJC_METHOD_DATA = 1,
+  };
+
+  using ObjCMethodDataLayout = BCRecordLayout<
+    OBJC_METHOD_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from ObjC (class names, selector,
+            // is-instance-method) tuples to ObjC method information
+  >;
+}
+
+namespace objc_selector_block {
+  enum {
+    OBJC_SELECTOR_DATA = 1,
+  };
+
+  using ObjCSelectorDataLayout = BCRecordLayout<
+    OBJC_SELECTOR_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from (# pieces, identifier IDs) to Objective-C selector ID.
+  >;
+}
+
+namespace global_variable_block {
+  enum {
+    GLOBAL_VARIABLE_DATA = 1
+  };
+
+  using GlobalVariableDataLayout = BCRecordLayout<
+    GLOBAL_VARIABLE_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from name to global variable information
+  >;
+}
+
+namespace global_function_block {
+  enum {
+    GLOBAL_FUNCTION_DATA = 1
+  };
+
+  using GlobalFunctionDataLayout = BCRecordLayout<
+    GLOBAL_FUNCTION_DATA,  // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob  // map from name to global function information
+  >;
+}
+
+namespace tag_block {
+  enum {
+    TAG_DATA = 1
+  };
+
+  using TagDataLayout = BCRecordLayout<
+    TAG_DATA,   // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob      // map from name to tag information
+  >;
+};
+
+namespace typedef_block {
+  enum {
+    TYPEDEF_DATA = 1
+  };
+
+  using TypedefDataLayout = BCRecordLayout<
+    TYPEDEF_DATA,   // record ID
+    BCVBR<16>,  // table offset within the blob (see below)
+    BCBlob      // map from name to typedef information
+  >;
+};
+
+namespace enum_constant_block {
+  enum {
+    ENUM_CONSTANT_DATA = 1
+  };
+
+  using EnumConstantDataLayout = BCRecordLayout<
+    ENUM_CONSTANT_DATA,  // record ID
+    BCVBR<16>,           // table offset within the blob (see below)
+    BCBlob               // map from name to enumerator information
+  >;
+}
+
+/// A stored Objective-C selector.
+struct StoredObjCSelector {
+  unsigned NumPieces;
+  llvm::SmallVector<IdentifierID, 2> Identifiers;
+};
+
+} // end namespace api_notes
+} // end namespace clang
+
+namespace llvm {
+  template<>
+  struct DenseMapInfo<clang::api_notes::StoredObjCSelector> {
+    typedef DenseMapInfo<unsigned> UnsignedInfo;
+
+    static inline clang::api_notes::StoredObjCSelector getEmptyKey() {
+      return clang::api_notes::StoredObjCSelector{ 
+               UnsignedInfo::getEmptyKey(), { } };
+    }
+
+    static inline clang::api_notes::StoredObjCSelector getTombstoneKey() {
+      return clang::api_notes::StoredObjCSelector{ 
+               UnsignedInfo::getTombstoneKey(), { } };
+    }
+    
+    static unsigned getHashValue(
+                      const clang::api_notes::StoredObjCSelector& value) {
+      auto hash = llvm::hash_value(value.NumPieces);
+      hash = hash_combine(hash, value.Identifiers.size());
+      for (auto piece : value.Identifiers)
+        hash = hash_combine(hash, static_cast<unsigned>(piece));
+      // FIXME: Mix upper/lower 32-bit values together to produce
+      // unsigned rather than truncating.
+      return hash;
+    }
+
+    static bool isEqual(const clang::api_notes::StoredObjCSelector &lhs, 
+                        const clang::api_notes::StoredObjCSelector &rhs) {
+      return lhs.NumPieces == rhs.NumPieces && 
+             lhs.Identifiers == rhs.Identifiers;
+    }
+  };
+}
+
+#endif // LLVM_CLANG_API_NOTES_FORMAT_H
diff --git a/lib/APINotes/APINotesManager.cpp b/lib/APINotes/APINotesManager.cpp
new file mode 100644
index 0000000..832f454
--- /dev/null
+++ b/lib/APINotes/APINotesManager.cpp
@@ -0,0 +1,587 @@
+//===--- APINotesManager.cpp - Manage API Notes Files ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the APINotesManager class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/APINotes/APINotesManager.h"
+#include "clang/APINotes/APINotesOptions.h"
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/APINotes/APINotesYAMLCompiler.h"
+#include "clang/Basic/DiagnosticIDs.h"
+#include "clang/Basic/FileManager.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/SourceMgrAdapter.h"
+#include "clang/Basic/Version.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include <sys/stat.h>
+
+using namespace clang;
+using namespace api_notes;
+
+#define DEBUG_TYPE "API Notes"
+STATISTIC(NumHeaderAPINotes,
+          "non-framework API notes files loaded");
+STATISTIC(NumPublicFrameworkAPINotes,
+          "framework public API notes loaded");
+STATISTIC(NumPrivateFrameworkAPINotes,
+          "framework private API notes loaded");
+STATISTIC(NumFrameworksSearched,
+          "frameworks searched");
+STATISTIC(NumDirectoriesSearched,
+          "header directories searched");
+STATISTIC(NumDirectoryCacheHits,
+          "directory cache hits");
+STATISTIC(NumBinaryCacheHits,
+          "binary form cache hits");
+STATISTIC(NumBinaryCacheMisses,
+          "binary form cache misses");
+STATISTIC(NumBinaryCacheRebuilds,
+          "binary form cache rebuilds");
+
+namespace {
+  /// Prints two successive strings, which much be kept alive as long as the
+  /// PrettyStackTrace entry.
+  class PrettyStackTraceDoubleString : public llvm::PrettyStackTraceEntry {
+    StringRef First, Second;
+  public:
+    PrettyStackTraceDoubleString(StringRef first, StringRef second)
+        : First(first), Second(second) {}
+    void print(raw_ostream &OS) const override {
+      OS << First << Second;
+    }
+  };
+}
+
+APINotesManager::APINotesManager(SourceManager &sourceMgr,
+                                 const LangOptions &langOpts)
+  : SourceMgr(sourceMgr), ImplicitAPINotes(langOpts.APINotes),
+    PrunedCache(false) { }
+
+APINotesManager::~APINotesManager() {
+  // Free the API notes readers.
+  for (const auto &entry : Readers) {
+    if (auto reader = entry.second.dyn_cast<APINotesReader *>()) {
+      delete reader;
+    }
+  }
+
+  delete CurrentModuleReaders[0];
+  delete CurrentModuleReaders[1];
+}
+
+/// \brief Write a new timestamp file with the given path.
+static void writeTimestampFile(StringRef TimestampFile) {
+  std::error_code EC;
+  llvm::raw_fd_ostream Out(TimestampFile.str(), EC, llvm::sys::fs::F_None);
+}
+
+/// \brief Prune the API notes cache of API notes that haven't been accessed in
+/// a long time.
+static void pruneAPINotesCache(StringRef APINotesCachePath) {
+  struct stat StatBuf;
+  llvm::SmallString<128> TimestampFile;
+  TimestampFile = APINotesCachePath;
+  llvm::sys::path::append(TimestampFile, "APINotes.timestamp");
+
+  // Try to stat() the timestamp file.
+  if (::stat(TimestampFile.c_str(), &StatBuf)) {
+    // If the timestamp file wasn't there, create one now.
+    if (errno == ENOENT) {
+      llvm::sys::fs::create_directories(APINotesCachePath);
+      writeTimestampFile(TimestampFile);
+    }
+    return;
+  }
+
+  const unsigned APINotesCachePruneInterval = 7 * 24 * 60 * 60;
+  const unsigned APINotesCachePruneAfter = 31 * 24 * 60 * 60;
+
+  // Check whether the time stamp is older than our pruning interval.
+  // If not, do nothing.
+  time_t TimeStampModTime = StatBuf.st_mtime;
+  time_t CurrentTime = time(nullptr);
+  if (CurrentTime - TimeStampModTime <= time_t(APINotesCachePruneInterval))
+    return;
+
+  // Write a new timestamp file so that nobody else attempts to prune.
+  // There is a benign race condition here, if two Clang instances happen to
+  // notice at the same time that the timestamp is out-of-date.
+  writeTimestampFile(TimestampFile);
+
+  // Walk the entire API notes cache, looking for unused compiled API notes.
+  std::error_code EC;
+  SmallString<128> APINotesCachePathNative;
+  llvm::sys::path::native(APINotesCachePath, APINotesCachePathNative);
+  for (llvm::sys::fs::directory_iterator
+         File(APINotesCachePathNative.str(), EC), DirEnd;
+       File != DirEnd && !EC; File.increment(EC)) {
+    StringRef Extension = llvm::sys::path::extension(File->path());
+    if (Extension.empty())
+      continue;
+
+    if (Extension.substr(1) != BINARY_APINOTES_EXTENSION)
+      continue;
+
+    // Look at this file. If we can't stat it, there's nothing interesting
+    // there.
+    if (::stat(File->path().c_str(), &StatBuf))
+      continue;
+
+    // If the file has been used recently enough, leave it there.
+    time_t FileAccessTime = StatBuf.st_atime;
+    if (CurrentTime - FileAccessTime <= time_t(APINotesCachePruneAfter)) {
+      continue;
+    }
+
+    // Remove the file.
+    llvm::sys::fs::remove(File->path());
+  }
+}
+
+std::unique_ptr<APINotesReader>
+APINotesManager::loadAPINotes(const FileEntry *apiNotesFile) {
+  FileManager &fileMgr = SourceMgr.getFileManager();
+  PrettyStackTraceDoubleString trace("Loading API notes from ",
+                                     apiNotesFile->getName());
+
+  // If the API notes file is already in the binary form, load it directly.
+  StringRef apiNotesFileName = apiNotesFile->getName();
+  StringRef apiNotesFileExt = llvm::sys::path::extension(apiNotesFileName);
+  if (!apiNotesFileExt.empty() &&
+      apiNotesFileExt.substr(1) == BINARY_APINOTES_EXTENSION) {
+    auto compiledFileID = SourceMgr.createFileID(apiNotesFile, SourceLocation(), SrcMgr::C_User);
+
+    // Load the file.
+    auto buffer = SourceMgr.getBuffer(compiledFileID, SourceLocation());
+    if (!buffer) return nullptr;
+
+    // Load the binary form.
+    return APINotesReader::getUnmanaged(buffer, SwiftVersion);
+  }
+
+  // If we haven't pruned the API notes cache yet during this execution, do
+  // so now.
+  if (!PrunedCache) {
+    pruneAPINotesCache(fileMgr.getFileSystemOpts().APINotesCachePath);
+    PrunedCache = true;
+  }
+
+  // Compute a hash of the API notes file's directory and the Clang version,
+  // to be used as part of the filename for the cached binary copy.
+  auto code = llvm::hash_value(StringRef(apiNotesFile->getDir()->getName()));
+  code = hash_combine(code, getClangFullRepositoryVersion());
+
+  // Determine the file name for the cached binary form.
+  SmallString<128> compiledFileName;
+  compiledFileName += fileMgr.getFileSystemOpts().APINotesCachePath;
+  assert(!compiledFileName.empty() && "No API notes cache path provided?");
+  llvm::sys::path::append(compiledFileName,
+    (llvm::Twine(llvm::sys::path::stem(apiNotesFileName)) + "-"
+     + llvm::APInt(64, code).toString(36, /*Signed=*/false) + "."
+     + BINARY_APINOTES_EXTENSION));
+
+  // Try to open the cached binary form.
+  if (const FileEntry *compiledFile = fileMgr.getFile(compiledFileName,
+                                                      /*openFile=*/true,
+                                                      /*cacheFailure=*/false)) {
+    // Load the file contents.
+    if (auto buffer = fileMgr.getBufferForFile(compiledFile)) {
+      // Load the file.
+      if (auto reader = APINotesReader::get(std::move(buffer.get()),
+                                            SwiftVersion)) {
+        bool outOfDate = false;
+        if (auto sizeAndModTime = reader->getSourceFileSizeAndModTime()) {
+          if (sizeAndModTime->first != apiNotesFile->getSize() ||
+              sizeAndModTime->second != apiNotesFile->getModificationTime())
+            outOfDate = true;
+        }
+
+        if (!outOfDate) {
+          // Success.
+          ++NumBinaryCacheHits;
+          return reader;
+        }
+      }
+    }
+
+    // The cache entry was somehow broken; delete this one so we can build a
+    // new one below.
+    llvm::sys::fs::remove(compiledFileName.str());
+    ++NumBinaryCacheRebuilds;
+  } else {
+    ++NumBinaryCacheMisses;
+  }
+
+  // Open the source file.
+  auto sourceFileID = SourceMgr.createFileID(apiNotesFile, SourceLocation(), SrcMgr::C_User);
+  auto sourceBuffer = SourceMgr.getBuffer(sourceFileID, SourceLocation());
+  if (!sourceBuffer) return nullptr;
+
+  // Compile the API notes source into a buffer.
+  // FIXME: Either propagate OSType through or, better yet, improve the binary
+  // APINotes format to maintain complete availability information.
+  llvm::SmallVector<char, 1024> apiNotesBuffer;
+  std::unique_ptr<llvm::MemoryBuffer> compiledBuffer;
+  {
+    SourceMgrAdapter srcMgrAdapter(SourceMgr, SourceMgr.getDiagnostics(),
+                                   diag::err_apinotes_message,
+                                   diag::warn_apinotes_message,
+                                   diag::note_apinotes_message,
+                                   apiNotesFile);
+    llvm::raw_svector_ostream OS(apiNotesBuffer);
+    if (api_notes::compileAPINotes(sourceBuffer->getBuffer(),
+                                   SourceMgr.getFileEntryForID(sourceFileID),
+                                   OS,
+                                   api_notes::OSType::Absent,
+                                   srcMgrAdapter.getDiagHandler(),
+                                   srcMgrAdapter.getDiagContext()))
+      return nullptr;
+
+    // Make a copy of the compiled form into the buffer.
+    compiledBuffer = llvm::MemoryBuffer::getMemBufferCopy(
+               StringRef(apiNotesBuffer.data(), apiNotesBuffer.size()));
+  }
+
+  // Save the binary form into the cache. Perform this operation
+  // atomically.
+  SmallString<64> temporaryBinaryFileName = compiledFileName.str();
+  temporaryBinaryFileName.erase(
+    temporaryBinaryFileName.end()
+      - llvm::sys::path::extension(temporaryBinaryFileName).size(),
+    temporaryBinaryFileName.end());
+  temporaryBinaryFileName += "-%%%%%%.";
+  temporaryBinaryFileName += BINARY_APINOTES_EXTENSION;
+
+  int temporaryFD;
+  llvm::sys::fs::create_directories(
+    fileMgr.getFileSystemOpts().APINotesCachePath);
+  if (!llvm::sys::fs::createUniqueFile(temporaryBinaryFileName.str(),
+                                       temporaryFD, temporaryBinaryFileName)) {
+    // Write the contents of the buffer.
+    bool hadError;
+    {
+      llvm::raw_fd_ostream out(temporaryFD, /*shouldClose=*/true);
+      out.write(compiledBuffer.get()->getBufferStart(),
+                compiledBuffer.get()->getBufferSize());
+      out.flush();
+
+      hadError = out.has_error();
+    }
+
+    if (!hadError) {
+      // Rename the temporary file to the actual compiled file.
+      llvm::sys::fs::rename(temporaryBinaryFileName.str(),
+                            compiledFileName.str());
+    }
+  }
+
+  // Load the binary form we just compiled.
+  auto reader = APINotesReader::get(std::move(compiledBuffer), SwiftVersion);
+  assert(reader && "Could not load the API notes we just generated?");
+  return reader;
+}
+
+bool APINotesManager::loadAPINotes(const DirectoryEntry *HeaderDir,
+                                   const FileEntry *APINotesFile) {
+  assert(Readers.find(HeaderDir) == Readers.end());
+  if (auto reader = loadAPINotes(APINotesFile)) {
+    Readers[HeaderDir] = reader.release();
+    return false;
+  }
+
+  Readers[HeaderDir] = nullptr;
+  return true;
+}
+
+const FileEntry *APINotesManager::findAPINotesFile(const DirectoryEntry *directory,
+                                                   StringRef basename,
+                                                   bool wantPublic) {
+  FileManager &fileMgr = SourceMgr.getFileManager();
+
+  llvm::SmallString<128> path;
+  path += directory->getName();
+
+  unsigned pathLen = path.size();
+
+  StringRef basenameSuffix = "";
+  if (!wantPublic) basenameSuffix = "_private";
+
+  // Look for a binary API notes file.
+  llvm::sys::path::append(path, 
+    llvm::Twine(basename) + basenameSuffix + "." + BINARY_APINOTES_EXTENSION);
+  if (const FileEntry *binaryFile = fileMgr.getFile(path))
+    return binaryFile;
+
+  // Go back to the original path.
+  path.resize(pathLen);
+
+  // Look for the source API notes file.
+  llvm::sys::path::append(path, 
+    llvm::Twine(basename) + basenameSuffix + "." + SOURCE_APINOTES_EXTENSION);
+  return fileMgr.getFile(path);
+}
+
+const DirectoryEntry *APINotesManager::loadFrameworkAPINotes(
+                        llvm::StringRef FrameworkPath,
+                        llvm::StringRef FrameworkName,
+                        bool Public) {
+  FileManager &FileMgr = SourceMgr.getFileManager();
+  
+  llvm::SmallString<128> Path;
+  Path += FrameworkPath;
+  unsigned FrameworkNameLength = Path.size();
+
+  // Form the path to the APINotes file.
+  llvm::sys::path::append(Path, "APINotes");
+  if (Public)
+    llvm::sys::path::append(Path,
+                            (llvm::Twine(FrameworkName) + "."
+                              + SOURCE_APINOTES_EXTENSION));
+  else
+    llvm::sys::path::append(Path,
+                            (llvm::Twine(FrameworkName) + "_private."
+                              + SOURCE_APINOTES_EXTENSION));
+
+  // Try to open the APINotes file.
+  const FileEntry *APINotesFile = FileMgr.getFile(Path);
+  if (!APINotesFile)
+    return nullptr;
+
+  // Form the path to the corresponding header directory.
+  Path.resize(FrameworkNameLength);
+  if (Public)
+    llvm::sys::path::append(Path, "Headers");
+  else
+    llvm::sys::path::append(Path, "PrivateHeaders");
+
+  // Try to access the header directory.
+  const DirectoryEntry *HeaderDir = FileMgr.getDirectory(Path);
+  if (!HeaderDir)
+    return nullptr;
+
+  // Try to load the API notes.
+  if (loadAPINotes(HeaderDir, APINotesFile))
+    return nullptr;
+
+  // Success: return the header directory.
+  if (Public)
+    ++NumPublicFrameworkAPINotes;
+  else
+    ++NumPrivateFrameworkAPINotes;
+  return HeaderDir;
+}
+
+bool APINotesManager::loadCurrentModuleAPINotes(
+                   const Module *module,
+                   bool lookInModule,
+                   ArrayRef<std::string> searchPaths) {
+  assert(!CurrentModuleReaders[0] &&
+         "Already loaded API notes for the current module?");
+
+  FileManager &fileMgr = SourceMgr.getFileManager();
+  auto moduleName = module->getTopLevelModuleName();
+
+  // First, look relative to the module itself.
+  if (lookInModule) {
+    bool foundAny = false;
+    unsigned numReaders = 0;
+
+    // Local function to try loading an API notes file in the given directory.
+    auto tryAPINotes = [&](const DirectoryEntry *dir, bool wantPublic) {
+      if (auto file = findAPINotesFile(dir, moduleName, wantPublic)) {
+        foundAny = true;
+
+        // Try to load the API notes file.
+        CurrentModuleReaders[numReaders] = loadAPINotes(file).release();
+        if (CurrentModuleReaders[numReaders])
+          ++numReaders;
+      }
+    };
+
+    if (module->IsFramework) {
+      // For frameworks, we search in the "Headers" or "PrivateHeaders"
+      // subdirectory.
+      llvm::SmallString<128> path;
+      path += module->Directory->getName();
+      unsigned pathLen = path.size();
+
+      llvm::sys::path::append(path, "Headers");
+      if (auto apinotesDir = fileMgr.getDirectory(path))
+        tryAPINotes(apinotesDir, /*wantPublic=*/true);
+
+      path.resize(pathLen);
+      llvm::sys::path::append(path, "PrivateHeaders");
+      if (auto privateAPINotesDir = fileMgr.getDirectory(path))
+        tryAPINotes(privateAPINotesDir, /*wantPublic=*/false);
+    } else {
+      tryAPINotes(module->Directory, /*wantPublic=*/true);
+      tryAPINotes(module->Directory, /*wantPublic=*/false);
+    }
+
+    if (foundAny)
+      return numReaders > 0;
+  }
+
+  // Second, look for API notes for this module in the module API
+  // notes search paths.
+  for (const auto &searchPath : searchPaths) {
+    if (auto searchDir = fileMgr.getDirectory(searchPath)) {
+      if (auto file = findAPINotesFile(searchDir, moduleName)) {
+        CurrentModuleReaders[0] = loadAPINotes(file).release();
+        return !getCurrentModuleReaders().empty();
+      }
+    }
+  }
+
+  // Didn't find any API notes.
+  return false;
+}
+
+llvm::SmallVector<APINotesReader *, 2> APINotesManager::findAPINotes(SourceLocation Loc) {
+  llvm::SmallVector<APINotesReader *, 2> Results;
+
+  // If there are readers for the current module, return them.
+  if (!getCurrentModuleReaders().empty()) {
+    Results.append(getCurrentModuleReaders().begin(), getCurrentModuleReaders().end());
+    return Results;
+  }
+
+  // If we're not allowed to implicitly load API notes files, we're done.
+  if (!ImplicitAPINotes) return Results;
+
+  // If we don't have source location information, we're done.
+  if (Loc.isInvalid()) return Results;
+
+  // API notes are associated with the expansion location. Retrieve the
+  // file for this location.
+  SourceLocation ExpansionLoc = SourceMgr.getExpansionLoc(Loc);
+  FileID ID = SourceMgr.getFileID(ExpansionLoc);
+  if (ID.isInvalid()) return Results;
+  const FileEntry *File = SourceMgr.getFileEntryForID(ID);
+  if (!File) return Results;
+
+  // Look for API notes in the directory corresponding to this file, or one of
+  // its its parent directories.
+  const DirectoryEntry *Dir = File->getDir();
+  FileManager &FileMgr = SourceMgr.getFileManager();
+  llvm::SetVector<const DirectoryEntry *,
+                  SmallVector<const DirectoryEntry *, 4>,
+                  llvm::SmallPtrSet<const DirectoryEntry *, 4>> DirsVisited;
+  do {
+    // Look for an API notes reader for this header search directory.
+    auto Known = Readers.find(Dir);
+
+    // If we already know the answer, chase it.
+    if (Known != Readers.end()) {
+      ++NumDirectoryCacheHits;
+
+      // We've been redirected to another directory for answers. Follow it.
+      if (auto OtherDir = Known->second.dyn_cast<const DirectoryEntry *>()) {
+        DirsVisited.insert(Dir);
+        Dir = OtherDir;
+        continue;
+      }
+
+      // We have the answer.
+      if (auto Reader = Known->second.dyn_cast<APINotesReader *>())
+        Results.push_back(Reader);
+      break;
+    }
+
+    // Look for API notes corresponding to this directory.
+    StringRef Path = Dir->getName();
+    if (llvm::sys::path::extension(Path) == ".framework") {
+      // If this is a framework directory, check whether there are API notes
+      // in the APINotes subdirectory.
+      auto FrameworkName = llvm::sys::path::stem(Path);
+      ++NumFrameworksSearched;
+
+      // Look for API notes for both the public and private headers.
+      const DirectoryEntry *PublicDir
+        = loadFrameworkAPINotes(Path, FrameworkName, /*Public=*/true);
+      const DirectoryEntry *PrivateDir
+        = loadFrameworkAPINotes(Path, FrameworkName, /*Public=*/false);
+
+      if (PublicDir || PrivateDir) {
+        // We found API notes: don't ever look past the framework directory.
+        Readers[Dir] = nullptr;
+
+        // Pretend we found the result in the public or private directory,
+        // as appropriate. All headers should be in one of those two places,
+        // but be defensive here.
+        if (!DirsVisited.empty()) {
+          if (DirsVisited.back() == PublicDir) {
+            DirsVisited.pop_back();
+            Dir = PublicDir;
+          } else if (DirsVisited.back() == PrivateDir) {
+            DirsVisited.pop_back();
+            Dir = PrivateDir;
+          }
+        }
+
+        // Grab the result.
+        if (auto Reader = Readers[Dir].dyn_cast<APINotesReader *>())
+          Results.push_back(Reader);
+        break;
+      }
+    } else {
+      // Look for an APINotes file in this directory.
+      llvm::SmallString<128> APINotesPath;
+      APINotesPath += Dir->getName();
+      llvm::sys::path::append(APINotesPath,
+                              (llvm::Twine("APINotes.")
+                                 + SOURCE_APINOTES_EXTENSION));
+
+      // If there is an API notes file here, try to load it.
+      ++NumDirectoriesSearched;
+      if (const FileEntry *APINotesFile = FileMgr.getFile(APINotesPath)) {
+        if (!loadAPINotes(Dir, APINotesFile)) {
+          ++NumHeaderAPINotes;
+          if (auto Reader = Readers[Dir].dyn_cast<APINotesReader *>())
+            Results.push_back(Reader);
+          break;
+        }
+      }
+    }
+
+    // We didn't find anything. Look at the parent directory.
+    if (!DirsVisited.insert(Dir)) {
+      Dir = 0;
+      break;
+    }
+
+    StringRef ParentPath = llvm::sys::path::parent_path(Path);
+    while (llvm::sys::path::stem(ParentPath) == "..") {
+      ParentPath = llvm::sys::path::parent_path(ParentPath);
+    }
+    if (ParentPath.empty()) {
+      Dir = nullptr;
+    } else {
+      Dir = FileMgr.getDirectory(ParentPath);
+    }
+  } while (Dir);
+
+  // Path compression for all of the directories we visited, redirecting
+  // them to the directory we ended on. If no API notes were found, the
+  // resulting directory will be NULL, indicating no API notes.
+  for (const auto Visited : DirsVisited) {
+    Readers[Visited] = Dir;
+  }
+
+  return Results;
+}
diff --git a/lib/APINotes/APINotesReader.cpp b/lib/APINotes/APINotesReader.cpp
new file mode 100644
index 0000000..0b802b4
--- /dev/null
+++ b/lib/APINotes/APINotesReader.cpp
@@ -0,0 +1,1876 @@
+//===--- APINotesReader.cpp - Side Car Reader --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the \c APINotesReader class that reads source
+// API notes data providing additional information about source code as
+// a separate input, such as the non-nil/nilable annotations for
+// method parameters.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/APINotesReader.h"
+#include "APINotesFormat.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/OnDiskHashTable.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringExtras.h"
+
+using namespace clang;
+using namespace api_notes;
+using namespace llvm::support;
+using namespace llvm;
+
+namespace {
+  /// Deserialize a version tuple.
+  VersionTuple readVersionTuple(const uint8_t *&data) {
+    uint8_t numVersions = (*data++) & 0x03;
+
+    unsigned major = endian::readNext<uint32_t, little, unaligned>(data);
+    if (numVersions == 0)
+      return VersionTuple(major);
+
+    unsigned minor = endian::readNext<uint32_t, little, unaligned>(data);
+    if (numVersions == 1)
+      return VersionTuple(major, minor);
+
+    unsigned subminor = endian::readNext<uint32_t, little, unaligned>(data);
+    if (numVersions == 2)
+      return VersionTuple(major, minor, subminor);
+
+    unsigned build = endian::readNext<uint32_t, little, unaligned>(data);
+    return VersionTuple(major, minor, subminor, build);
+  }
+
+  /// An on-disk hash table whose data is versioned based on the Swift version.
+  template<typename Derived, typename KeyType, typename UnversionedDataType>
+  class VersionedTableInfo {
+  public:
+    using internal_key_type = KeyType;
+    using external_key_type = KeyType;
+    using data_type = SmallVector<std::pair<VersionTuple, UnversionedDataType>, 1>;
+    using hash_value_type = size_t;
+    using offset_type = unsigned;
+
+    internal_key_type GetInternalKey(external_key_type key) {
+      return key;
+    }
+
+    external_key_type GetExternalKey(internal_key_type key) {
+      return key;
+    }
+
+    hash_value_type ComputeHash(internal_key_type key) {
+      return static_cast<size_t>(llvm::hash_value(key));
+    }
+
+    static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
+      return lhs == rhs;
+    }
+
+    static std::pair<unsigned, unsigned>
+    ReadKeyDataLength(const uint8_t *&data) {
+      unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
+      return { keyLength, dataLength };
+    }
+
+    static data_type ReadData(internal_key_type key, const uint8_t *data,
+                              unsigned length) {
+      unsigned numElements = endian::readNext<uint16_t, little, unaligned>(data);
+      data_type result;
+      result.reserve(numElements);
+      for (unsigned i = 0; i != numElements; ++i) {
+        auto version = readVersionTuple(data);
+        auto dataBefore = data; (void)dataBefore;
+        auto unversionedData = Derived::readUnversioned(key, data);
+        assert(data != dataBefore
+               && "Unversioned data reader didn't move pointer");
+        result.push_back({version, unversionedData});
+      }
+      return result;
+    }
+  };
+
+
+  /// Read serialized CommonEntityInfo.
+  void readCommonEntityInfo(const uint8_t *&data, CommonEntityInfo &info) {
+    uint8_t unavailableBits = *data++;
+    info.Unavailable = (unavailableBits >> 1) & 0x01;
+    info.UnavailableInSwift = unavailableBits & 0x01;
+    if ((unavailableBits >> 2) & 0x01)
+      info.setSwiftPrivate(static_cast<bool>((unavailableBits >> 3) & 0x01));
+
+    unsigned msgLength = endian::readNext<uint16_t, little, unaligned>(data);
+    info.UnavailableMsg
+      = std::string(reinterpret_cast<const char *>(data),
+                    reinterpret_cast<const char *>(data) + msgLength);
+    data += msgLength;
+
+    unsigned swiftNameLength
+      = endian::readNext<uint16_t, little, unaligned>(data);
+    info.SwiftName
+      = std::string(reinterpret_cast<const char *>(data),
+                    reinterpret_cast<const char *>(data) + swiftNameLength);
+    data += swiftNameLength;
+  }
+
+  /// Read serialized CommonTypeInfo.
+  void readCommonTypeInfo(const uint8_t *&data, CommonTypeInfo &info) {
+    readCommonEntityInfo(data, info);
+
+    unsigned swiftBridgeLength =
+        endian::readNext<uint16_t, little, unaligned>(data);
+    if (swiftBridgeLength > 0) {
+      info.setSwiftBridge(
+        std::string(reinterpret_cast<const char *>(data), swiftBridgeLength-1));
+      data += swiftBridgeLength-1;
+    }
+
+    unsigned errorDomainLength =
+      endian::readNext<uint16_t, little, unaligned>(data);
+    if (errorDomainLength > 0) {
+      info.setNSErrorDomain(
+        std::string(reinterpret_cast<const char *>(data), errorDomainLength-1));
+      data += errorDomainLength-1;
+    }
+  }
+
+  /// Used to deserialize the on-disk identifier table.
+  class IdentifierTableInfo {
+  public:
+    using internal_key_type = StringRef;
+    using external_key_type = StringRef;
+    using data_type = IdentifierID;
+    using hash_value_type = uint32_t;
+    using offset_type = unsigned;
+
+    internal_key_type GetInternalKey(external_key_type key) {
+      return key;
+    }
+
+    external_key_type GetExternalKey(internal_key_type key) {
+      return key;
+    }
+
+    hash_value_type ComputeHash(internal_key_type key) {
+      return llvm::HashString(key);
+    }
+    
+    static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
+      return lhs == rhs;
+    }
+    
+    static std::pair<unsigned, unsigned> 
+    ReadKeyDataLength(const uint8_t *&data) {
+      unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
+      return { keyLength, dataLength };
+    }
+    
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      return StringRef(reinterpret_cast<const char *>(data), length);
+    }
+    
+    static data_type ReadData(internal_key_type key, const uint8_t *data,
+                              unsigned length) {
+      return endian::readNext<uint32_t, little, unaligned>(data);
+    }
+  };
+
+  /// Used to deserialize the on-disk Objective-C class table.
+  class ObjCContextIDTableInfo {
+  public:
+    // identifier ID, is-protocol
+    using internal_key_type = std::pair<unsigned, char>;
+    using external_key_type = internal_key_type;
+    using data_type = unsigned;
+    using hash_value_type = size_t;
+    using offset_type = unsigned;
+
+    internal_key_type GetInternalKey(external_key_type key) {
+      return key;
+    }
+
+    external_key_type GetExternalKey(internal_key_type key) {
+      return key;
+    }
+
+    hash_value_type ComputeHash(internal_key_type key) {
+      return static_cast<size_t>(llvm::hash_value(key));
+    }
+    
+    static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
+      return lhs == rhs;
+    }
+    
+    static std::pair<unsigned, unsigned> 
+    ReadKeyDataLength(const uint8_t *&data) {
+      unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
+      return { keyLength, dataLength };
+    }
+    
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID
+        = endian::readNext<uint32_t, little, unaligned>(data);
+      auto isProtocol = endian::readNext<uint8_t, little, unaligned>(data);
+      return { nameID, isProtocol };
+    }
+    
+    static data_type ReadData(internal_key_type key, const uint8_t *data,
+                              unsigned length) {
+      return endian::readNext<uint32_t, little, unaligned>(data);
+    }
+  };
+
+  /// Used to deserialize the on-disk Objective-C property table.
+  class ObjCContextInfoTableInfo
+    : public VersionedTableInfo<ObjCContextInfoTableInfo,
+                                unsigned,
+                                ObjCContextInfo>
+  {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      return endian::readNext<uint32_t, little, unaligned>(data);
+    }
+    
+    static ObjCContextInfo readUnversioned(internal_key_type key,
+                                           const uint8_t *&data) {
+      ObjCContextInfo info;
+      readCommonTypeInfo(data, info);
+      uint8_t payload = *data++;
+
+      if (payload & 0x01)
+        info.setHasDesignatedInits(true);
+      payload = payload >> 1;
+
+      if (payload & 0x4)
+        info.setDefaultNullability(static_cast<NullabilityKind>(payload&0x03));
+      payload >>= 3;
+
+      if (payload & (1 << 1))
+        info.setSwiftObjCMembers(payload & 1);
+      payload >>= 2;
+
+      if (payload & (1 << 1))
+        info.setSwiftImportAsNonGeneric(payload & 1);
+
+      return info;
+    }
+  };
+
+  /// Read serialized VariableInfo.
+  void readVariableInfo(const uint8_t *&data, VariableInfo &info) {
+    readCommonEntityInfo(data, info);
+    if (*data++) {
+      info.setNullabilityAudited(static_cast<NullabilityKind>(*data));
+    }
+    ++data;
+
+    auto typeLen
+      = endian::readNext<uint16_t, little, unaligned>(data);
+    info.setType(std::string(data, data + typeLen));
+    data += typeLen;
+  }
+
+  /// Used to deserialize the on-disk Objective-C property table.
+  class ObjCPropertyTableInfo
+    : public VersionedTableInfo<ObjCPropertyTableInfo,
+                                std::tuple<unsigned, unsigned, char>,
+                                ObjCPropertyInfo>
+  {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto classID = endian::readNext<uint32_t, little, unaligned>(data);
+      auto nameID = endian::readNext<uint32_t, little, unaligned>(data);
+      char isInstance = endian::readNext<uint8_t, little, unaligned>(data);
+      return std::make_tuple(classID, nameID, isInstance);
+    }
+    
+    static ObjCPropertyInfo readUnversioned(internal_key_type key,
+                                            const uint8_t *&data) {
+      ObjCPropertyInfo info;
+      readVariableInfo(data, info);
+      uint8_t flags = *data++;
+      if (flags & (1 << 0))
+        info.setSwiftImportAsAccessors(flags & (1 << 1));
+      return info;
+    }
+  };
+
+  /// Read serialized ParamInfo.
+  void readParamInfo(const uint8_t *&data, ParamInfo &info) {
+    readVariableInfo(data, info);
+
+    uint8_t payload = endian::readNext<uint8_t, little, unaligned>(data);
+    if (payload & 0x01) {
+      info.setNoEscape(payload & 0x02);
+    }
+    payload >>= 2; assert(payload == 0 && "Bad API notes");
+  }
+
+  /// Read serialized FunctionInfo.
+  void readFunctionInfo(const uint8_t *&data, FunctionInfo &info) {
+    readCommonEntityInfo(data, info);
+    info.NullabilityAudited
+      = endian::readNext<uint8_t, little, unaligned>(data);
+    info.NumAdjustedNullable
+      = endian::readNext<uint8_t, little, unaligned>(data);
+    info.NullabilityPayload
+      = endian::readNext<uint64_t, little, unaligned>(data);
+
+    unsigned numParams = endian::readNext<uint16_t, little, unaligned>(data);
+    while (numParams > 0) {
+      ParamInfo pi;
+      readParamInfo(data, pi);
+      info.Params.push_back(pi);
+      --numParams;
+    }
+
+    unsigned resultTypeLen
+      = endian::readNext<uint16_t, little, unaligned>(data);
+    info.ResultType = std::string(data, data + resultTypeLen);
+    data += resultTypeLen;
+  }
+
+  /// Used to deserialize the on-disk Objective-C method table.
+  class ObjCMethodTableInfo
+    : public VersionedTableInfo<ObjCMethodTableInfo,
+                                std::tuple<unsigned, unsigned, char>,
+                                ObjCMethodInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto classID = endian::readNext<uint32_t, little, unaligned>(data);
+      auto selectorID = endian::readNext<uint32_t, little, unaligned>(data);
+      auto isInstance = endian::readNext<uint8_t, little, unaligned>(data);
+      return internal_key_type{ classID, selectorID, isInstance };
+    }
+    
+    static ObjCMethodInfo readUnversioned(internal_key_type key,
+                                          const uint8_t *&data) {
+      ObjCMethodInfo info;
+      uint8_t payload = *data++;
+      info.Required = payload & 0x01;
+      payload >>= 1;
+      info.DesignatedInit = payload & 0x01;
+      payload >>= 1;
+
+      readFunctionInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk Objective-C selector table.
+  class ObjCSelectorTableInfo {
+  public:
+    using internal_key_type = StoredObjCSelector; 
+    using external_key_type = internal_key_type;
+    using data_type = SelectorID;
+    using hash_value_type = unsigned;
+    using offset_type = unsigned;
+
+    internal_key_type GetInternalKey(external_key_type key) {
+      return key;
+    }
+
+    external_key_type GetExternalKey(internal_key_type key) {
+      return key;
+    }
+
+    hash_value_type ComputeHash(internal_key_type key) {
+      return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(key);
+    }
+    
+    static bool EqualKey(internal_key_type lhs, internal_key_type rhs) {
+      return llvm::DenseMapInfo<StoredObjCSelector>::isEqual(lhs, rhs);
+    }
+    
+    static std::pair<unsigned, unsigned> 
+    ReadKeyDataLength(const uint8_t *&data) {
+      unsigned keyLength = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned dataLength = endian::readNext<uint16_t, little, unaligned>(data);
+      return { keyLength, dataLength };
+    }
+    
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      internal_key_type key;
+      key.NumPieces = endian::readNext<uint16_t, little, unaligned>(data);
+      unsigned numIdents = (length - sizeof(uint16_t)) / sizeof(uint32_t);
+      for (unsigned i = 0; i != numIdents; ++i) {
+        key.Identifiers.push_back(
+          endian::readNext<uint32_t, little, unaligned>(data));
+      }
+      return key;
+    }
+    
+    static data_type ReadData(internal_key_type key, const uint8_t *data,
+                              unsigned length) {
+      return endian::readNext<uint32_t, little, unaligned>(data);
+    }
+  };
+
+  /// Used to deserialize the on-disk global variable table.
+  class GlobalVariableTableInfo
+    : public VersionedTableInfo<GlobalVariableTableInfo, unsigned,
+                                GlobalVariableInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<uint32_t, little, unaligned>(data);
+      return nameID;
+    }
+
+    static GlobalVariableInfo readUnversioned(internal_key_type key,
+                                              const uint8_t *&data) {
+      GlobalVariableInfo info;
+      readVariableInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk global function table.
+  class GlobalFunctionTableInfo
+    : public VersionedTableInfo<GlobalFunctionTableInfo, unsigned,
+                                GlobalFunctionInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<uint32_t, little, unaligned>(data);
+      return nameID;
+    }
+    
+    static GlobalFunctionInfo readUnversioned(internal_key_type key,
+                                              const uint8_t *&data) {
+      GlobalFunctionInfo info;
+      readFunctionInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk enumerator table.
+  class EnumConstantTableInfo
+    : public VersionedTableInfo<EnumConstantTableInfo, unsigned,
+                                EnumConstantInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<uint32_t, little, unaligned>(data);
+      return nameID;
+    }
+    
+    static EnumConstantInfo readUnversioned(internal_key_type key,
+                                            const uint8_t *&data) {
+      EnumConstantInfo info;
+      readCommonEntityInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk tag table.
+  class TagTableInfo
+    : public VersionedTableInfo<TagTableInfo, unsigned, TagInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<IdentifierID, little, unaligned>(data);
+      return nameID;
+    }
+    
+    static TagInfo readUnversioned(internal_key_type key,
+                                   const uint8_t *&data) {
+      TagInfo info;
+
+      uint8_t payload = *data++;
+      if (payload & 1) {
+        info.setFlagEnum(payload & 2);
+      }
+      payload >>= 2;
+      if (payload > 0) {
+        info.EnumExtensibility =
+            static_cast<EnumExtensibilityKind>((payload & 0x3) - 1);
+      }
+
+      readCommonTypeInfo(data, info);
+      return info;
+    }
+  };
+
+  /// Used to deserialize the on-disk typedef table.
+  class TypedefTableInfo
+    : public VersionedTableInfo<TypedefTableInfo, unsigned, TypedefInfo> {
+  public:
+    static internal_key_type ReadKey(const uint8_t *data, unsigned length) {
+      auto nameID = endian::readNext<IdentifierID, little, unaligned>(data);
+      return nameID;
+    }
+
+    static TypedefInfo readUnversioned(internal_key_type key,
+                                       const uint8_t *&data) {
+      TypedefInfo info;
+
+      uint8_t payload = *data++;
+      if (payload > 0) {
+        info.SwiftWrapper = static_cast<SwiftWrapperKind>((payload & 0x3) - 1);
+      }
+
+      readCommonTypeInfo(data, info);
+      return info;
+    }
+  };
+} // end anonymous namespace
+
+class APINotesReader::Implementation {
+public:
+  /// The input buffer for the API notes data.
+  llvm::MemoryBuffer *InputBuffer;
+
+  /// Whether we own the input buffer.
+  bool OwnsInputBuffer;
+
+  /// The Swift version to use for filtering.
+  VersionTuple SwiftVersion;
+
+  /// The name of the module that we read from the control block.
+  std::string ModuleName;
+
+  // The size and modification time of the source file from
+  // which this API notes file was created, if known.
+  Optional<std::pair<off_t, time_t>> SourceFileSizeAndModTime;
+
+  /// Various options and attributes for the module
+  ModuleOptions ModuleOpts;
+
+  using SerializedIdentifierTable =
+      llvm::OnDiskIterableChainedHashTable<IdentifierTableInfo>;
+
+  /// The identifier table.
+  std::unique_ptr<SerializedIdentifierTable> IdentifierTable;
+
+  using SerializedObjCContextIDTable =
+      llvm::OnDiskIterableChainedHashTable<ObjCContextIDTableInfo>;
+
+  /// The Objective-C context ID table.
+  std::unique_ptr<SerializedObjCContextIDTable> ObjCContextIDTable;
+
+  using SerializedObjCContextInfoTable =
+    llvm::OnDiskIterableChainedHashTable<ObjCContextInfoTableInfo>;
+
+  /// The Objective-C context info table.
+  std::unique_ptr<SerializedObjCContextInfoTable> ObjCContextInfoTable;
+
+  using SerializedObjCPropertyTable =
+      llvm::OnDiskIterableChainedHashTable<ObjCPropertyTableInfo>;
+
+  /// The Objective-C property table.
+  std::unique_ptr<SerializedObjCPropertyTable> ObjCPropertyTable;
+
+  using SerializedObjCMethodTable =
+      llvm::OnDiskIterableChainedHashTable<ObjCMethodTableInfo>;
+
+  /// The Objective-C method table.
+  std::unique_ptr<SerializedObjCMethodTable> ObjCMethodTable;
+
+  using SerializedObjCSelectorTable =
+      llvm::OnDiskIterableChainedHashTable<ObjCSelectorTableInfo>;
+
+  /// The Objective-C selector table.
+  std::unique_ptr<SerializedObjCSelectorTable> ObjCSelectorTable;
+
+  using SerializedGlobalVariableTable =
+      llvm::OnDiskIterableChainedHashTable<GlobalVariableTableInfo>;
+
+  /// The global variable table.
+  std::unique_ptr<SerializedGlobalVariableTable> GlobalVariableTable;
+
+  using SerializedGlobalFunctionTable =
+      llvm::OnDiskIterableChainedHashTable<GlobalFunctionTableInfo>;
+
+  /// The global function table.
+  std::unique_ptr<SerializedGlobalFunctionTable> GlobalFunctionTable;
+
+  using SerializedEnumConstantTable =
+      llvm::OnDiskIterableChainedHashTable<EnumConstantTableInfo>;
+
+  /// The enumerator table.
+  std::unique_ptr<SerializedEnumConstantTable> EnumConstantTable;
+
+  using SerializedTagTable =
+      llvm::OnDiskIterableChainedHashTable<TagTableInfo>;
+
+  /// The tag table.
+  std::unique_ptr<SerializedTagTable> TagTable;
+
+  using SerializedTypedefTable =
+      llvm::OnDiskIterableChainedHashTable<TypedefTableInfo>;
+
+  /// The typedef table.
+  std::unique_ptr<SerializedTypedefTable> TypedefTable;
+
+  /// Retrieve the identifier ID for the given string, or an empty
+  /// optional if the string is unknown.
+  Optional<IdentifierID> getIdentifier(StringRef str);
+
+  /// Retrieve the selector ID for the given selector, or an empty
+  /// optional if the string is unknown.
+  Optional<SelectorID> getSelector(ObjCSelectorRef selector);
+
+  bool readControlBlock(llvm::BitstreamCursor &cursor, 
+                        SmallVectorImpl<uint64_t> &scratch);
+  bool readIdentifierBlock(llvm::BitstreamCursor &cursor,
+                           SmallVectorImpl<uint64_t> &scratch);
+  bool readObjCContextBlock(llvm::BitstreamCursor &cursor,
+                            SmallVectorImpl<uint64_t> &scratch);
+  bool readObjCPropertyBlock(llvm::BitstreamCursor &cursor, 
+                             SmallVectorImpl<uint64_t> &scratch);
+  bool readObjCMethodBlock(llvm::BitstreamCursor &cursor, 
+                             SmallVectorImpl<uint64_t> &scratch);
+  bool readObjCSelectorBlock(llvm::BitstreamCursor &cursor, 
+                             SmallVectorImpl<uint64_t> &scratch);
+  bool readGlobalVariableBlock(llvm::BitstreamCursor &cursor,
+                               SmallVectorImpl<uint64_t> &scratch);
+  bool readGlobalFunctionBlock(llvm::BitstreamCursor &cursor,
+                               SmallVectorImpl<uint64_t> &scratch);
+  bool readEnumConstantBlock(llvm::BitstreamCursor &cursor,
+                             SmallVectorImpl<uint64_t> &scratch);
+  bool readTagBlock(llvm::BitstreamCursor &cursor,
+                    SmallVectorImpl<uint64_t> &scratch);
+  bool readTypedefBlock(llvm::BitstreamCursor &cursor,
+                        SmallVectorImpl<uint64_t> &scratch);
+};
+
+Optional<IdentifierID> APINotesReader::Implementation::getIdentifier(
+                         StringRef str) {
+  if (!IdentifierTable)
+    return None;
+
+  if (str.empty())
+    return IdentifierID(0);
+
+  auto known = IdentifierTable->find(str);
+  if (known == IdentifierTable->end())
+    return None;
+
+  return *known;
+}
+
+Optional<SelectorID> APINotesReader::Implementation::getSelector(
+                       ObjCSelectorRef selector) {
+  if (!ObjCSelectorTable || !IdentifierTable)
+    return None;
+
+  // Translate the identifiers.
+  StoredObjCSelector key;
+  key.NumPieces = selector.NumPieces;
+  for (auto ident : selector.Identifiers) {
+    if (auto identID = getIdentifier(ident)) {
+      key.Identifiers.push_back(*identID);
+    } else {
+      return None;
+    }
+  }
+
+  auto known = ObjCSelectorTable->find(key);
+  if (known == ObjCSelectorTable->end())
+    return None;
+
+  return *known;
+
+}
+
+bool APINotesReader::Implementation::readControlBlock(
+       llvm::BitstreamCursor &cursor,
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(CONTROL_BLOCK_ID))
+    return true;
+
+  bool sawMetadata = false;
+  
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown metadata sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case control_block::METADATA:
+      // Already saw metadata.
+      if (sawMetadata)
+        return true;
+
+      if (scratch[0] != VERSION_MAJOR || scratch[1] != VERSION_MINOR)
+        return true;
+
+      sawMetadata = true;
+      break;
+
+    case control_block::MODULE_NAME:
+      ModuleName = blobData.str();
+      break;
+
+    case control_block::MODULE_OPTIONS:
+      ModuleOpts.SwiftInferImportAsMember = (scratch.front() & 1) != 0;
+      break;
+
+    case control_block::SOURCE_FILE:
+      SourceFileSizeAndModTime = { scratch[0], scratch[1] };
+      break;
+
+    default:
+      // Unknown metadata record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return !sawMetadata;
+}
+
+bool APINotesReader::Implementation::readIdentifierBlock(
+       llvm::BitstreamCursor &cursor,
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(IDENTIFIER_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case identifier_block::IDENTIFIER_DATA: {
+      // Already saw identifier table.
+      if (IdentifierTable)
+        return true;
+
+      uint32_t tableOffset;
+      identifier_block::IdentifierDataLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      IdentifierTable.reset(
+        SerializedIdentifierTable::Create(base + tableOffset,
+                                          base + sizeof(uint32_t),
+                                          base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readObjCContextBlock(
+       llvm::BitstreamCursor &cursor,
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(OBJC_CONTEXT_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case objc_context_block::OBJC_CONTEXT_ID_DATA: {
+      // Already saw Objective-C context ID table.
+      if (ObjCContextIDTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_context_block::ObjCContextIDLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCContextIDTable.reset(
+        SerializedObjCContextIDTable::Create(base + tableOffset,
+                                             base + sizeof(uint32_t),
+                                             base));
+      break;
+    }
+
+    case objc_context_block::OBJC_CONTEXT_INFO_DATA: {
+      // Already saw Objective-C context info table.
+      if (ObjCContextInfoTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_context_block::ObjCContextInfoLayout::readRecord(scratch,
+                                                            tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCContextInfoTable.reset(
+        SerializedObjCContextInfoTable::Create(base + tableOffset,
+                                               base + sizeof(uint32_t),
+                                               base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readObjCPropertyBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(OBJC_PROPERTY_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case objc_property_block::OBJC_PROPERTY_DATA: {
+      // Already saw Objective-C property table.
+      if (ObjCPropertyTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_property_block::ObjCPropertyDataLayout::readRecord(scratch, 
+                                                              tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCPropertyTable.reset(
+        SerializedObjCPropertyTable::Create(base + tableOffset,
+                                            base + sizeof(uint32_t),
+                                            base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readObjCMethodBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(OBJC_METHOD_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case objc_method_block::OBJC_METHOD_DATA: {
+      // Already saw Objective-C method table.
+      if (ObjCMethodTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_method_block::ObjCMethodDataLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCMethodTable.reset(
+        SerializedObjCMethodTable::Create(base + tableOffset,
+                                          base + sizeof(uint32_t),
+                                          base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readObjCSelectorBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(OBJC_SELECTOR_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case objc_selector_block::OBJC_SELECTOR_DATA: {
+      // Already saw Objective-C selector table.
+      if (ObjCSelectorTable)
+        return true;
+
+      uint32_t tableOffset;
+      objc_selector_block::ObjCSelectorDataLayout::readRecord(scratch, 
+                                                              tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      ObjCSelectorTable.reset(
+        SerializedObjCSelectorTable::Create(base + tableOffset,
+                                          base + sizeof(uint32_t),
+                                          base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readGlobalVariableBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(GLOBAL_VARIABLE_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case global_variable_block::GLOBAL_VARIABLE_DATA: {
+      // Already saw global variable table.
+      if (GlobalVariableTable)
+        return true;
+
+      uint32_t tableOffset;
+      global_variable_block::GlobalVariableDataLayout::readRecord(scratch,
+                                                                  tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      GlobalVariableTable.reset(
+        SerializedGlobalVariableTable::Create(base + tableOffset,
+                                              base + sizeof(uint32_t),
+                                              base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readGlobalFunctionBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(GLOBAL_FUNCTION_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case global_function_block::GLOBAL_FUNCTION_DATA: {
+      // Already saw global function table.
+      if (GlobalFunctionTable)
+        return true;
+
+      uint32_t tableOffset;
+      global_function_block::GlobalFunctionDataLayout::readRecord(scratch,
+                                                                  tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      GlobalFunctionTable.reset(
+        SerializedGlobalFunctionTable::Create(base + tableOffset,
+                                              base + sizeof(uint32_t),
+                                              base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readEnumConstantBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(ENUM_CONSTANT_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case enum_constant_block::ENUM_CONSTANT_DATA: {
+      // Already saw enumerator table.
+      if (EnumConstantTable)
+        return true;
+
+      uint32_t tableOffset;
+      enum_constant_block::EnumConstantDataLayout::readRecord(scratch,
+                                                              tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      EnumConstantTable.reset(
+        SerializedEnumConstantTable::Create(base + tableOffset,
+                                            base + sizeof(uint32_t),
+                                            base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readTagBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(TAG_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case tag_block::TAG_DATA: {
+      // Already saw tag table.
+      if (TagTable)
+        return true;
+
+      uint32_t tableOffset;
+      tag_block::TagDataLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      TagTable.reset(
+        SerializedTagTable::Create(base + tableOffset,
+                                   base + sizeof(uint32_t),
+                                   base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+bool APINotesReader::Implementation::readTypedefBlock(
+       llvm::BitstreamCursor &cursor, 
+       SmallVectorImpl<uint64_t> &scratch) {
+  if (cursor.EnterSubBlock(TYPEDEF_BLOCK_ID))
+    return true;
+
+  auto next = cursor.advance();
+  while (next.Kind != llvm::BitstreamEntry::EndBlock) {
+    if (next.Kind == llvm::BitstreamEntry::Error)
+      return true;
+
+    if (next.Kind == llvm::BitstreamEntry::SubBlock) {
+      // Unknown sub-block, possibly for use by a future version of the
+      // API notes format.
+      if (cursor.SkipBlock())
+        return true;
+      
+      next = cursor.advance();
+      continue;
+    }
+
+    scratch.clear();
+    StringRef blobData;
+    unsigned kind = cursor.readRecord(next.ID, scratch, &blobData);
+    switch (kind) {
+    case typedef_block::TYPEDEF_DATA: {
+      // Already saw typedef table.
+      if (TypedefTable)
+        return true;
+
+      uint32_t tableOffset;
+      typedef_block::TypedefDataLayout::readRecord(scratch, tableOffset);
+      auto base = reinterpret_cast<const uint8_t *>(blobData.data());
+
+      TypedefTable.reset(
+        SerializedTypedefTable::Create(base + tableOffset,
+                                       base + sizeof(uint32_t),
+                                       base));
+      break;
+    }
+
+    default:
+      // Unknown record, possibly for use by a future version of the
+      // module format.
+      break;
+    }
+
+    next = cursor.advance();
+  }
+
+  return false;
+}
+
+APINotesReader::APINotesReader(llvm::MemoryBuffer *inputBuffer, 
+                               bool ownsInputBuffer,
+                               VersionTuple swiftVersion,
+                               bool &failed) 
+  : Impl(*new Implementation)
+{
+  failed = false;
+
+  // Initialize the input buffer.
+  Impl.InputBuffer = inputBuffer;
+  Impl.OwnsInputBuffer = ownsInputBuffer;
+  Impl.SwiftVersion = swiftVersion;
+  llvm::BitstreamCursor cursor(*Impl.InputBuffer);
+
+  // Validate signature.
+  for (auto byte : API_NOTES_SIGNATURE) {
+    if (cursor.AtEndOfStream() || cursor.Read(8) != byte) {
+      failed = true;
+      return;
+    }
+  }
+
+  // Look at all of the blocks.
+  bool hasValidControlBlock = false;
+  SmallVector<uint64_t, 64> scratch;
+  while (!cursor.AtEndOfStream()) {
+    auto topLevelEntry = cursor.advance();
+    if (topLevelEntry.Kind != llvm::BitstreamEntry::SubBlock)
+      break;
+
+    switch (topLevelEntry.ID) {
+    case llvm::bitc::BLOCKINFO_BLOCK_ID:
+      if (!cursor.ReadBlockInfoBlock()) {
+        failed = true;
+        break;
+      }
+      break;
+
+    case CONTROL_BLOCK_ID:
+      // Only allow a single control block.
+      if (hasValidControlBlock || Impl.readControlBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+
+      hasValidControlBlock = true;
+      break;
+
+    case IDENTIFIER_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readIdentifierBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case OBJC_CONTEXT_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readObjCContextBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+
+      break;
+
+    case OBJC_PROPERTY_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readObjCPropertyBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case OBJC_METHOD_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readObjCMethodBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case OBJC_SELECTOR_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readObjCSelectorBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case GLOBAL_VARIABLE_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readGlobalVariableBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case GLOBAL_FUNCTION_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readGlobalFunctionBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case ENUM_CONSTANT_BLOCK_ID:
+      if (!hasValidControlBlock || 
+          Impl.readEnumConstantBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case TAG_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readTagBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    case TYPEDEF_BLOCK_ID:
+      if (!hasValidControlBlock || Impl.readTypedefBlock(cursor, scratch)) {
+        failed = true;
+        return;
+      }
+      break;
+
+    default:
+      // Unknown top-level block, possibly for use by a future version of the
+      // module format.
+      if (cursor.SkipBlock()) {
+        failed = true;
+        return;
+      }
+      break;
+    }
+  }
+
+  if (!cursor.AtEndOfStream()) {
+    failed = true;
+    return;
+  }
+}
+
+APINotesReader::~APINotesReader() {
+  if (Impl.OwnsInputBuffer)
+    delete Impl.InputBuffer;
+
+  delete &Impl;
+}
+
+std::unique_ptr<APINotesReader> 
+APINotesReader::get(std::unique_ptr<llvm::MemoryBuffer> inputBuffer,
+                    VersionTuple swiftVersion) {
+  bool failed = false;
+  std::unique_ptr<APINotesReader> 
+    reader(new APINotesReader(inputBuffer.release(), /*ownsInputBuffer=*/true,
+                              swiftVersion, failed));
+  if (failed)
+    return nullptr;
+
+  return reader;
+}
+
+std::unique_ptr<APINotesReader> 
+APINotesReader::getUnmanaged(llvm::MemoryBuffer *inputBuffer,
+                             VersionTuple swiftVersion) {
+  bool failed = false;
+  std::unique_ptr<APINotesReader> 
+    reader(new APINotesReader(inputBuffer, /*ownsInputBuffer=*/false,
+                              swiftVersion, failed));
+  if (failed)
+    return nullptr;
+
+  return reader;
+}
+
+StringRef APINotesReader::getModuleName() const {
+  return Impl.ModuleName;
+}
+
+Optional<std::pair<off_t, time_t>>
+APINotesReader::getSourceFileSizeAndModTime() const {
+  return Impl.SourceFileSizeAndModTime;
+}
+
+ModuleOptions APINotesReader::getModuleOptions() const {
+  return Impl.ModuleOpts;
+}
+
+template<typename T>
+APINotesReader::VersionedInfo<T>::VersionedInfo(
+    VersionTuple version,
+    SmallVector<std::pair<VersionTuple, T>, 1> results)
+  : Results(std::move(results)) {
+
+  // Look for an exact version match.
+  Optional<unsigned> unversioned;
+  Selected = Results.size();
+
+  for (unsigned i = 0, n = Results.size(); i != n; ++i) {
+    if (Results[i].first == version) {
+      Selected = i;
+      break;
+    }
+
+    if (!Results[i].first) {
+      assert(!unversioned && "Two unversioned entries?");
+      unversioned = i;
+    }
+  }
+
+  // If we didn't find a match but we have an unversioned result, use the
+  // unversioned result.
+  if (Selected == Results.size() && unversioned) {
+    Selected = *unversioned;
+  }
+}
+
+auto APINotesReader::lookupObjCClassID(StringRef name) -> Optional<ContextID> {
+  if (!Impl.ObjCContextIDTable)
+    return None;
+
+  Optional<IdentifierID> classID = Impl.getIdentifier(name);
+  if (!classID)
+    return None;
+
+  auto knownID = Impl.ObjCContextIDTable->find({*classID, '\0'});
+  if (knownID == Impl.ObjCContextIDTable->end())
+    return None;
+
+  return ContextID(*knownID);
+}
+
+auto APINotesReader::lookupObjCClassInfo(StringRef name)
+       -> VersionedInfo<ObjCContextInfo> {
+  if (!Impl.ObjCContextInfoTable)
+    return None;
+
+  Optional<ContextID> contextID = lookupObjCClassID(name);
+  if (!contextID)
+    return None;
+
+  auto knownInfo = Impl.ObjCContextInfoTable->find(contextID->Value);
+  if (knownInfo == Impl.ObjCContextInfoTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *knownInfo };
+}
+
+auto APINotesReader::lookupObjCProtocolID(StringRef name)
+       -> Optional<ContextID> {
+   if (!Impl.ObjCContextIDTable)
+     return None;
+
+   Optional<IdentifierID> classID = Impl.getIdentifier(name);
+   if (!classID)
+     return None;
+
+   auto knownID = Impl.ObjCContextIDTable->find({*classID, '\1'});
+   if (knownID == Impl.ObjCContextIDTable->end())
+     return None;
+
+   return ContextID(*knownID);
+}
+
+auto APINotesReader::lookupObjCProtocolInfo(StringRef name)
+       -> VersionedInfo<ObjCContextInfo> {
+   if (!Impl.ObjCContextInfoTable)
+     return None;
+
+   Optional<ContextID> contextID = lookupObjCProtocolID(name);
+   if (!contextID)
+     return None;
+
+   auto knownInfo = Impl.ObjCContextInfoTable->find(contextID->Value);
+   if (knownInfo == Impl.ObjCContextInfoTable->end())
+     return None;
+   
+   return { Impl.SwiftVersion, *knownInfo };
+}
+
+
+auto APINotesReader::lookupObjCProperty(ContextID contextID,
+                                        StringRef name,
+                                        bool isInstance)
+    -> VersionedInfo<ObjCPropertyInfo> {
+  if (!Impl.ObjCPropertyTable)
+    return None;
+
+  Optional<IdentifierID> propertyID = Impl.getIdentifier(name);
+  if (!propertyID)
+    return None;
+
+  auto known = Impl.ObjCPropertyTable->find(std::make_tuple(contextID.Value,
+                                                            *propertyID,
+                                                            (char)isInstance));
+  if (known == Impl.ObjCPropertyTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupObjCMethod(
+                                      ContextID contextID,
+                                      ObjCSelectorRef selector,
+                                      bool isInstanceMethod)
+    -> VersionedInfo<ObjCMethodInfo> {
+  if (!Impl.ObjCMethodTable)
+    return None;
+
+  Optional<SelectorID> selectorID = Impl.getSelector(selector);
+  if (!selectorID)
+    return None;
+
+  auto known = Impl.ObjCMethodTable->find(
+      ObjCMethodTableInfo::internal_key_type{
+          contextID.Value, *selectorID, isInstanceMethod});
+  if (known == Impl.ObjCMethodTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupGlobalVariable(
+                                          StringRef name)
+    -> VersionedInfo<GlobalVariableInfo> {
+  if (!Impl.GlobalVariableTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.GlobalVariableTable->find(*nameID);
+  if (known == Impl.GlobalVariableTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupGlobalFunction(StringRef name)
+    -> VersionedInfo<GlobalFunctionInfo> {
+  if (!Impl.GlobalFunctionTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.GlobalFunctionTable->find(*nameID);
+  if (known == Impl.GlobalFunctionTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupEnumConstant(StringRef name)
+    -> VersionedInfo<EnumConstantInfo> {
+  if (!Impl.EnumConstantTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.EnumConstantTable->find(*nameID);
+  if (known == Impl.EnumConstantTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupTag(StringRef name) -> VersionedInfo<TagInfo> {
+  if (!Impl.TagTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.TagTable->find(*nameID);
+  if (known == Impl.TagTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+auto APINotesReader::lookupTypedef(StringRef name)
+    -> VersionedInfo<TypedefInfo> {
+  if (!Impl.TypedefTable)
+    return None;
+
+  Optional<IdentifierID> nameID = Impl.getIdentifier(name);
+  if (!nameID)
+    return None;
+
+  auto known = Impl.TypedefTable->find(*nameID);
+  if (known == Impl.TypedefTable->end())
+    return None;
+
+  return { Impl.SwiftVersion, *known };
+}
+
+APINotesReader::Visitor::~Visitor() { }
+
+void APINotesReader::Visitor::visitObjCClass(
+       ContextID contextID,
+       StringRef name,
+       const ObjCContextInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitObjCProtocol(
+       ContextID contextID,
+       StringRef name,
+       const ObjCContextInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitObjCMethod(
+       ContextID contextID,
+       StringRef selector,
+       bool isInstanceMethod,
+       const ObjCMethodInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitObjCProperty(
+       ContextID contextID,
+       StringRef name,
+       bool isInstance,
+       const ObjCPropertyInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitGlobalVariable(
+       StringRef name,
+       const GlobalVariableInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitGlobalFunction(
+       StringRef name,
+       const GlobalFunctionInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitEnumConstant(
+       StringRef name,
+       const EnumConstantInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitTag(
+       StringRef name,
+       const TagInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::Visitor::visitTypedef(
+       StringRef name,
+       const TypedefInfo &info,
+       VersionTuple swiftVersion) { }
+
+void APINotesReader::visit(Visitor &visitor) {
+  // FIXME: All of these iterations would be significantly more efficient if we
+  // could get the keys and data together, but OnDiskIterableHashTable doesn't
+  // support that.
+
+  // Build an identifier ID -> string mapping, which we'll need when visiting
+  // any of the tables.
+  llvm::DenseMap<unsigned, StringRef> identifiers;
+  if (Impl.IdentifierTable) {
+    for (auto key : Impl.IdentifierTable->keys()) {
+      unsigned ID = *Impl.IdentifierTable->find(key);
+      assert(identifiers.count(ID) == 0);
+      identifiers[ID] = key;
+    }
+  }
+
+  // Visit classes and protocols.
+  if (Impl.ObjCContextIDTable && Impl.ObjCContextInfoTable) {
+    for (auto key : Impl.ObjCContextIDTable->keys()) {
+      auto name = identifiers[key.first];
+      auto contextID = *Impl.ObjCContextIDTable->find(key);
+
+      auto knownInfo = Impl.ObjCContextInfoTable->find(contextID);
+      if (knownInfo == Impl.ObjCContextInfoTable->end()) continue;
+
+      for (const auto &versioned : *knownInfo) {
+        if (key.second)
+          visitor.visitObjCProtocol(ContextID(contextID), name,
+                                    versioned.second, versioned.first);
+        else
+          visitor.visitObjCClass(ContextID(contextID), name, versioned.second,
+                                 versioned.first);
+      }
+    }
+  }
+
+  // Build a selector ID -> stored Objective-C selector mapping, which we need
+  // when visiting the method tables.
+  llvm::DenseMap<unsigned, std::string> selectors;
+  if (Impl.ObjCSelectorTable) {
+    for (auto key : Impl.ObjCSelectorTable->keys()) {
+      std::string selector;
+      if (key.NumPieces == 0)
+        selector = identifiers[key.Identifiers[0]];
+      else {
+        for (auto identID : key.Identifiers) {
+          selector += identifiers[identID];
+          selector += ':';
+        }
+      }
+
+      unsigned selectorID = *Impl.ObjCSelectorTable->find(key);
+      selectors[selectorID] = selector;
+    }
+  }
+
+  // Visit methods.
+  if (Impl.ObjCMethodTable) {
+    for (auto key : Impl.ObjCMethodTable->keys()) {
+      ContextID contextID(std::get<0>(key));
+      const auto &selector = selectors[std::get<1>(key)];
+      for (const auto &versioned : *Impl.ObjCMethodTable->find(key))
+        visitor.visitObjCMethod(contextID, selector, std::get<2>(key),
+                                versioned.second, versioned.first);
+    }
+  }
+
+  // Visit properties.
+  if (Impl.ObjCPropertyTable) {
+    for (auto key : Impl.ObjCPropertyTable->keys()) {
+      ContextID contextID(std::get<0>(key));
+      auto name = identifiers[std::get<1>(key)];
+      char isInstance = std::get<2>(key);
+      for (const auto &versioned : *Impl.ObjCPropertyTable->find(key)) {
+        visitor.visitObjCProperty(contextID, name, isInstance, versioned.second,
+                                  versioned.first);
+      }
+    }
+  }
+
+  // Visit global functions.
+  if (Impl.GlobalFunctionTable) {
+    for (auto key : Impl.GlobalFunctionTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.GlobalFunctionTable->find(key))
+        visitor.visitGlobalFunction(name, versioned.second, versioned.first);
+    }
+  }
+
+  // Visit global variables.
+  if (Impl.GlobalVariableTable) {
+    for (auto key : Impl.GlobalVariableTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.GlobalVariableTable->find(key))
+        visitor.visitGlobalVariable(name, versioned.second, versioned.first);
+    }
+  }
+
+  // Visit global variables.
+  if (Impl.EnumConstantTable) {
+    for (auto key : Impl.EnumConstantTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.EnumConstantTable->find(key))
+        visitor.visitEnumConstant(name, versioned.second, versioned.first);
+    }
+  }
+
+  // Visit tags.
+  if (Impl.TagTable) {
+    for (auto key : Impl.TagTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.TagTable->find(key))
+        visitor.visitTag(name, versioned.second, versioned.first);
+    }
+  }
+
+  // Visit typedefs.
+  if (Impl.TypedefTable) {
+    for (auto key : Impl.TypedefTable->keys()) {
+      auto name = identifiers[key];
+      for (const auto &versioned : *Impl.TypedefTable->find(key))
+        visitor.visitTypedef(name, versioned.second, versioned.first);
+    }
+  }
+}
+
diff --git a/lib/APINotes/APINotesWriter.cpp b/lib/APINotes/APINotesWriter.cpp
new file mode 100644
index 0000000..285a35e
--- /dev/null
+++ b/lib/APINotes/APINotesWriter.cpp
@@ -0,0 +1,1322 @@
+//===--- APINotesWriter.cpp - API Notes Writer --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the \c APINotesWriter class that writes out
+// source API notes data providing additional information about source
+// code as a separate input, such as the non-nil/nilable annotations
+// for method parameters.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/APINotesWriter.h"
+#include "APINotesFormat.h"
+#include "clang/Basic/FileManager.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/OnDiskHashTable.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/DataTypes.h"
+#include <tuple>
+#include <vector>
+using namespace clang;
+using namespace api_notes;
+using namespace llvm::support;
+
+namespace {
+  template<typename T> using VersionedSmallVector =
+    SmallVector<std::pair<VersionTuple, T>, 1>;
+}
+
+class APINotesWriter::Implementation {
+  /// Mapping from strings to identifier IDs.
+  llvm::StringMap<IdentifierID> IdentifierIDs;
+
+  /// Mapping from selectors to selector ID.
+  llvm::DenseMap<StoredObjCSelector, SelectorID> SelectorIDs;
+
+  /// Scratch space for bitstream writing.
+  SmallVector<uint64_t, 64> ScratchRecord;
+
+public:
+  /// The name of the module
+  std::string ModuleName;
+
+  /// The source file from which this binary representation was
+  /// created, if known.
+  const FileEntry *SourceFile;
+
+  bool SwiftInferImportAsMember = false;
+
+  /// Information about Objective-C contexts (classes or protocols).
+  ///
+  /// Indexed by the identifier ID and a bit indication whether we're looking
+  /// for a class (0) or protocol (1) and provides both the context ID and
+  /// information describing the context within that module.
+  llvm::DenseMap<std::pair<unsigned, char>,
+                 std::pair<unsigned, VersionedSmallVector<ObjCContextInfo>>>
+    ObjCContexts;
+
+  /// Mapping from context IDs to the identifier ID holding the name.
+  llvm::DenseMap<unsigned, unsigned> ObjCContextNames;
+
+  /// Information about Objective-C properties.
+  ///
+  /// Indexed by the context ID, property name, and whether this is an
+  /// instance property.
+  llvm::DenseMap<std::tuple<unsigned, unsigned, char>,
+                 llvm::SmallVector<std::pair<VersionTuple, ObjCPropertyInfo>,
+                 1>>
+    ObjCProperties;
+
+  /// Information about Objective-C methods.
+  ///
+  /// Indexed by the context ID, selector ID, and Boolean (stored as a
+  /// char) indicating whether this is a class or instance method.
+  llvm::DenseMap<std::tuple<unsigned, unsigned, char>,
+                 llvm::SmallVector<std::pair<VersionTuple, ObjCMethodInfo>, 1>>
+    ObjCMethods;
+
+  /// Information about global variables.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, GlobalVariableInfo>,
+                                   1>>
+    GlobalVariables;
+
+  /// Information about global functions.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, GlobalFunctionInfo>,
+                                   1>>
+    GlobalFunctions;
+
+  /// Information about enumerators.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, EnumConstantInfo>,
+                                   1>>
+    EnumConstants;
+
+  /// Information about tags.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, TagInfo>, 1>>
+    Tags;
+
+  /// Information about typedefs.
+  ///
+  /// Indexed by the identifier ID.
+  llvm::DenseMap<unsigned,
+                 llvm::SmallVector<std::pair<VersionTuple, TypedefInfo>, 1>>
+    Typedefs;
+
+  /// Retrieve the ID for the given identifier.
+  IdentifierID getIdentifier(StringRef identifier) {
+    if (identifier.empty())
+      return 0;
+
+    auto known = IdentifierIDs.find(identifier);
+    if (known != IdentifierIDs.end())
+      return known->second;
+
+    // Add to the identifier table.
+    known = IdentifierIDs.insert({identifier, IdentifierIDs.size() + 1}).first;
+    return known->second;
+  }
+
+  /// Retrieve the ID for the given selector.
+  SelectorID getSelector(ObjCSelectorRef selectorRef) {
+    // Translate the selector reference into a stored selector.
+    StoredObjCSelector selector;
+    selector.NumPieces = selectorRef.NumPieces;
+    selector.Identifiers.reserve(selectorRef.Identifiers.size());
+    for (auto piece : selectorRef.Identifiers) {
+      selector.Identifiers.push_back(getIdentifier(piece));
+    }
+
+    // Look for the stored selector.
+    auto known = SelectorIDs.find(selector);
+    if (known != SelectorIDs.end())
+      return known->second;
+
+    // Add to the selector table.
+    known = SelectorIDs.insert({selector, SelectorIDs.size()}).first;
+    return known->second;
+  }
+
+  void writeToStream(llvm::raw_ostream &os);
+
+private:
+  void writeBlockInfoBlock(llvm::BitstreamWriter &writer);
+  void writeControlBlock(llvm::BitstreamWriter &writer);
+  void writeIdentifierBlock(llvm::BitstreamWriter &writer);
+  void writeObjCContextBlock(llvm::BitstreamWriter &writer);
+  void writeObjCPropertyBlock(llvm::BitstreamWriter &writer);
+  void writeObjCMethodBlock(llvm::BitstreamWriter &writer);
+  void writeObjCSelectorBlock(llvm::BitstreamWriter &writer);
+  void writeGlobalVariableBlock(llvm::BitstreamWriter &writer);
+  void writeGlobalFunctionBlock(llvm::BitstreamWriter &writer);
+  void writeEnumConstantBlock(llvm::BitstreamWriter &writer);
+  void writeTagBlock(llvm::BitstreamWriter &writer);
+  void writeTypedefBlock(llvm::BitstreamWriter &writer);
+};
+
+/// Record the name of a block.
+static void emitBlockID(llvm::BitstreamWriter &out, unsigned ID,
+                        StringRef name,
+                        SmallVectorImpl<unsigned char> &nameBuffer) {
+  SmallVector<unsigned, 1> idBuffer;
+  idBuffer.push_back(ID);
+  out.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, idBuffer);
+
+  // Emit the block name if present.
+  if (name.empty())
+    return;
+  nameBuffer.resize(name.size());
+  memcpy(nameBuffer.data(), name.data(), name.size());
+  out.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, nameBuffer);
+}
+
+/// Record the name of a record within a block.
+static void emitRecordID(llvm::BitstreamWriter &out, unsigned ID,
+                         StringRef name,
+                         SmallVectorImpl<unsigned char> &nameBuffer) {
+  assert(ID < 256 && "can't fit record ID in next to name");
+  nameBuffer.resize(name.size()+1);
+  nameBuffer[0] = ID;
+  memcpy(nameBuffer.data()+1, name.data(), name.size());
+  out.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, nameBuffer);
+}
+
+void APINotesWriter::Implementation::writeBlockInfoBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, llvm::bitc::BLOCKINFO_BLOCK_ID, 2);  
+
+  SmallVector<unsigned char, 64> nameBuffer;
+#define BLOCK(X) emitBlockID(writer, X ## _ID, #X, nameBuffer)
+#define BLOCK_RECORD(K, X) emitRecordID(writer, K::X, #X, nameBuffer)
+
+  BLOCK(CONTROL_BLOCK);
+  BLOCK_RECORD(control_block, METADATA);
+  BLOCK_RECORD(control_block, MODULE_NAME);
+
+  BLOCK(IDENTIFIER_BLOCK);
+  BLOCK_RECORD(identifier_block, IDENTIFIER_DATA);
+
+  BLOCK(OBJC_CONTEXT_BLOCK);
+  BLOCK_RECORD(objc_context_block, OBJC_CONTEXT_ID_DATA);
+
+  BLOCK(OBJC_PROPERTY_BLOCK);
+  BLOCK_RECORD(objc_property_block, OBJC_PROPERTY_DATA);
+
+  BLOCK(OBJC_METHOD_BLOCK);
+  BLOCK_RECORD(objc_method_block, OBJC_METHOD_DATA);
+
+  BLOCK(OBJC_SELECTOR_BLOCK);
+  BLOCK_RECORD(objc_selector_block, OBJC_SELECTOR_DATA);
+
+  BLOCK(GLOBAL_VARIABLE_BLOCK);
+  BLOCK_RECORD(global_variable_block, GLOBAL_VARIABLE_DATA);
+
+  BLOCK(GLOBAL_FUNCTION_BLOCK);
+  BLOCK_RECORD(global_function_block, GLOBAL_FUNCTION_DATA);
+#undef BLOCK
+#undef BLOCK_RECORD
+}
+
+void APINotesWriter::Implementation::writeControlBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, CONTROL_BLOCK_ID, 3);
+  control_block::MetadataLayout metadata(writer);
+  metadata.emit(ScratchRecord, VERSION_MAJOR, VERSION_MINOR);
+
+  control_block::ModuleNameLayout moduleName(writer);
+  moduleName.emit(ScratchRecord, ModuleName);
+
+  if (SwiftInferImportAsMember) {
+    control_block::ModuleOptionsLayout moduleOptions(writer);
+    moduleOptions.emit(ScratchRecord, SwiftInferImportAsMember);
+  }
+
+  if (SourceFile) {
+    control_block::SourceFileLayout sourceFile(writer);
+    sourceFile.emit(ScratchRecord, SourceFile->getSize(),
+                    SourceFile->getModificationTime());
+  }
+}
+
+namespace {
+  /// Used to serialize the on-disk identifier table.
+  class IdentifierTableInfo {
+  public:
+    using key_type = StringRef;
+    using key_type_ref = key_type;
+    using data_type = IdentifierID;
+    using data_type_ref = const data_type &;
+    using hash_value_type = uint32_t;
+    using offset_type = unsigned;
+
+    hash_value_type ComputeHash(key_type_ref key) {
+      return llvm::HashString(key);
+    }
+
+    std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &out,
+                                                    key_type_ref key,
+                                                    data_type_ref data) {
+      uint32_t keyLength = key.size();
+      uint32_t dataLength = sizeof(uint32_t);
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(keyLength);
+      writer.write<uint16_t>(dataLength);
+      return { keyLength, dataLength };
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      out << key;
+    }
+
+    void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
+                  unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(data);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeIdentifierBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, IDENTIFIER_BLOCK_ID, 3);
+
+  if (IdentifierIDs.empty())
+    return;
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<IdentifierTableInfo> generator;
+    for (auto &entry : IdentifierIDs)
+      generator.insert(entry.first(), entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  identifier_block::IdentifierDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Retrieve the serialized size of the given CommonEntityInfo, for use in
+  /// on-disk hash tables.
+  static unsigned getCommonEntityInfoSize(const CommonEntityInfo &info) {
+    return 5 + info.UnavailableMsg.size() + info.SwiftName.size();
+  }
+
+  /// Emit a serialized representation of the common entity information.
+  static void emitCommonEntityInfo(raw_ostream &out,
+                                   const CommonEntityInfo &info) {
+    endian::Writer<little> writer(out);
+    uint8_t payload = 0;
+    if (auto swiftPrivate = info.isSwiftPrivate()) {
+      payload |= 0x01;
+      if (*swiftPrivate) payload |= 0x02;
+    }
+    payload <<= 1;
+    payload |= info.Unavailable;
+    payload <<= 1;
+    payload |= info.UnavailableInSwift;
+
+    writer.write<uint8_t>(payload);
+
+    writer.write<uint16_t>(info.UnavailableMsg.size());
+    out.write(info.UnavailableMsg.c_str(), info.UnavailableMsg.size());
+    writer.write<uint16_t>(info.SwiftName.size());
+    out.write(info.SwiftName.c_str(), info.SwiftName.size());
+  }
+
+  // Retrieve the serialized size of the given CommonTypeInfo, for use
+  // in on-disk hash tables.
+  static unsigned getCommonTypeInfoSize(const CommonTypeInfo &info) {
+    return 2 + (info.getSwiftBridge() ? info.getSwiftBridge()->size() : 0) +
+           2 + (info.getNSErrorDomain() ? info.getNSErrorDomain()->size() : 0) +
+           getCommonEntityInfoSize(info);
+  }
+
+  /// Emit a serialized representation of the common type information.
+  static void emitCommonTypeInfo(raw_ostream &out, const CommonTypeInfo &info) {
+    emitCommonEntityInfo(out, info);
+    endian::Writer<little> writer(out);
+    if (auto swiftBridge = info.getSwiftBridge()) {
+      writer.write<uint16_t>(swiftBridge->size() + 1);
+      out.write(swiftBridge->c_str(), swiftBridge->size());
+    } else {
+      writer.write<uint16_t>(0);
+    }
+    if (auto nsErrorDomain = info.getNSErrorDomain()) {
+      writer.write<uint16_t>(nsErrorDomain->size() + 1);
+      out.write(nsErrorDomain->c_str(), info.getNSErrorDomain()->size());
+    } else {
+      writer.write<uint16_t>(0);
+    }
+  }
+
+  /// Used to serialize the on-disk Objective-C context table.
+  class ObjCContextIDTableInfo {
+  public:
+    using key_type = std::pair<unsigned, char>; // identifier ID, is-protocol
+    using key_type_ref = key_type;
+    using data_type = unsigned;
+    using data_type_ref = const data_type &;
+    using hash_value_type = size_t;
+    using offset_type = unsigned;
+
+    hash_value_type ComputeHash(key_type_ref key) {
+      return static_cast<size_t>(llvm::hash_value(key));
+    }
+
+    std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &out,
+                                                    key_type_ref key,
+                                                    data_type_ref data) {
+      uint32_t keyLength = sizeof(uint32_t) + 1;
+      uint32_t dataLength = sizeof(uint32_t);
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(keyLength);
+      writer.write<uint16_t>(dataLength);
+      return { keyLength, dataLength };
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key.first);
+      writer.write<uint8_t>(key.second);
+    }
+
+    void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
+                  unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(data);
+    }
+  };
+} // end anonymous namespace
+
+namespace {
+  /// Retrieve the serialized size of the given VersionTuple, for use in
+  /// on-disk hash tables.
+  unsigned getVersionTupleSize(const VersionTuple &version) {
+    unsigned size = sizeof(uint8_t) + /*major*/sizeof(uint32_t);
+    if (version.getMinor()) size += sizeof(uint32_t);
+    if (version.getSubminor()) size += sizeof(uint32_t);
+    if (version.getBuild()) size += sizeof(uint32_t);
+    return size;
+  }
+
+  /// Emit a serialized representation of a version tuple.
+  void emitVersionTuple(raw_ostream &out, const VersionTuple &version) {
+    endian::Writer<little> writer(out);
+
+    // First byte contains the number of components beyond the 'major'
+    // component.
+    uint8_t descriptor;
+    if (version.getBuild()) descriptor = 3;
+    else if (version.getSubminor()) descriptor = 2;
+    else if (version.getMinor()) descriptor = 1;
+    else descriptor = 0;
+    assert(!version.usesUnderscores() && "Not a serializable version");
+    writer.write<uint8_t>(descriptor);
+
+    // Write the components.
+    writer.write<uint32_t>(version.getMajor());
+    if (auto minor = version.getMinor())
+      writer.write<uint32_t>(*minor);
+    if (auto subminor = version.getSubminor())
+      writer.write<uint32_t>(*subminor);
+    if (auto build = version.getBuild())
+      writer.write<uint32_t>(*build);
+  }
+
+  /// Localized helper to make a type dependent, thwarting template argument
+  /// deduction.
+  template<typename T>
+  struct MakeDependent {
+    typedef T Type;
+  };
+
+  /// Determine the size of an array of versioned information,
+  template<typename T>
+  unsigned getVersionedInfoSize(
+             const SmallVectorImpl<std::pair<VersionTuple, T>> &infoArray,
+            llvm::function_ref<unsigned(const typename MakeDependent<T>::Type&)>
+              getInfoSize) {
+    unsigned result = sizeof(uint16_t); // # of elements
+    for (const auto &element : infoArray) {
+      result += getVersionTupleSize(element.first);
+      result += getInfoSize(element.second);
+    }
+
+    return result;
+  }
+
+  /// Emit versioned information.
+  template<typename T>
+  void emitVersionedInfo(
+         raw_ostream &out,
+         const SmallVectorImpl<std::pair<VersionTuple, T>> &infoArray,
+         llvm::function_ref<void(raw_ostream &out,
+                                 const typename MakeDependent<T>::Type& info)>
+           emitInfo) {
+    endian::Writer<little> writer(out);
+    writer.write<uint16_t>(infoArray.size());
+    for (const auto &element : infoArray) {
+      emitVersionTuple(out, element.first);
+      emitInfo(out, element.second);
+    }
+  }
+
+  /// Retrieve the serialized size of the given VariableInfo, for use in
+  /// on-disk hash tables.
+  unsigned getVariableInfoSize(const VariableInfo &info) {
+    return 2 + getCommonEntityInfoSize(info) + 2 + info.getType().size();
+  }
+
+  /// Emit a serialized representation of the variable information.
+  void emitVariableInfo(raw_ostream &out, const VariableInfo &info) {
+    emitCommonEntityInfo(out, info);
+
+    uint8_t bytes[2] = { 0, 0 };
+    if (auto nullable = info.getNullability()) {
+      bytes[0] = 1;
+      bytes[1] = static_cast<uint8_t>(*nullable);
+    } else {
+      // Nothing to do.
+    }
+
+    out.write(reinterpret_cast<const char *>(bytes), 2);
+
+    endian::Writer<little> writer(out);
+    writer.write<uint16_t>(info.getType().size());
+    out.write(info.getType().data(), info.getType().size());
+  }
+
+  /// On-dish hash table info key base for handling versioned data.
+  template<typename Derived, typename KeyType, typename UnversionedDataType>
+  class VersionedTableInfo {
+    Derived &asDerived() {
+      return *static_cast<Derived *>(this);
+    }
+
+    const Derived &asDerived() const {
+      return *static_cast<const Derived *>(this);
+    }
+
+  public:
+    using key_type = KeyType;
+    using key_type_ref = key_type;
+    using data_type =
+      SmallVector<std::pair<VersionTuple, UnversionedDataType>, 1>;
+    using data_type_ref = const data_type &;
+    using hash_value_type = size_t;
+    using offset_type = unsigned;
+
+    hash_value_type ComputeHash(key_type_ref key) {
+      return llvm::hash_value(key);
+    }
+
+    std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &out,
+                                                    key_type_ref key,
+                                                    data_type_ref data) {
+      uint32_t keyLength = asDerived().getKeyLength(key);
+      uint32_t dataLength = getVersionedInfoSize(data,
+        [this](const UnversionedDataType &unversionedInfo) {
+          return asDerived().getUnversionedInfoSize(unversionedInfo);
+      });
+
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(keyLength);
+      writer.write<uint16_t>(dataLength);
+      return { keyLength, dataLength };
+    }
+
+    void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
+                  unsigned len) {
+      emitVersionedInfo(out, data,
+        [this](llvm::raw_ostream &out,
+               const UnversionedDataType &unversionedInfo) {
+          asDerived().emitUnversionedInfo(out, unversionedInfo);
+      });
+    }
+  };
+
+  /// Used to serialize the on-disk Objective-C property table.
+  class ObjCContextInfoTableInfo
+    : public VersionedTableInfo<ObjCContextInfoTableInfo,
+                                unsigned,
+                                ObjCContextInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const ObjCContextInfo &info) {
+      return getCommonTypeInfoSize(info) + 1;
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const ObjCContextInfo &info) {
+      emitCommonTypeInfo(out, info);
+
+      uint8_t payload = 0;
+      if (auto swiftImportAsNonGeneric = info.getSwiftImportAsNonGeneric()) {
+        payload |= (0x01 << 1) | swiftImportAsNonGeneric.getValue();
+      }
+      payload <<= 2;
+      if (auto swiftObjCMembers = info.getSwiftObjCMembers()) {
+        payload |= (0x01 << 1) | swiftObjCMembers.getValue();
+      }
+      payload <<= 3;
+      if (auto nullable = info.getDefaultNullability()) {
+        payload |= (0x01 << 2) | static_cast<uint8_t>(*nullable);
+      }
+      payload = (payload << 1) | (info.hasDesignatedInits() ? 1 : 0);
+      out << payload;
+    }
+  };
+
+  /// Used to serialize the on-disk Objective-C property table.
+  class ObjCPropertyTableInfo
+    : public VersionedTableInfo<ObjCPropertyTableInfo,
+                                std::tuple<unsigned, unsigned, char>,
+                                ObjCPropertyInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint8_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(std::get<0>(key));
+      writer.write<uint32_t>(std::get<1>(key));
+      writer.write<uint8_t>(std::get<2>(key));
+    }
+
+    unsigned getUnversionedInfoSize(const ObjCPropertyInfo &info) {
+      return getVariableInfoSize(info) + 1;
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const ObjCPropertyInfo &info) {
+      emitVariableInfo(out, info);
+      uint8_t flags = 0;
+      if (Optional<bool> value = info.getSwiftImportAsAccessors()) {
+        flags |= 1 << 0;
+        flags |= value.getValue() << 1;
+      }
+      out << flags;
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeObjCContextBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, OBJC_CONTEXT_BLOCK_ID, 3);
+
+  if (ObjCContexts.empty())
+    return;  
+
+  {
+    llvm::SmallString<4096> hashTableBlob;
+    uint32_t tableOffset;
+    {
+      llvm::OnDiskChainedHashTableGenerator<ObjCContextIDTableInfo> generator;
+      for (auto &entry : ObjCContexts)
+        generator.insert(entry.first, entry.second.first);
+
+      llvm::raw_svector_ostream blobStream(hashTableBlob);
+      // Make sure that no bucket is at offset 0
+      endian::Writer<little>(blobStream).write<uint32_t>(0);
+      tableOffset = generator.Emit(blobStream);
+    }
+
+    objc_context_block::ObjCContextIDLayout layout(writer);
+    layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+  }
+
+  {
+    llvm::SmallString<4096> hashTableBlob;
+    uint32_t tableOffset;
+    {
+      llvm::OnDiskChainedHashTableGenerator<ObjCContextInfoTableInfo>
+        generator;
+      for (auto &entry : ObjCContexts)
+        generator.insert(entry.second.first, entry.second.second);
+
+      llvm::raw_svector_ostream blobStream(hashTableBlob);
+      // Make sure that no bucket is at offset 0
+      endian::Writer<little>(blobStream).write<uint32_t>(0);
+      tableOffset = generator.Emit(blobStream);
+    }
+
+    objc_context_block::ObjCContextInfoLayout layout(writer);
+    layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+  }
+}
+
+void APINotesWriter::Implementation::writeObjCPropertyBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, OBJC_PROPERTY_BLOCK_ID, 3);
+
+  if (ObjCProperties.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<ObjCPropertyTableInfo> generator;
+    for (auto &entry : ObjCProperties)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  objc_property_block::ObjCPropertyDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  static unsigned getParamInfoSize(const ParamInfo &info) {
+    return getVariableInfoSize(info) + 1;
+  }
+
+  static void emitParamInfo(raw_ostream &out, const ParamInfo &info) {
+    emitVariableInfo(out, info);
+
+    endian::Writer<little> writer(out);
+
+    uint8_t payload = 0;
+    if (auto noescape = info.isNoEscape()) {
+      payload |= 0x01;
+      if (*noescape)
+        payload |= 0x02;
+    }
+    writer.write<uint8_t>(payload);
+  }
+
+  /// Retrieve the serialized size of the given FunctionInfo, for use in
+  /// on-disk hash tables.
+  static unsigned getFunctionInfoSize(const FunctionInfo &info) {
+    unsigned size = 2 + sizeof(uint64_t) + getCommonEntityInfoSize(info) + 2;
+
+    for (const auto &param : info.Params)
+      size += getParamInfoSize(param);
+
+    size += 2 + info.ResultType.size();
+    return size;
+  }
+
+  /// Emit a serialized representation of the function information.
+  static void emitFunctionInfo(raw_ostream &out, const FunctionInfo &info) {
+    emitCommonEntityInfo(out, info);
+
+    endian::Writer<little> writer(out);
+    writer.write<uint8_t>(info.NullabilityAudited);
+    writer.write<uint8_t>(info.NumAdjustedNullable);
+    writer.write<uint64_t>(info.NullabilityPayload);
+
+    // Parameters.
+    writer.write<uint16_t>(info.Params.size());
+    for (const auto &pi : info.Params)
+      emitParamInfo(out, pi);
+
+    // Result type.
+    writer.write<uint16_t>(info.ResultType.size());
+    out.write(info.ResultType.data(), info.ResultType.size());
+  }
+
+  /// Used to serialize the on-disk Objective-C method table.
+  class ObjCMethodTableInfo
+    : public VersionedTableInfo<ObjCMethodTableInfo,
+                                std::tuple<unsigned, unsigned, char>,
+                                ObjCMethodInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t) + sizeof(uint32_t) + 1;
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(std::get<0>(key));
+      writer.write<uint32_t>(std::get<1>(key));
+      writer.write<uint8_t>(std::get<2>(key));
+    }
+
+    unsigned getUnversionedInfoSize(const ObjCMethodInfo &info) {
+      return 1 + getFunctionInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const ObjCMethodInfo &info) {
+      uint8_t payload = 0;
+      payload = (payload << 1) | info.DesignatedInit;
+      payload = (payload << 1) | info.Required;
+      endian::Writer<little> writer(out);
+      writer.write<uint8_t>(payload);
+
+      emitFunctionInfo(out, info);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeObjCMethodBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, OBJC_METHOD_BLOCK_ID, 3);
+
+  if (ObjCMethods.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<ObjCMethodTableInfo> generator;
+    for (auto &entry : ObjCMethods) {
+      generator.insert(entry.first, entry.second);
+    }
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  objc_method_block::ObjCMethodDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk Objective-C selector table.
+  class ObjCSelectorTableInfo {
+  public:
+    using key_type = StoredObjCSelector;
+    using key_type_ref = const key_type &;
+    using data_type = SelectorID;
+    using data_type_ref = data_type;
+    using hash_value_type = unsigned;
+    using offset_type = unsigned;
+
+    hash_value_type ComputeHash(key_type_ref key) {
+      return llvm::DenseMapInfo<StoredObjCSelector>::getHashValue(key);
+    }
+
+    std::pair<unsigned, unsigned> EmitKeyDataLength(raw_ostream &out,
+                                                    key_type_ref key,
+                                                    data_type_ref data) {
+      uint32_t keyLength = sizeof(uint16_t) 
+                         + sizeof(uint32_t) * key.Identifiers.size();
+      uint32_t dataLength = sizeof(uint32_t);
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(keyLength);
+      writer.write<uint16_t>(dataLength);
+      return { keyLength, dataLength };
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint16_t>(key.NumPieces);
+      for (auto piece : key.Identifiers) {
+        writer.write<uint32_t>(piece);
+      }
+    }
+
+    void EmitData(raw_ostream &out, key_type_ref key, data_type_ref data,
+                  unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(data);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeObjCSelectorBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, OBJC_SELECTOR_BLOCK_ID, 3);
+
+  if (SelectorIDs.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<ObjCSelectorTableInfo> generator;
+    for (auto &entry : SelectorIDs)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  objc_selector_block::ObjCSelectorDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk global variable table.
+  class GlobalVariableTableInfo
+    : public VersionedTableInfo<GlobalVariableTableInfo,
+                                unsigned,
+                                GlobalVariableInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref key) {
+      return sizeof(uint32_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const GlobalVariableInfo &info) {
+      return getVariableInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out,
+                             const GlobalVariableInfo &info) {
+      emitVariableInfo(out, info);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeGlobalVariableBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, GLOBAL_VARIABLE_BLOCK_ID, 3);
+
+  if (GlobalVariables.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<GlobalVariableTableInfo> generator;
+    for (auto &entry : GlobalVariables)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  global_variable_block::GlobalVariableDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk global function table.
+  class GlobalFunctionTableInfo
+    : public VersionedTableInfo<GlobalFunctionTableInfo,
+                                unsigned,
+                                GlobalFunctionInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const GlobalFunctionInfo &info) {
+      return getFunctionInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out,
+                             const GlobalFunctionInfo &info) {
+      emitFunctionInfo(out, info);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeGlobalFunctionBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, GLOBAL_FUNCTION_BLOCK_ID, 3);
+
+  if (GlobalFunctions.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<GlobalFunctionTableInfo> generator;
+    for (auto &entry : GlobalFunctions) {
+      generator.insert(entry.first, entry.second);
+    }
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  global_function_block::GlobalFunctionDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk global enum constant.
+  class EnumConstantTableInfo
+    : public VersionedTableInfo<EnumConstantTableInfo,
+                                unsigned,
+                                EnumConstantInfo> {
+  public:
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(uint32_t);
+    }
+
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<uint32_t>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const EnumConstantInfo &info) {
+      return getCommonEntityInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const EnumConstantInfo &info) {
+      emitCommonEntityInfo(out, info);
+    }
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeEnumConstantBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, ENUM_CONSTANT_BLOCK_ID, 3);
+
+  if (EnumConstants.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<EnumConstantTableInfo> generator;
+    for (auto &entry : EnumConstants)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  enum_constant_block::EnumConstantDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  template<typename Derived, typename UnversionedDataType>
+  class CommonTypeTableInfo
+    : public VersionedTableInfo<Derived, unsigned, UnversionedDataType> {
+  public:
+    using key_type_ref = typename CommonTypeTableInfo::key_type_ref;
+
+    unsigned getKeyLength(key_type_ref) {
+      return sizeof(IdentifierID);
+    }
+    void EmitKey(raw_ostream &out, key_type_ref key, unsigned len) {
+      endian::Writer<little> writer(out);
+      writer.write<IdentifierID>(key);
+    }
+
+    unsigned getUnversionedInfoSize(const UnversionedDataType &info) {
+      return getCommonTypeInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out,
+                             const UnversionedDataType &info) {
+      emitCommonTypeInfo(out, info);
+    }
+  };
+
+  /// Used to serialize the on-disk tag table.
+  class TagTableInfo : public CommonTypeTableInfo<TagTableInfo, TagInfo> {
+  public:
+    unsigned getUnversionedInfoSize(const TagInfo &info) {
+      return 1 + getCommonTypeInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const TagInfo &info) {
+      endian::Writer<little> writer(out);
+
+      uint8_t payload = 0;
+      if (auto enumExtensibility = info.EnumExtensibility) {
+        payload |= static_cast<uint8_t>(enumExtensibility.getValue()) + 1;
+        assert((payload < (1 << 2)) && "must fit in two bits");
+      }
+
+      payload <<= 2;
+      if (Optional<bool> value = info.isFlagEnum()) {
+        payload |= 1 << 0;
+        payload |= value.getValue() << 1;
+      }
+
+      writer.write<uint8_t>(payload);
+
+      emitCommonTypeInfo(out, info);
+    }
+  };
+
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeTagBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, TAG_BLOCK_ID, 3);
+
+  if (Tags.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<TagTableInfo> generator;
+    for (auto &entry : Tags)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  tag_block::TagDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+namespace {
+  /// Used to serialize the on-disk typedef table.
+  class TypedefTableInfo
+    : public CommonTypeTableInfo<TypedefTableInfo, TypedefInfo> {
+
+  public:
+    unsigned getUnversionedInfoSize(const TypedefInfo &info) {
+      return 1 + getCommonTypeInfoSize(info);
+    }
+
+    void emitUnversionedInfo(raw_ostream &out, const TypedefInfo &info) {
+      endian::Writer<little> writer(out);
+
+      uint8_t payload = 0;
+      if (auto swiftWrapper = info.SwiftWrapper) {
+        payload |= static_cast<uint8_t>(*swiftWrapper) + 1;
+      }
+
+      writer.write<uint8_t>(payload);
+
+      emitCommonTypeInfo(out, info);
+    }
+
+  };
+} // end anonymous namespace
+
+void APINotesWriter::Implementation::writeTypedefBlock(
+       llvm::BitstreamWriter &writer) {
+  BCBlockRAII restoreBlock(writer, TYPEDEF_BLOCK_ID, 3);
+
+  if (Typedefs.empty())
+    return;  
+
+  llvm::SmallString<4096> hashTableBlob;
+  uint32_t tableOffset;
+  {
+    llvm::OnDiskChainedHashTableGenerator<TypedefTableInfo> generator;
+    for (auto &entry : Typedefs)
+      generator.insert(entry.first, entry.second);
+
+    llvm::raw_svector_ostream blobStream(hashTableBlob);
+    // Make sure that no bucket is at offset 0
+    endian::Writer<little>(blobStream).write<uint32_t>(0);
+    tableOffset = generator.Emit(blobStream);
+  }
+
+  typedef_block::TypedefDataLayout layout(writer);
+  layout.emit(ScratchRecord, tableOffset, hashTableBlob);
+}
+
+void APINotesWriter::Implementation::writeToStream(llvm::raw_ostream &os) {
+  // Write the API notes file into a buffer.
+  SmallVector<char, 0> buffer;
+  {
+    llvm::BitstreamWriter writer(buffer);
+
+    // Emit the signature.
+    for (unsigned char byte : API_NOTES_SIGNATURE)
+      writer.Emit(byte, 8);
+
+    // Emit the blocks.
+    writeBlockInfoBlock(writer);
+    writeControlBlock(writer);
+    writeIdentifierBlock(writer);
+    writeObjCContextBlock(writer);
+    writeObjCPropertyBlock(writer);
+    writeObjCMethodBlock(writer);
+    writeObjCSelectorBlock(writer);
+    writeGlobalVariableBlock(writer);
+    writeGlobalFunctionBlock(writer);
+    writeEnumConstantBlock(writer);
+    writeTagBlock(writer);
+    writeTypedefBlock(writer);
+  }
+
+  // Write the buffer to the stream.
+  os.write(buffer.data(), buffer.size());
+  os.flush();
+}
+
+APINotesWriter::APINotesWriter(StringRef moduleName, const FileEntry *sourceFile)
+  : Impl(*new Implementation)
+{
+  Impl.ModuleName = moduleName;
+  Impl.SourceFile = sourceFile;
+}
+
+APINotesWriter::~APINotesWriter() {
+  delete &Impl;
+}
+
+
+void APINotesWriter::writeToStream(raw_ostream &os) {
+  Impl.writeToStream(os);
+}
+
+ContextID APINotesWriter::addObjCContext(StringRef name, bool isClass,
+                                         const ObjCContextInfo &info,
+                                         VersionTuple swiftVersion) {
+  IdentifierID nameID = Impl.getIdentifier(name);
+
+  std::pair<unsigned, char> key(nameID, isClass ? 0 : 1);
+  auto known = Impl.ObjCContexts.find(key);
+  if (known == Impl.ObjCContexts.end()) {
+    unsigned nextID = Impl.ObjCContexts.size() + 1;
+
+    VersionedSmallVector<ObjCContextInfo> emptyVersionedInfo;
+    known = Impl.ObjCContexts.insert(
+              std::make_pair(key, std::make_pair(nextID, emptyVersionedInfo)))
+              .first;
+
+    Impl.ObjCContextNames[nextID] = nameID;
+  }
+
+  // Add this version information.
+  auto &versionedVec = known->second.second;
+  bool found = false;
+  for (auto &versioned : versionedVec){
+    if (versioned.first == swiftVersion) {
+      versioned.second |= info;
+      found = true;
+      break;
+    }
+  }
+
+  if (!found)
+    versionedVec.push_back({swiftVersion, info});
+
+  return ContextID(known->second.first);
+}
+
+void APINotesWriter::addObjCProperty(ContextID contextID, StringRef name,
+                                     bool isInstance,
+                                     const ObjCPropertyInfo &info,
+                                     VersionTuple swiftVersion) {
+  IdentifierID nameID = Impl.getIdentifier(name);
+  Impl.ObjCProperties[std::make_tuple(contextID.Value, nameID, isInstance)]
+    .push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addObjCMethod(ContextID contextID,
+                                   ObjCSelectorRef selector,
+                                   bool isInstanceMethod,
+                                   const ObjCMethodInfo &info,
+                                   VersionTuple swiftVersion) {
+  SelectorID selectorID = Impl.getSelector(selector);
+  auto key = std::tuple<unsigned, unsigned, char>{
+      contextID.Value, selectorID, isInstanceMethod};
+  Impl.ObjCMethods[key].push_back({swiftVersion, info});
+
+  // If this method is a designated initializer, update the class to note that
+  // it has designated initializers.
+  if (info.DesignatedInit) {
+    assert(Impl.ObjCContexts.count({Impl.ObjCContextNames[contextID.Value],
+                                    (char)0}));
+    auto &versionedVec =
+      Impl.ObjCContexts[{Impl.ObjCContextNames[contextID.Value], (char)0}]
+        .second;
+    bool found = false;
+    for (auto &versioned : versionedVec) {
+      if (versioned.first == swiftVersion) {
+        versioned.second.setHasDesignatedInits(true);
+        found = true;
+        break;
+      }
+    }
+
+    if (!found) {
+      versionedVec.push_back({swiftVersion, ObjCContextInfo()});
+      versionedVec.back().second.setHasDesignatedInits(true);
+    }
+  }
+}
+
+void APINotesWriter::addGlobalVariable(llvm::StringRef name,
+                                       const GlobalVariableInfo &info,
+                                       VersionTuple swiftVersion) {
+  IdentifierID variableID = Impl.getIdentifier(name);
+  Impl.GlobalVariables[variableID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addGlobalFunction(llvm::StringRef name,
+                                       const GlobalFunctionInfo &info,
+                                       VersionTuple swiftVersion) {
+  IdentifierID nameID = Impl.getIdentifier(name);
+  Impl.GlobalFunctions[nameID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addEnumConstant(llvm::StringRef name,
+                                     const EnumConstantInfo &info,
+                                     VersionTuple swiftVersion) {
+  IdentifierID enumConstantID = Impl.getIdentifier(name);
+  Impl.EnumConstants[enumConstantID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addTag(llvm::StringRef name, const TagInfo &info,
+                            VersionTuple swiftVersion) {
+  IdentifierID tagID = Impl.getIdentifier(name);
+  Impl.Tags[tagID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addTypedef(llvm::StringRef name, const TypedefInfo &info,
+                                VersionTuple swiftVersion) {
+  IdentifierID typedefID = Impl.getIdentifier(name);
+  Impl.Typedefs[typedefID].push_back({swiftVersion, info});
+}
+
+void APINotesWriter::addModuleOptions(ModuleOptions opts) {
+  Impl.SwiftInferImportAsMember = opts.SwiftInferImportAsMember;
+}
+
diff --git a/lib/APINotes/APINotesYAMLCompiler.cpp b/lib/APINotes/APINotesYAMLCompiler.cpp
new file mode 100644
index 0000000..f0f6cb8
--- /dev/null
+++ b/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -0,0 +1,1503 @@
+//===--- APINotesYAMLCompiler.cpp - API Notes YAML format reader *- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file reads API notes specified in YAML format.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/APINotesYAMLCompiler.h"
+#include "clang/APINotes/APINotesReader.h"
+#include "clang/APINotes/Types.h"
+#include "clang/APINotes/APINotesWriter.h"
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/YAMLTraits.h"
+#include <algorithm>
+
+/*
+ 
+ YAML Format specification.
+
+ Nullability should be expressed using one of the following values:
+   O - Optional (or Nullable)
+   N - Not Optional
+   S - Scalar
+   U - Unknown
+ Note, the API is considered 'audited' when at least the return value or a
+ parameter has a nullability value. For 'audited' APIs, we assume the default
+ nullability for any underspecified type.
+
+---
+ Name: AppKit             # The name of the framework
+
+ Availability: OSX        # Optional: Specifies which platform the API is
+                          # available on. [OSX / iOS / none/
+                          #                available / nonswift]
+
+ AvailabilityMsg: ""  # Optional: Custom availability message to display to
+                          # the user, when API is not available.
+
+ Classes:                 # List of classes
+ ...
+ Protocols:               # List of protocols
+ ...
+ Functions:               # List of functions
+ ...
+ Globals:                 # List of globals
+ ...
+ Enumerators:             # List of enumerators
+ ...
+ Tags:                    # List of tags (struct/union/enum/C++ class)
+ ...
+ Typedefs:                # List of typedef-names and C++11 type aliases
+ ...
+
+ Each class and protocol is defined as following:
+
+ - Name: NSView                       # The name of the class
+ 
+   AuditedForNullability: false       # Optional: Specifies if the whole class
+                                      # has been audited for nullability.
+                                      # If yes, we assume all the methods and
+                                      # properties of the class have default
+                                      # nullability unless it is overwritten by
+                                      # a method/property specific info below.
+                                      # This applies to all classes, extensions,
+                                      # and categories of the class defined in
+                                      # the current framework/module.
+                                      # (false/true)
+
+   Availability: OSX
+
+   AvailabilityMsg: ""
+
+   Methods:
+     - Selector: "setSubviews:"       # Full name
+
+       MethodKind: Instance           # [Class/Instance]
+
+       Nullability: [N, N, O, S]      # The nullability of parameters in
+                                      # the signature.
+
+       NullabilityOfRet: O            # The nullability of the return value.
+
+       Availability: OSX
+
+       AvailabilityMsg: ""
+
+       DesignatedInit: false          # Optional: Specifies if this method is a
+                                      # designated initializer (false/true)
+
+       Required: false                # Optional: Specifies if this method is a
+                                      # required initializer (false/true)
+
+   Properties:
+     - Name: window
+
+       Nullability: O
+
+       Availability: OSX
+
+       AvailabilityMsg: ""
+
+ The protocol definition format is the same as the class definition.
+
+ Each function definition is of the following form:
+
+ - Name: "myGlobalFunction"           # Full name
+
+   Nullability: [N, N, O, S]          # The nullability of parameters in
+                                      # the signature.
+
+   NullabilityOfRet: O                # The nullability of the return value.
+
+   Availability: OSX
+
+   AvailabilityMsg: ""
+
+Each global variable definition is of the following form:
+
+ - Name: MyGlobalVar
+
+   Nullability: O
+
+   Availability: OSX
+
+   AvailabilityMsg: ""
+
+*/
+
+using llvm::StringRef;
+using namespace clang;
+namespace {
+  enum class APIAvailability {
+    Available = 0,
+    OSX,
+    IOS,
+    None,
+    NonSwift,
+  };
+
+  enum class MethodKind {
+    Class,
+    Instance,
+  };
+
+  /// Old attribute deprecated in favor of SwiftName.
+  enum class FactoryAsInitKind {
+    /// Infer based on name and type (the default).
+    Infer,
+    /// Treat as a class method.
+    AsClassMethod,
+    /// Treat as an initializer.
+    AsInitializer
+  };
+  
+  /// Syntactic sugar for EnumExtensibility and FlagEnum
+  enum class EnumConvenienceAliasKind {
+    /// EnumExtensibility: none, FlagEnum: false
+    None,
+    /// EnumExtensibility: open, FlagEnum: false
+    CFEnum,
+    /// EnumExtensibility: open, FlagEnum: true
+    CFOptions,
+    /// EnumExtensibility: closed, FlagEnum: false
+    CFClosedEnum
+  };
+
+  struct AvailabilityItem {
+    APIAvailability Mode = APIAvailability::Available;
+    StringRef Msg;
+    AvailabilityItem() : Mode(APIAvailability::Available), Msg("") {}
+  };
+
+  static llvm::Optional<NullabilityKind> AbsentNullability = llvm::None;
+  static llvm::Optional<NullabilityKind> DefaultNullability =
+    NullabilityKind::NonNull;
+  typedef std::vector<clang::NullabilityKind> NullabilitySeq;
+
+  struct Param {
+    unsigned Position;
+    Optional<bool> NoEscape = false;
+    llvm::Optional<NullabilityKind> Nullability;
+    StringRef Type;
+  };
+  typedef std::vector<Param> ParamsSeq;
+
+  struct Method {
+    StringRef Selector;
+    MethodKind Kind;
+    ParamsSeq Params;
+    NullabilitySeq Nullability;
+    llvm::Optional<NullabilityKind> NullabilityOfRet;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    FactoryAsInitKind FactoryAsInit = FactoryAsInitKind::Infer;
+    bool DesignatedInit = false;
+    bool Required = false;
+    StringRef ResultType;
+  };
+  typedef std::vector<Method> MethodsSeq;
+
+  struct Property {
+    StringRef Name;
+    llvm::Optional<MethodKind> Kind;
+    llvm::Optional<NullabilityKind> Nullability;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    Optional<bool> SwiftImportAsAccessors;
+    StringRef Type;
+  };
+  typedef std::vector<Property> PropertiesSeq;
+
+  struct Class {
+    StringRef Name;
+    bool AuditedForNullability = false;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    Optional<StringRef> SwiftBridge;
+    Optional<StringRef> NSErrorDomain;
+    Optional<bool> SwiftImportAsNonGeneric;
+    Optional<bool> SwiftObjCMembers;
+    MethodsSeq Methods;
+    PropertiesSeq Properties;
+  };
+  typedef std::vector<Class> ClassesSeq;
+
+  struct Function {
+    StringRef Name;
+    ParamsSeq Params;
+    NullabilitySeq Nullability;
+    llvm::Optional<NullabilityKind> NullabilityOfRet;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    StringRef Type;
+    StringRef ResultType;
+  };
+  typedef std::vector<Function> FunctionsSeq;
+
+  struct GlobalVariable {
+    StringRef Name;
+    llvm::Optional<NullabilityKind> Nullability;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+    StringRef Type;
+  };
+  typedef std::vector<GlobalVariable> GlobalVariablesSeq;
+
+  struct EnumConstant {
+    StringRef Name;
+    AvailabilityItem Availability;
+    Optional<bool> SwiftPrivate;
+    StringRef SwiftName;
+  };
+  typedef std::vector<EnumConstant> EnumConstantsSeq;
+
+  struct Tag {
+    StringRef Name;
+    AvailabilityItem Availability;
+    StringRef SwiftName;
+    Optional<bool> SwiftPrivate;
+    Optional<StringRef> SwiftBridge;
+    Optional<StringRef> NSErrorDomain;
+    Optional<api_notes::EnumExtensibilityKind> EnumExtensibility;
+    Optional<bool> FlagEnum;
+    Optional<EnumConvenienceAliasKind> EnumConvenienceKind;
+  };
+  typedef std::vector<Tag> TagsSeq;
+
+  struct Typedef {
+    StringRef Name;
+    AvailabilityItem Availability;
+    StringRef SwiftName;
+    Optional<bool> SwiftPrivate;
+    Optional<StringRef> SwiftBridge;
+    Optional<StringRef> NSErrorDomain;
+    Optional<api_notes::SwiftWrapperKind> SwiftWrapper;
+  };
+  typedef std::vector<Typedef> TypedefsSeq;
+
+  struct TopLevelItems {
+    ClassesSeq Classes;
+    ClassesSeq Protocols;
+    FunctionsSeq Functions;
+    GlobalVariablesSeq Globals;
+    EnumConstantsSeq EnumConstants;
+    TagsSeq Tags;
+    TypedefsSeq Typedefs;
+  };
+
+  struct Versioned {
+    VersionTuple Version;
+    TopLevelItems Items;
+  };
+
+  typedef std::vector<Versioned> VersionedSeq;
+
+  struct Module {
+    StringRef Name;
+    AvailabilityItem Availability;
+    TopLevelItems TopLevel;
+    VersionedSeq SwiftVersions;
+
+    llvm::Optional<bool> SwiftInferImportAsMember = {llvm::None};
+
+    LLVM_ATTRIBUTE_DEPRECATED(
+      void dump() LLVM_ATTRIBUTE_USED,
+      "only for use within the debugger");
+  };
+}
+
+LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(clang::NullabilityKind)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Method)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Property)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Param)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Class)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Function)
+LLVM_YAML_IS_SEQUENCE_VECTOR(GlobalVariable)
+LLVM_YAML_IS_SEQUENCE_VECTOR(EnumConstant)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Tag)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Typedef)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Versioned)
+
+namespace llvm {
+  namespace yaml {
+
+    template <>
+    struct ScalarEnumerationTraits<NullabilityKind > {
+      static void enumeration(IO &io, NullabilityKind  &value) {
+        io.enumCase(value, "N", NullabilityKind::NonNull);
+        io.enumCase(value, "O", NullabilityKind::Nullable);
+        io.enumCase(value, "U", NullabilityKind::Unspecified);
+        // TODO: Mapping this to it's own value would allow for better cross
+        // checking. Also the default should be Unknown.
+        io.enumCase(value, "S", NullabilityKind::Unspecified);
+      }
+    };
+
+    template <>
+    struct ScalarEnumerationTraits<FactoryAsInitKind> {
+      static void enumeration(IO &io, FactoryAsInitKind  &value) {
+        io.enumCase(value, "A", FactoryAsInitKind::Infer);
+        io.enumCase(value, "C", FactoryAsInitKind::AsClassMethod);
+        io.enumCase(value, "I", FactoryAsInitKind::AsInitializer);
+      }
+    };
+
+    template <>
+    struct ScalarEnumerationTraits<MethodKind> {
+      static void enumeration(IO &io, MethodKind &value) {
+        io.enumCase(value, "Class",    MethodKind::Class);
+        io.enumCase(value, "Instance", MethodKind::Instance);
+      }
+    };
+
+    template <>
+    struct ScalarEnumerationTraits<APIAvailability> {
+      static void enumeration(IO &io, APIAvailability &value) {
+        io.enumCase(value, "OSX",       APIAvailability::OSX);
+        io.enumCase(value, "iOS",       APIAvailability::IOS);
+        io.enumCase(value, "none",      APIAvailability::None);
+        io.enumCase(value, "nonswift",  APIAvailability::NonSwift);
+        io.enumCase(value, "available", APIAvailability::Available);
+      }
+    };
+
+    template<>
+    struct ScalarEnumerationTraits<api_notes::SwiftWrapperKind> {
+      static void enumeration(IO &io, api_notes::SwiftWrapperKind &value) {
+        io.enumCase(value, "none",      api_notes::SwiftWrapperKind::None);
+        io.enumCase(value, "struct",    api_notes::SwiftWrapperKind::Struct);
+        io.enumCase(value, "enum",      api_notes::SwiftWrapperKind::Enum);
+      }
+    };
+
+    template<>
+    struct ScalarEnumerationTraits<api_notes::EnumExtensibilityKind> {
+      static void enumeration(IO &io, api_notes::EnumExtensibilityKind &value) {
+        io.enumCase(value, "none",   api_notes::EnumExtensibilityKind::None);
+        io.enumCase(value, "open",   api_notes::EnumExtensibilityKind::Open);
+        io.enumCase(value, "closed", api_notes::EnumExtensibilityKind::Closed);
+      }
+    };
+
+    template<>
+    struct ScalarEnumerationTraits<EnumConvenienceAliasKind> {
+      static void enumeration(IO &io, EnumConvenienceAliasKind &value) {
+        io.enumCase(value, "none",      EnumConvenienceAliasKind::None);
+        io.enumCase(value, "CFEnum",    EnumConvenienceAliasKind::CFEnum);
+        io.enumCase(value, "NSEnum",    EnumConvenienceAliasKind::CFEnum);
+        io.enumCase(value, "CFOptions", EnumConvenienceAliasKind::CFOptions);
+        io.enumCase(value, "NSOptions", EnumConvenienceAliasKind::CFOptions);
+        io.enumCase(value, "CFClosedEnum",
+                    EnumConvenienceAliasKind::CFClosedEnum);
+        io.enumCase(value, "NSClosedEnum",
+                    EnumConvenienceAliasKind::CFClosedEnum);
+      }
+    };
+
+    template <>
+    struct ScalarTraits<VersionTuple> {
+      static void output(const VersionTuple &value, void*,
+                         llvm::raw_ostream &out) {
+        out << value;
+      }
+      static StringRef input(StringRef scalar, void*, VersionTuple &value) {
+        if (value.tryParse(scalar))
+          return "not a version number in the form XX.YY";
+
+        // Canonicalize on '.' as a separator.
+        value.UseDotAsSeparator();
+        return StringRef();
+      }
+
+      static bool mustQuote(StringRef) { return false; }
+    };
+
+    template <>
+    struct MappingTraits<Param> {
+      static void mapping(IO &io, Param& p) {
+        io.mapRequired("Position",        p.Position);
+        io.mapOptional("Nullability",     p.Nullability, 
+                                          AbsentNullability);
+        io.mapOptional("NoEscape",        p.NoEscape);
+        io.mapOptional("Type",            p.Type, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<Property> {
+      static void mapping(IO &io, Property& p) {
+        io.mapRequired("Name",            p.Name);
+        io.mapOptional("PropertyKind",    p.Kind);
+        io.mapOptional("Nullability",     p.Nullability, 
+                                          AbsentNullability);
+        io.mapOptional("Availability",    p.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", p.Availability.Msg);
+        io.mapOptional("SwiftPrivate",    p.SwiftPrivate);
+        io.mapOptional("SwiftName",       p.SwiftName);
+        io.mapOptional("SwiftImportAsAccessors", p.SwiftImportAsAccessors);
+        io.mapOptional("Type",            p.Type, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<Method> {
+      static void mapping(IO &io, Method& m) {
+        io.mapRequired("Selector",        m.Selector);
+        io.mapRequired("MethodKind",      m.Kind);
+        io.mapOptional("Parameters",      m.Params);
+        io.mapOptional("Nullability",     m.Nullability);
+        io.mapOptional("NullabilityOfRet",  m.NullabilityOfRet,
+                                            AbsentNullability);
+        io.mapOptional("Availability",    m.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", m.Availability.Msg);
+        io.mapOptional("SwiftPrivate",    m.SwiftPrivate);
+        io.mapOptional("SwiftName",       m.SwiftName);
+        io.mapOptional("FactoryAsInit",   m.FactoryAsInit,
+                                          FactoryAsInitKind::Infer);
+        io.mapOptional("DesignatedInit",  m.DesignatedInit, false);
+        io.mapOptional("Required",        m.Required, false);
+        io.mapOptional("ResultType",      m.ResultType, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<Class> {
+      static void mapping(IO &io, Class& c) {
+        io.mapRequired("Name",                  c.Name);
+        io.mapOptional("AuditedForNullability", c.AuditedForNullability, false);
+        io.mapOptional("Availability",          c.Availability.Mode);
+        io.mapOptional("AvailabilityMsg",       c.Availability.Msg);
+        io.mapOptional("SwiftPrivate",          c.SwiftPrivate);
+        io.mapOptional("SwiftName",             c.SwiftName);
+        io.mapOptional("SwiftBridge",           c.SwiftBridge);
+        io.mapOptional("NSErrorDomain",         c.NSErrorDomain);
+        io.mapOptional("SwiftImportAsNonGeneric", c.SwiftImportAsNonGeneric);
+        io.mapOptional("SwiftObjCMembers",      c.SwiftObjCMembers);
+        io.mapOptional("Methods",               c.Methods);
+        io.mapOptional("Properties",            c.Properties);
+      }
+    };
+
+    template <>
+    struct MappingTraits<Function> {
+      static void mapping(IO &io, Function& f) {
+        io.mapRequired("Name",             f.Name);
+        io.mapOptional("Parameters",       f.Params);
+        io.mapOptional("Nullability",      f.Nullability);
+        io.mapOptional("NullabilityOfRet", f.NullabilityOfRet,
+                                           AbsentNullability);
+        io.mapOptional("Availability",     f.Availability.Mode);
+        io.mapOptional("AvailabilityMsg",  f.Availability.Msg);
+        io.mapOptional("SwiftPrivate",     f.SwiftPrivate);
+        io.mapOptional("SwiftName",        f.SwiftName);
+        io.mapOptional("ResultType",       f.ResultType, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<GlobalVariable> {
+      static void mapping(IO &io, GlobalVariable& v) {
+        io.mapRequired("Name",            v.Name);
+        io.mapOptional("Nullability",     v.Nullability,
+                                          AbsentNullability);
+        io.mapOptional("Availability",    v.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", v.Availability.Msg);
+        io.mapOptional("SwiftPrivate",    v.SwiftPrivate);
+        io.mapOptional("SwiftName",       v.SwiftName);
+        io.mapOptional("Type",            v.Type, StringRef(""));
+      }
+    };
+
+    template <>
+    struct MappingTraits<EnumConstant> {
+      static void mapping(IO &io, EnumConstant& v) {
+        io.mapRequired("Name",            v.Name);
+        io.mapOptional("Availability",    v.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", v.Availability.Msg);
+        io.mapOptional("SwiftPrivate",    v.SwiftPrivate);
+        io.mapOptional("SwiftName",       v.SwiftName);
+      }
+    };
+
+    template <>
+    struct MappingTraits<Tag> {
+      static void mapping(IO &io, Tag& t) {
+        io.mapRequired("Name",                  t.Name);
+        io.mapOptional("Availability",          t.Availability.Mode);
+        io.mapOptional("AvailabilityMsg",       t.Availability.Msg);
+        io.mapOptional("SwiftPrivate",          t.SwiftPrivate);
+        io.mapOptional("SwiftName",             t.SwiftName);
+        io.mapOptional("SwiftBridge",           t.SwiftBridge);
+        io.mapOptional("NSErrorDomain",         t.NSErrorDomain);
+        io.mapOptional("EnumExtensibility",     t.EnumExtensibility);
+        io.mapOptional("FlagEnum",              t.FlagEnum);
+        io.mapOptional("EnumKind",              t.EnumConvenienceKind);
+      }
+    };
+
+    template <>
+    struct MappingTraits<Typedef> {
+      static void mapping(IO &io, Typedef& t) {
+        io.mapRequired("Name",                  t.Name);
+        io.mapOptional("Availability",          t.Availability.Mode);
+        io.mapOptional("AvailabilityMsg",       t.Availability.Msg);
+        io.mapOptional("SwiftPrivate",          t.SwiftPrivate);
+        io.mapOptional("SwiftName",             t.SwiftName);
+        io.mapOptional("SwiftBridge",           t.SwiftBridge);
+        io.mapOptional("NSErrorDomain",         t.NSErrorDomain);
+        io.mapOptional("SwiftWrapper",         t.SwiftWrapper);
+      }
+    };
+
+    static void mapTopLevelItems(IO &io, TopLevelItems &i) {
+      io.mapOptional("Classes",         i.Classes);
+      io.mapOptional("Protocols",       i.Protocols);
+      io.mapOptional("Functions",       i.Functions);
+      io.mapOptional("Globals",         i.Globals);
+      io.mapOptional("Enumerators",     i.EnumConstants);
+      io.mapOptional("Tags",            i.Tags);
+      io.mapOptional("Typedefs",        i.Typedefs);
+    }
+
+    template <>
+    struct MappingTraits<Versioned> {
+      static void mapping(IO &io, Versioned& v) {
+        io.mapRequired("Version", v.Version);
+        mapTopLevelItems(io, v.Items);
+      }
+    };
+
+    template <>
+    struct MappingTraits<Module> {
+      static void mapping(IO &io, Module& m) {
+        io.mapRequired("Name",            m.Name);
+        io.mapOptional("Availability",    m.Availability.Mode);
+        io.mapOptional("AvailabilityMsg", m.Availability.Msg);
+        io.mapOptional("SwiftInferImportAsMember", m.SwiftInferImportAsMember);
+
+        mapTopLevelItems(io, m.TopLevel);
+
+        io.mapOptional("SwiftVersions",  m.SwiftVersions);
+      }
+    };
+  }
+}
+
+using llvm::yaml::Input;
+using llvm::yaml::Output;
+
+void Module::dump() {
+  Output yout(llvm::errs());
+  yout << *this;
+}
+
+static bool parseAPINotes(StringRef yamlInput, Module &module,
+                          llvm::SourceMgr::DiagHandlerTy diagHandler,
+                          void *diagHandlerCtxt) {
+  Input yin(yamlInput, nullptr, diagHandler, diagHandlerCtxt);
+  yin >> module;
+
+  return static_cast<bool>(yin.error());
+}
+
+namespace {
+  using namespace api_notes;
+
+  class YAMLConverter {
+    const Module &TheModule;
+    const FileEntry *SourceFile;
+    APINotesWriter *Writer;
+    OSType TargetOS;
+    llvm::raw_ostream &OS;
+    llvm::SourceMgr::DiagHandlerTy DiagHandler;
+    void *DiagHandlerCtxt;
+    bool ErrorOccured;
+
+    /// Emit a diagnostic
+    bool emitError(llvm::Twine message) {
+      DiagHandler(llvm::SMDiagnostic("", llvm::SourceMgr::DK_Error,
+                                     message.str()),
+                  DiagHandlerCtxt);
+      ErrorOccured = true;
+      return true;
+    }
+
+  public:
+    YAMLConverter(const Module &module,
+                  const FileEntry *sourceFile,
+                  OSType targetOS,
+                  llvm::raw_ostream &os,
+                  llvm::SourceMgr::DiagHandlerTy diagHandler,
+                  void *diagHandlerCtxt) :
+      TheModule(module), SourceFile(sourceFile), Writer(0), TargetOS(targetOS), OS(os),
+      DiagHandler(diagHandler), DiagHandlerCtxt(diagHandlerCtxt),
+      ErrorOccured(false) {}
+
+    bool isAvailable(const AvailabilityItem &in) {
+      // Check if the API is available on the OS for which we are building.
+      if (in.Mode == APIAvailability::OSX && TargetOS != OSType::OSX)
+        return false;
+      if (in.Mode == APIAvailability::IOS && TargetOS != OSType::IOS)
+        return false;
+      return true;
+    }
+
+    bool convertAvailability(const AvailabilityItem &in,
+                             CommonEntityInfo &outInfo,
+                             llvm::StringRef apiName) {
+      // Populate the unavailability information.
+      outInfo.Unavailable = (in.Mode == APIAvailability::None);
+      outInfo.UnavailableInSwift = (in.Mode == APIAvailability::NonSwift);
+      if (outInfo.Unavailable || outInfo.UnavailableInSwift) {
+        outInfo.UnavailableMsg = in.Msg;
+      } else {
+        if (!in.Msg.empty()) {
+          emitError("availability message for available API '" +
+                    apiName + "' will not be used");
+        }
+      }
+      return false;
+    }
+
+    void convertParams(const ParamsSeq &params, FunctionInfo &outInfo) {
+      for (const auto &p : params) {
+        ParamInfo pi;
+        if (p.Nullability)
+          pi.setNullabilityAudited(*p.Nullability);
+        pi.setNoEscape(p.NoEscape);
+        pi.setType(p.Type);
+        while (outInfo.Params.size() <= p.Position) {
+          outInfo.Params.push_back(ParamInfo());
+        }
+        outInfo.Params[p.Position] |= pi;
+      }
+    }
+
+    void convertNullability(const NullabilitySeq &nullability,
+                            Optional<NullabilityKind> nullabilityOfRet,
+                            FunctionInfo &outInfo,
+                            llvm::StringRef apiName) {
+      if (nullability.size() > FunctionInfo::getMaxNullabilityIndex()) {
+        emitError("nullability info for " + apiName + " does not fit");
+        return;
+      }
+
+      bool audited = false;
+      unsigned int idx = 1;
+      for (auto i = nullability.begin(),
+                e = nullability.end(); i != e; ++i, ++idx){
+        outInfo.addTypeInfo(idx, *i);
+        audited = true;
+      }
+      if (nullabilityOfRet) {
+        outInfo.addTypeInfo(0, *nullabilityOfRet);
+        audited = true;
+      } else if (audited) {
+        outInfo.addTypeInfo(0, *DefaultNullability);
+      }
+      if (audited) {
+        outInfo.NullabilityAudited = audited;
+        outInfo.NumAdjustedNullable = idx;
+      }
+    }
+
+    /// Convert the common parts of an entity from YAML.
+    template<typename T>
+    bool convertCommon(const T& common, CommonEntityInfo &info,
+                       StringRef apiName) {
+      if (!isAvailable(common.Availability))
+        return true;
+
+      convertAvailability(common.Availability, info, apiName);
+      info.setSwiftPrivate(common.SwiftPrivate);
+      info.SwiftName = common.SwiftName;
+      return false;
+    }
+    
+    /// Convert the common parts of a type entity from YAML.
+    template<typename T>
+    bool convertCommonType(const T& common, CommonTypeInfo &info,
+                           StringRef apiName) {
+      if (convertCommon(common, info, apiName))
+        return true;
+
+      info.setSwiftBridge(common.SwiftBridge);
+      info.setNSErrorDomain(common.NSErrorDomain);
+      return false;
+    }
+
+    // Translate from Method into ObjCMethodInfo and write it out.
+    void convertMethod(const Method &meth,
+                       ContextID classID, StringRef className,
+                       VersionTuple swiftVersion) {
+      ObjCMethodInfo mInfo;
+
+      if (convertCommon(meth, mInfo, meth.Selector))
+        return;
+
+      // Check if the selector ends with ':' to determine if it takes arguments.
+      bool takesArguments = meth.Selector.endswith(":");
+
+      // Split the selector into pieces.
+      llvm::SmallVector<StringRef, 4> a;
+      meth.Selector.split(a, ":", /*MaxSplit*/ -1, /*KeepEmpty*/ false);
+      if (!takesArguments && a.size() > 1 ) {
+        emitError("selector " + meth.Selector + "is missing a ':' at the end");
+        return;
+      }
+
+      // Construct ObjCSelectorRef.
+      api_notes::ObjCSelectorRef selectorRef;
+      selectorRef.NumPieces = !takesArguments ? 0 : a.size();
+      selectorRef.Identifiers = a;
+
+      // Translate the initializer info.
+      mInfo.DesignatedInit = meth.DesignatedInit;
+      mInfo.Required = meth.Required;
+      if (meth.FactoryAsInit != FactoryAsInitKind::Infer) {
+        emitError("'FactoryAsInit' is no longer valid; "
+                  "use 'SwiftName' instead");
+      }
+      mInfo.ResultType = meth.ResultType;
+
+      // Translate parameter information.
+      convertParams(meth.Params, mInfo);
+
+      // Translate nullability info.
+      convertNullability(meth.Nullability, meth.NullabilityOfRet,
+                         mInfo, meth.Selector);
+
+      // Write it.
+      Writer->addObjCMethod(classID, selectorRef,
+                            meth.Kind == MethodKind::Instance,
+                            mInfo, swiftVersion);
+    }
+
+    void convertContext(const Class &cl, bool isClass,
+                        VersionTuple swiftVersion) {
+      // Write the class.
+      ObjCContextInfo cInfo;
+
+      if (convertCommonType(cl, cInfo, cl.Name))
+        return;
+
+      if (cl.AuditedForNullability)
+        cInfo.setDefaultNullability(*DefaultNullability);
+      if (cl.SwiftImportAsNonGeneric)
+        cInfo.setSwiftImportAsNonGeneric(*cl.SwiftImportAsNonGeneric);
+      if (cl.SwiftObjCMembers)
+        cInfo.setSwiftObjCMembers(*cl.SwiftObjCMembers);
+
+      ContextID clID = Writer->addObjCContext(cl.Name, isClass, cInfo,
+                                              swiftVersion);
+
+      // Write all methods.
+      llvm::StringMap<std::pair<bool, bool>> knownMethods;
+      for (const auto &method : cl.Methods) {
+        // Check for duplicate method definitions.
+        bool isInstanceMethod = method.Kind == MethodKind::Instance;
+        bool &known = isInstanceMethod ? knownMethods[method.Selector].first
+                                       : knownMethods[method.Selector].second;
+        if (known) {
+          emitError(llvm::Twine("duplicate definition of method '") +
+                    (isInstanceMethod? "-" : "+") + "[" + cl.Name + " " +
+                    method.Selector + "]'");
+          continue;
+        }
+        known = true;
+
+        convertMethod(method, clID, cl.Name, swiftVersion);
+      }
+
+      // Write all properties.
+      llvm::StringSet<> knownInstanceProperties;
+      llvm::StringSet<> knownClassProperties;
+      for (const auto &prop : cl.Properties) {
+        // Check for duplicate property definitions.
+        if ((!prop.Kind || *prop.Kind == MethodKind::Instance) &&
+            !knownInstanceProperties.insert(prop.Name).second) {
+          emitError("duplicate definition of instance property '" + cl.Name +
+                    "." + prop.Name + "'");
+          continue;
+        }
+
+        if ((!prop.Kind || *prop.Kind == MethodKind::Class) &&
+            !knownClassProperties.insert(prop.Name).second) {
+          emitError("duplicate definition of class property '" + cl.Name + "." +
+                    prop.Name + "'");
+          continue;
+        }
+
+        // Translate from Property into ObjCPropertyInfo.
+        ObjCPropertyInfo pInfo;
+        if (!isAvailable(prop.Availability))
+          continue;
+        convertAvailability(prop.Availability, pInfo, prop.Name);
+        pInfo.setSwiftPrivate(prop.SwiftPrivate);
+        pInfo.SwiftName = prop.SwiftName;
+        if (prop.Nullability)
+          pInfo.setNullabilityAudited(*prop.Nullability);
+        if (prop.SwiftImportAsAccessors)
+          pInfo.setSwiftImportAsAccessors(*prop.SwiftImportAsAccessors);
+        pInfo.setType(prop.Type);
+        if (prop.Kind) {
+          Writer->addObjCProperty(clID, prop.Name,
+                                  *prop.Kind == MethodKind::Instance, pInfo,
+                                  swiftVersion);
+        } else {
+          // Add both instance and class properties with this name.
+          Writer->addObjCProperty(clID, prop.Name, true, pInfo, swiftVersion);
+          Writer->addObjCProperty(clID, prop.Name, false, pInfo, swiftVersion);
+        }
+      }
+    }
+
+    void convertTopLevelItems(const TopLevelItems &items,
+                              VersionTuple swiftVersion) {
+      // Write all classes.
+      llvm::StringSet<> knownClasses;
+      for (const auto &cl : items.Classes) {
+        // Check for duplicate class definitions.
+        if (!knownClasses.insert(cl.Name).second) {
+          emitError("multiple definitions of class '" + cl.Name + "'");
+          continue;
+        }
+
+        convertContext(cl, /*isClass*/ true, swiftVersion);
+      }
+
+      // Write all protocols.
+      llvm::StringSet<> knownProtocols;
+      for (const auto &pr : items.Protocols) {
+        // Check for duplicate protocol definitions.
+        if (!knownProtocols.insert(pr.Name).second) {
+          emitError("multiple definitions of protocol '" + pr.Name + "'");
+          continue;
+        }
+
+        convertContext(pr, /*isClass*/ false, swiftVersion);
+      }
+
+      // Write all global variables.
+      llvm::StringSet<> knownGlobals;
+      for (const auto &global : items.Globals) {
+        // Check for duplicate global variables.
+        if (!knownGlobals.insert(global.Name).second) {
+          emitError("multiple definitions of global variable '" +
+                    global.Name + "'");
+          continue;
+        }
+
+        GlobalVariableInfo info;
+        if (!isAvailable(global.Availability))
+          continue;
+        convertAvailability(global.Availability, info, global.Name);
+        info.setSwiftPrivate(global.SwiftPrivate);
+        info.SwiftName = global.SwiftName;
+        if (global.Nullability)
+          info.setNullabilityAudited(*global.Nullability);
+        info.setType(global.Type);
+        Writer->addGlobalVariable(global.Name, info, swiftVersion);
+      }
+
+      // Write all global functions.
+      llvm::StringSet<> knownFunctions;
+      for (const auto &function : items.Functions) {
+        // Check for duplicate global functions.
+        if (!knownFunctions.insert(function.Name).second) {
+          emitError("multiple definitions of global function '" +
+                    function.Name + "'");
+          continue;
+        }
+
+        GlobalFunctionInfo info;
+        if (!isAvailable(function.Availability))
+          continue;
+        convertAvailability(function.Availability, info, function.Name);
+        info.setSwiftPrivate(function.SwiftPrivate);
+        info.SwiftName = function.SwiftName;
+        convertParams(function.Params, info);
+        convertNullability(function.Nullability,
+                           function.NullabilityOfRet,
+                           info, function.Name);
+        info.ResultType = function.ResultType;
+        Writer->addGlobalFunction(function.Name, info, swiftVersion);
+      }
+
+      // Write all enumerators.
+      llvm::StringSet<> knownEnumConstants;
+      for (const auto &enumConstant : items.EnumConstants) {
+        // Check for duplicate enumerators
+        if (!knownEnumConstants.insert(enumConstant.Name).second) {
+          emitError("multiple definitions of enumerator '" +
+                    enumConstant.Name + "'");
+          continue;
+        }
+
+        EnumConstantInfo info;
+        if (!isAvailable(enumConstant.Availability))
+          continue;
+        convertAvailability(enumConstant.Availability, info, enumConstant.Name);
+        info.setSwiftPrivate(enumConstant.SwiftPrivate);
+        info.SwiftName = enumConstant.SwiftName;
+        Writer->addEnumConstant(enumConstant.Name, info, swiftVersion);
+      }
+
+      // Write all tags.
+      llvm::StringSet<> knownTags;
+      for (const auto &t : items.Tags) {
+        // Check for duplicate tag definitions.
+        if (!knownTags.insert(t.Name).second) {
+          emitError("multiple definitions Of tag '" + t.Name + "'");
+          continue;
+        }
+
+        TagInfo tagInfo;
+        if (convertCommonType(t, tagInfo, t.Name))
+          continue;
+
+        if (t.EnumConvenienceKind) {
+          if (t.EnumExtensibility) {
+            emitError(llvm::Twine(
+                "cannot mix EnumKind and EnumExtensibility (for ") + t.Name +
+                ")");
+            continue;
+          }
+          if (t.FlagEnum) {
+            emitError(llvm::Twine("cannot mix EnumKind and FlagEnum (for ") +
+                t.Name + ")");
+            continue;
+          }
+          switch (t.EnumConvenienceKind.getValue()) {
+          case EnumConvenienceAliasKind::None:
+            tagInfo.EnumExtensibility = EnumExtensibilityKind::None;
+            tagInfo.setFlagEnum(false);
+            break;
+          case EnumConvenienceAliasKind::CFEnum:
+            tagInfo.EnumExtensibility = EnumExtensibilityKind::Open;
+            tagInfo.setFlagEnum(false);
+            break;
+          case EnumConvenienceAliasKind::CFOptions:
+            tagInfo.EnumExtensibility = EnumExtensibilityKind::Open;
+            tagInfo.setFlagEnum(true);
+            break;
+          case EnumConvenienceAliasKind::CFClosedEnum:
+            tagInfo.EnumExtensibility = EnumExtensibilityKind::Closed;
+            tagInfo.setFlagEnum(false);
+            break;
+          }
+        } else {
+          tagInfo.EnumExtensibility = t.EnumExtensibility;
+          tagInfo.setFlagEnum(t.FlagEnum);          
+        }
+
+        Writer->addTag(t.Name, tagInfo, swiftVersion);
+      }
+
+      // Write all typedefs.
+      llvm::StringSet<> knownTypedefs;
+      for (const auto &t : items.Typedefs) {
+        // Check for duplicate typedef definitions.
+        if (!knownTypedefs.insert(t.Name).second) {
+          emitError("multiple definitions of typedef '" + t.Name + "'");
+          continue;
+        }
+
+        TypedefInfo typedefInfo;
+        if (convertCommonType(t, typedefInfo, t.Name))
+          continue;
+        typedefInfo.SwiftWrapper = t.SwiftWrapper;
+
+        Writer->addTypedef(t.Name, typedefInfo, swiftVersion);
+      }
+    }
+
+    bool convertModule() {
+      if (!isAvailable(TheModule.Availability))
+        return false;
+
+      // Set up the writer.
+      // FIXME: This is kindof ugly.
+      APINotesWriter writer(TheModule.Name, SourceFile);
+      Writer = &writer;
+
+      // Write the top-level items.
+      convertTopLevelItems(TheModule.TopLevel, VersionTuple());
+
+      if (TheModule.SwiftInferImportAsMember) {
+        ModuleOptions opts;
+        opts.SwiftInferImportAsMember = true;
+        Writer->addModuleOptions(opts);
+      }
+
+      // Convert the versioned information.
+      for (const auto &versioned : TheModule.SwiftVersions) {
+        convertTopLevelItems(versioned.Items, versioned.Version);
+      }
+
+      if (!ErrorOccured)
+        Writer->writeToStream(OS);
+
+      return ErrorOccured;
+    }
+  };
+}
+
+static bool compile(const Module &module,
+                    const FileEntry *sourceFile,
+                    llvm::raw_ostream &os,
+                    api_notes::OSType targetOS,
+                    llvm::SourceMgr::DiagHandlerTy diagHandler,
+                    void *diagHandlerCtxt){
+  using namespace api_notes;
+
+  YAMLConverter c(module, sourceFile, targetOS, os, diagHandler, diagHandlerCtxt);
+  return c.convertModule();
+}
+
+bool api_notes::parseAndDumpAPINotes(StringRef yamlInput)  {
+  Module module;
+
+  if (parseAPINotes(yamlInput, module, nullptr, nullptr))
+    return true;
+
+  Output yout(llvm::outs());
+  yout << module;
+
+  return false;
+}
+
+/// Simple diagnostic handler that prints diagnostics to standard error.
+static void printDiagnostic(const llvm::SMDiagnostic &diag, void *context) {
+  diag.print(nullptr, llvm::errs());
+}
+
+bool api_notes::compileAPINotes(StringRef yamlInput,
+                                const FileEntry *sourceFile,
+                                llvm::raw_ostream &os,
+                                OSType targetOS,
+                                llvm::SourceMgr::DiagHandlerTy diagHandler,
+                                void *diagHandlerCtxt) {
+  Module module;
+
+  if (!diagHandler) {
+    diagHandler = &printDiagnostic;
+  }
+
+  if (parseAPINotes(yamlInput, module, diagHandler, diagHandlerCtxt))
+    return true;
+
+  return compile(module, sourceFile, os, targetOS, diagHandler, diagHandlerCtxt);
+}
+
+namespace {
+  // Deserialize the API notes file into a module.
+  class DecompileVisitor : public APINotesReader::Visitor {
+    /// Allocator used to clone those strings that need it.
+    llvm::BumpPtrAllocator Allocator;
+
+    /// The module we're building.
+    Module TheModule;
+
+    /// A known context, which tracks what we know about a context ID.
+    struct KnownContext {
+      /// Whether this is a protocol (vs. a class).
+      bool isProtocol;
+
+      /// The indices into the top-level items for this context at each
+      /// Swift version.
+      SmallVector<std::pair<VersionTuple, unsigned>, 1> indices;
+
+      Class &getContext(const VersionTuple &swiftVersion,
+                        TopLevelItems &items) {
+        ClassesSeq &seq = isProtocol ? items.Protocols : items.Classes;
+
+        for (auto &index : indices) {
+          if (index.first == swiftVersion)
+            return seq[index.second];
+        }
+
+        indices.push_back({swiftVersion, seq.size()});
+        seq.push_back(Class());
+        return seq.back();
+      }
+    };
+
+    /// A mapping from context ID to a pair (index, is-protocol) that indicates
+    /// the index of that class or protocol in the global "classes" or
+    /// "protocols" list.
+    llvm::DenseMap<unsigned, KnownContext> knownContexts;
+
+    /// Copy a string into allocated memory so it does disappear on us.
+    StringRef copyString(StringRef string) {
+      if (string.empty()) return StringRef();
+
+      void *ptr = Allocator.Allocate(string.size(), 1);
+      memcpy(ptr, string.data(), string.size());
+      return StringRef(reinterpret_cast<const char *>(ptr), string.size());
+    }
+
+    /// Copy an optional string into allocated memory so it does disappear on us.
+    Optional<StringRef> maybeCopyString(Optional<StringRef> string) {
+      if (!string) return None;
+
+      return copyString(*string);
+    }
+
+    /// Copy an optional string into allocated memory so it does disappear on us.
+    Optional<StringRef> maybeCopyString(Optional<std::string> string) {
+      if (!string) return None;
+
+      return copyString(*string);
+    }
+
+    template<typename T>
+    void handleCommon(T &record, const CommonEntityInfo &info) {
+      handleAvailability(record.Availability, info);
+      record.SwiftPrivate = info.isSwiftPrivate();
+      record.SwiftName = copyString(info.SwiftName);
+    }
+
+    template<typename T>
+    void handleCommonType(T &record, const CommonTypeInfo &info) {
+      handleCommon(record, info);
+      record.SwiftBridge = maybeCopyString(info.getSwiftBridge());
+      record.NSErrorDomain = maybeCopyString(info.getNSErrorDomain());
+    }
+
+    /// Map Objective-C context info.
+    void handleObjCContext(Class &record, StringRef name,
+                           const ObjCContextInfo &info) {
+      record.Name = name;
+
+      handleCommonType(record, info);
+      record.SwiftImportAsNonGeneric = info.getSwiftImportAsNonGeneric();
+      record.SwiftObjCMembers = info.getSwiftObjCMembers();
+
+      if (info.getDefaultNullability()) {
+        record.AuditedForNullability = true;
+      }
+    }
+
+    /// Map availability information, if present.
+    void handleAvailability(AvailabilityItem &availability,
+                            const CommonEntityInfo &info) {
+      if (info.Unavailable) {
+        availability.Mode = APIAvailability::None;
+        availability.Msg = copyString(info.UnavailableMsg);
+      }
+
+      if (info.UnavailableInSwift) {
+        availability.Mode = APIAvailability::NonSwift;
+        availability.Msg = copyString(info.UnavailableMsg);
+      }
+    }
+
+    /// Map parameter information for a function.
+    void handleParameters(ParamsSeq &params,
+                          const FunctionInfo &info) {
+      unsigned position = 0;
+      for (const auto &pi: info.Params) {
+        Param p;
+        p.Position = position++;
+        p.Nullability = pi.getNullability();
+        p.NoEscape = pi.isNoEscape();
+        p.Type = copyString(pi.getType());
+        params.push_back(p);
+      }
+    }
+
+    /// Map nullability information for a function.
+    void handleNullability(NullabilitySeq &nullability,
+                           llvm::Optional<NullabilityKind> &nullabilityOfRet,
+                           const FunctionInfo &info,
+                           unsigned numParams) {
+      if (info.NullabilityAudited) {
+        nullabilityOfRet = info.getReturnTypeInfo();
+
+        // Figure out the number of parameters from the selector.
+        for (unsigned i = 0; i != numParams; ++i)
+          nullability.push_back(info.getParamTypeInfo(i));
+      }
+    }
+
+    TopLevelItems &getTopLevelItems(VersionTuple swiftVersion) {
+      if (!swiftVersion) return TheModule.TopLevel;
+
+      for (auto &versioned : TheModule.SwiftVersions) {
+        if (versioned.Version == swiftVersion)
+          return versioned.Items;
+      }
+
+      TheModule.SwiftVersions.push_back(Versioned());
+      TheModule.SwiftVersions.back().Version = swiftVersion;
+      return TheModule.SwiftVersions.back().Items;
+    }
+
+  public:
+    virtual void visitObjCClass(ContextID contextID, StringRef name,
+                                const ObjCContextInfo &info,
+                                VersionTuple swiftVersion) {
+      // Record this known context.
+      auto &items = getTopLevelItems(swiftVersion);
+      auto &known = knownContexts[contextID.Value];
+      known.isProtocol = false;
+
+      handleObjCContext(known.getContext(swiftVersion, items), name, info);
+    }
+
+    virtual void visitObjCProtocol(ContextID contextID, StringRef name,
+                                   const ObjCContextInfo &info,
+                                   VersionTuple swiftVersion) {
+      // Record this known context.
+      auto &items = getTopLevelItems(swiftVersion);
+      auto &known = knownContexts[contextID.Value];
+      known.isProtocol = true;
+
+      handleObjCContext(known.getContext(swiftVersion, items), name, info);
+    }
+
+    virtual void visitObjCMethod(ContextID contextID, StringRef selector,
+                                 bool isInstanceMethod,
+                                 const ObjCMethodInfo &info,
+                                 VersionTuple swiftVersion) {
+      Method method;
+      method.Selector = copyString(selector);
+      method.Kind = isInstanceMethod ? MethodKind::Instance : MethodKind::Class;
+
+      handleCommon(method, info);
+      handleParameters(method.Params, info);
+      handleNullability(method.Nullability, method.NullabilityOfRet, info,
+                        selector.count(':'));
+      method.DesignatedInit = info.DesignatedInit;
+      method.Required = info.Required;
+      method.ResultType = copyString(info.ResultType);
+      auto &items = getTopLevelItems(swiftVersion);
+      knownContexts[contextID.Value].getContext(swiftVersion, items)
+        .Methods.push_back(method);
+    }
+
+    virtual void visitObjCProperty(ContextID contextID, StringRef name,
+                                   bool isInstance,
+                                   const ObjCPropertyInfo &info,
+                                   VersionTuple swiftVersion) {
+      Property property;
+      property.Name = name;
+      property.Kind = isInstance ? MethodKind::Instance : MethodKind::Class;
+      handleCommon(property, info);
+
+      // FIXME: No way to represent "not audited for nullability".
+      if (auto nullability = info.getNullability()) {
+        property.Nullability = *nullability;
+      }
+
+      property.SwiftImportAsAccessors = info.getSwiftImportAsAccessors();
+
+      property.Type = copyString(info.getType());
+
+      auto &items = getTopLevelItems(swiftVersion);
+      knownContexts[contextID.Value].getContext(swiftVersion, items)
+        .Properties.push_back(property);
+    }
+
+    virtual void visitGlobalFunction(StringRef name,
+                                     const GlobalFunctionInfo &info,
+                                     VersionTuple swiftVersion) {
+      Function function;
+      function.Name = name;
+      handleCommon(function, info);
+      handleParameters(function.Params, info);
+      if (info.NumAdjustedNullable > 0)
+        handleNullability(function.Nullability, function.NullabilityOfRet,
+                          info, info.NumAdjustedNullable-1);
+      function.ResultType = copyString(info.ResultType);
+      auto &items = getTopLevelItems(swiftVersion);
+      items.Functions.push_back(function);
+    }
+
+    virtual void visitGlobalVariable(StringRef name,
+                                     const GlobalVariableInfo &info,
+                                     VersionTuple swiftVersion) {
+      GlobalVariable global;
+      global.Name = name;
+      handleCommon(global, info);
+
+      // FIXME: No way to represent "not audited for nullability".
+      if (auto nullability = info.getNullability()) {
+        global.Nullability = *nullability;
+      }
+      global.Type = copyString(info.getType());
+
+      auto &items = getTopLevelItems(swiftVersion);
+      items.Globals.push_back(global);
+    }
+
+    virtual void visitEnumConstant(StringRef name,
+                                   const EnumConstantInfo &info,
+                                   VersionTuple swiftVersion) {
+      EnumConstant enumConstant;
+      enumConstant.Name = name;
+      handleCommon(enumConstant, info);
+
+      auto &items = getTopLevelItems(swiftVersion);
+      items.EnumConstants.push_back(enumConstant);
+    }
+
+    virtual void visitTag(StringRef name, const TagInfo &info,
+                          VersionTuple swiftVersion) {
+      Tag tag;
+      tag.Name = name;
+      handleCommonType(tag, info);
+      tag.EnumExtensibility = info.EnumExtensibility;
+      tag.FlagEnum = info.isFlagEnum();
+      auto &items = getTopLevelItems(swiftVersion);
+      items.Tags.push_back(tag);
+    }
+
+    virtual void visitTypedef(StringRef name, const TypedefInfo &info,
+                              VersionTuple swiftVersion) {
+      Typedef td;
+      td.Name = name;
+      handleCommonType(td, info);
+      td.SwiftWrapper = info.SwiftWrapper;
+      auto &items = getTopLevelItems(swiftVersion);
+      items.Typedefs.push_back(td);
+    }
+
+    /// Retrieve the module.
+    Module &getModule() { return TheModule; }
+  };
+}
+
+/// Produce a flattened, numeric value for optional method/property kinds.
+static unsigned flattenPropertyKind(llvm::Optional<MethodKind> kind) {
+  return kind ? (*kind == MethodKind::Instance ? 2 : 1) : 0;
+}
+
+/// Sort the items in the given block of "top-level" items.
+static void sortTopLevelItems(TopLevelItems &items) {
+  // Sort classes.
+  std::sort(items.Classes.begin(), items.Classes.end(),
+            [](const Class &lhs, const Class &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort protocols.
+  std::sort(items.Protocols.begin(), items.Protocols.end(),
+            [](const Class &lhs, const Class &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort methods and properties within each class and protocol.
+  auto sortMembers = [](Class &record) {
+    // Sort properties.
+    std::sort(record.Properties.begin(), record.Properties.end(),
+              [](const Property &lhs, const Property &rhs) -> bool {
+                return lhs.Name < rhs.Name ||
+                (lhs.Name == rhs.Name &&
+                 flattenPropertyKind(lhs.Kind) <
+                 flattenPropertyKind(rhs.Kind));
+              });
+
+    // Sort methods.
+    std::sort(record.Methods.begin(), record.Methods.end(),
+              [](const Method &lhs, const Method &rhs) -> bool {
+                return lhs.Selector < rhs.Selector ||
+                (lhs.Selector == rhs.Selector &&
+                 static_cast<unsigned>(lhs.Kind)
+                 < static_cast<unsigned>(rhs.Kind));
+              });
+  };
+  std::for_each(items.Classes.begin(), items.Classes.end(), sortMembers);
+  std::for_each(items.Protocols.begin(), items.Protocols.end(), sortMembers);
+
+  // Sort functions.
+  std::sort(items.Functions.begin(), items.Functions.end(),
+            [](const Function &lhs, const Function &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort global variables.
+  std::sort(items.Globals.begin(), items.Globals.end(),
+            [](const GlobalVariable &lhs, const GlobalVariable &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort enum constants.
+  std::sort(items.EnumConstants.begin(), items.EnumConstants.end(),
+            [](const EnumConstant &lhs, const EnumConstant &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort tags.
+  std::sort(items.Tags.begin(), items.Tags.end(),
+            [](const Tag &lhs, const Tag &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+
+  // Sort typedefs.
+  std::sort(items.Typedefs.begin(), items.Typedefs.end(),
+            [](const Typedef &lhs, const Typedef &rhs) -> bool {
+              return lhs.Name < rhs.Name;
+            });
+}
+
+bool api_notes::decompileAPINotes(std::unique_ptr<llvm::MemoryBuffer> input,
+                                  llvm::raw_ostream &os) {
+  // Try to read the file.
+  auto reader = APINotesReader::get(std::move(input), VersionTuple());
+  if (!reader) {
+    llvm::errs() << "not a well-formed API notes binary file\n";
+    return true;
+  }
+
+  DecompileVisitor decompileVisitor;
+  reader->visit(decompileVisitor);
+
+  // Sort the data in the module, because the API notes reader doesn't preserve
+  // order.
+  auto &module = decompileVisitor.getModule();
+
+  // Set module name.
+  module.Name = reader->getModuleName();
+
+  // Set module options
+  auto opts = reader->getModuleOptions();
+  if (opts.SwiftInferImportAsMember)
+    module.SwiftInferImportAsMember = true;
+
+  // Sort the top-level items.
+  sortTopLevelItems(module.TopLevel);
+
+  // Sort the Swift versions.
+  std::sort(module.SwiftVersions.begin(), module.SwiftVersions.end(),
+            [](const Versioned &lhs, const Versioned &rhs) -> bool {
+              return lhs.Version < rhs.Version;
+            });
+
+  // Sort the top-level items within each Swift version.
+  for (auto &versioned : module.SwiftVersions)
+    sortTopLevelItems(versioned.Items);
+
+  // Output the YAML representation.
+  Output yout(os);
+  yout << module;
+
+  return false;
+}
+
diff --git a/lib/APINotes/CMakeLists.txt b/lib/APINotes/CMakeLists.txt
new file mode 100644
index 0000000..da9d0d1
--- /dev/null
+++ b/lib/APINotes/CMakeLists.txt
@@ -0,0 +1,15 @@
+set(LLVM_LINK_COMPONENTS
+  BitReader
+  Support
+  )
+
+add_clang_library(clangAPINotes
+  APINotesManager.cpp
+  APINotesWriter.cpp
+  APINotesReader.cpp
+  APINotesYAMLCompiler.cpp
+  Types.cpp
+
+  LINK_LIBS
+  clangBasic
+)
diff --git a/lib/APINotes/Types.cpp b/lib/APINotes/Types.cpp
new file mode 100644
index 0000000..4bbb4a8
--- /dev/null
+++ b/lib/APINotes/Types.cpp
@@ -0,0 +1,55 @@
+//===--- Types.cpp - API Notes Data Types ----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines data types used in the representation of API notes data.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/Types.h"
+#include "llvm/Support/raw_ostream.h"
+
+void clang::api_notes::ObjCMethodInfo::dump(llvm::raw_ostream &os) {
+    os << DesignatedInit << " " << Unavailable << " "
+       << NullabilityAudited << " " << NumAdjustedNullable << " "
+       << NullabilityPayload << " " << UnavailableMsg << "\n";
+}
+
+void clang::api_notes::ObjCContextInfo::dump(llvm::raw_ostream &os) {
+  os << HasDefaultNullability << " " << DefaultNullability << " "
+     << HasDesignatedInits << "\n";
+}
+
+void clang::api_notes::ObjCMethodInfo::mergePropInfoIntoSetter(
+      const ObjCPropertyInfo &pInfo) {
+  // Set the type of the first argument of the the setter or check that the
+  // value we have is consistent with the property.
+  // TODO: Can we provide proper error handling here?
+  if (auto pNullability = pInfo.getNullability()) {
+    if (!NullabilityAudited) {
+      addParamTypeInfo(0, *pNullability);
+      assert(NumAdjustedNullable == 2);
+    } else {
+      assert(getParamTypeInfo(0) == *pNullability);
+    }
+  }
+}
+
+void clang::api_notes::ObjCMethodInfo::mergePropInfoIntoGetter(
+      const ObjCPropertyInfo &pInfo) {
+  // Set the return type of the getter or check that the value we have is
+  // consistent with the property.
+  // TODO: Can we provide proper error handling here?
+  if (auto pNullability = pInfo.getNullability()) {
+    if (!NullabilityAudited) {
+      addReturnTypeInfo(*pNullability);
+      assert(NumAdjustedNullable == 1);
+    } else {
+      assert(getReturnTypeInfo() == *pNullability);
+    }
+  }
+}
diff --git a/lib/ARCMigrate/ObjCMT.cpp b/lib/ARCMigrate/ObjCMT.cpp
index 241a724..fcc67da 100644
--- a/lib/ARCMigrate/ObjCMT.cpp
+++ b/lib/ARCMigrate/ObjCMT.cpp
@@ -2189,7 +2189,7 @@
 
   Rewriter rewriter(SM, LangOpts);
   RewritesReceiver Rec(rewriter);
-  Editor.applyRewrites(Rec);
+  Editor.applyRewrites(Rec, /*adjustRemovals=*/false);
 
   const RewriteBuffer *Buf = rewriter.getRewriteBufferFor(FID);
   SmallString<512> NewText;
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index b531a66..c8cdc72 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4078,11 +4078,6 @@
                   bool allowOnPointerType) const {
   hasError = false;
 
-  if (const ObjCTypeParamType *objT =
-      dyn_cast<ObjCTypeParamType>(type.getTypePtr())) {
-    return getObjCTypeParamType(objT->getDecl(), protocols);
-  }
-
   // Apply protocol qualifiers to ObjCObjectPointerType.
   if (allowOnPointerType) {
     if (const ObjCObjectPointerType *objPtr =
@@ -8870,22 +8865,30 @@
     return GVA_Internal;
 
   if (VD->isStaticLocal()) {
-    GVALinkage StaticLocalLinkage = GVA_DiscardableODR;
     const DeclContext *LexicalContext = VD->getParentFunctionOrMethod();
     while (LexicalContext && !isa<FunctionDecl>(LexicalContext))
       LexicalContext = LexicalContext->getLexicalParent();
 
-    // Let the static local variable inherit its linkage from the nearest
-    // enclosing function.
-    if (LexicalContext)
-      StaticLocalLinkage =
-          Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
+    // ObjC Blocks can create local variables that don't have a FunctionDecl
+    // LexicalContext.
+    if (!LexicalContext)
+      return GVA_DiscardableODR;
 
-    // GVA_StrongODR function linkage is stronger than what we need,
-    // downgrade to GVA_DiscardableODR.
-    // This allows us to discard the variable if we never end up needing it.
-    return StaticLocalLinkage == GVA_StrongODR ? GVA_DiscardableODR
-                                               : StaticLocalLinkage;
+    // Otherwise, let the static local variable inherit its linkage from the
+    // nearest enclosing function.
+    auto StaticLocalLinkage =
+        Context.GetGVALinkageForFunction(cast<FunctionDecl>(LexicalContext));
+
+    // Itanium ABI 5.2.2: "Each COMDAT group [for a static local variable] must
+    // be emitted in any object with references to the symbol for the object it
+    // contains, whether inline or out-of-line."
+    // Similar behavior is observed with MSVC. An alternative ABI could use
+    // StrongODR/AvailableExternally to match the function, but none are
+    // known/supported currently.
+    if (StaticLocalLinkage == GVA_StrongODR ||
+        StaticLocalLinkage == GVA_AvailableExternally)
+      return GVA_DiscardableODR;
+    return StaticLocalLinkage;
   }
 
   // MSVC treats in-class initialized static data members as definitions.
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 1ccb746..fa9d1e8 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -14,6 +14,7 @@
 #include "clang/AST/ASTImporter.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/ASTStructuralEquivalence.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclVisitor.h"
@@ -319,1284 +320,12 @@
   };
 }
 
-using namespace clang;
-
-//----------------------------------------------------------------------------
-// Structural Equivalence
-//----------------------------------------------------------------------------
-
-namespace {
-  struct StructuralEquivalenceContext {
-    /// \brief AST contexts for which we are checking structural equivalence.
-    ASTContext &C1, &C2;
-    
-    /// \brief The set of "tentative" equivalences between two canonical 
-    /// declarations, mapping from a declaration in the first context to the
-    /// declaration in the second context that we believe to be equivalent.
-    llvm::DenseMap<Decl *, Decl *> TentativeEquivalences;
-    
-    /// \brief Queue of declarations in the first context whose equivalence
-    /// with a declaration in the second context still needs to be verified.
-    std::deque<Decl *> DeclsToCheck;
-    
-    /// \brief Declaration (from, to) pairs that are known not to be equivalent
-    /// (which we have already complained about).
-    llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls;
-    
-    /// \brief Whether we're being strict about the spelling of types when 
-    /// unifying two types.
-    bool StrictTypeSpelling;
-
-    /// \brief Whether to complain about failures.
-    bool Complain;
-
-    /// \brief \c true if the last diagnostic came from C2.
-    bool LastDiagFromC2;
-
-    StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
-               llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
-                                 bool StrictTypeSpelling = false,
-                                 bool Complain = true)
-      : C1(C1), C2(C2), NonEquivalentDecls(NonEquivalentDecls),
-        StrictTypeSpelling(StrictTypeSpelling), Complain(Complain),
-        LastDiagFromC2(false) {}
-
-    /// \brief Determine whether the two declarations are structurally
-    /// equivalent.
-    bool IsStructurallyEquivalent(Decl *D1, Decl *D2);
-    
-    /// \brief Determine whether the two types are structurally equivalent.
-    bool IsStructurallyEquivalent(QualType T1, QualType T2);
-
-  private:
-    /// \brief Finish checking all of the structural equivalences.
-    ///
-    /// \returns true if an error occurred, false otherwise.
-    bool Finish();
-    
-  public:
-    DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
-      assert(Complain && "Not allowed to complain");
-      if (LastDiagFromC2)
-        C1.getDiagnostics().notePriorDiagnosticFrom(C2.getDiagnostics());
-      LastDiagFromC2 = false;
-      return C1.getDiagnostics().Report(Loc, DiagID);
-    }
-
-    DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
-      assert(Complain && "Not allowed to complain");
-      if (!LastDiagFromC2)
-        C2.getDiagnostics().notePriorDiagnosticFrom(C1.getDiagnostics());
-      LastDiagFromC2 = true;
-      return C2.getDiagnostics().Report(Loc, DiagID);
-    }
-  };
-}
-
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     QualType T1, QualType T2);
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     Decl *D1, Decl *D2);
-
-/// \brief Determine structural equivalence of two expressions.
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     Expr *E1, Expr *E2) {
-  if (!E1 || !E2)
-    return E1 == E2;
-  
-  // FIXME: Actually perform a structural comparison!
-  return true;
-}
-
-/// \brief Determine whether two identifiers are equivalent.
-static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
-                                     const IdentifierInfo *Name2) {
-  if (!Name1 || !Name2)
-    return Name1 == Name2;
-  
-  return Name1->getName() == Name2->getName();
-}
-
-/// \brief Determine whether two nested-name-specifiers are equivalent.
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     NestedNameSpecifier *NNS1,
-                                     NestedNameSpecifier *NNS2) {
-  // FIXME: Implement!
-  return true;
-}
-
-/// \brief Determine whether two template arguments are equivalent.
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     const TemplateArgument &Arg1,
-                                     const TemplateArgument &Arg2) {
-  if (Arg1.getKind() != Arg2.getKind())
-    return false;
-
-  switch (Arg1.getKind()) {
-  case TemplateArgument::Null:
-    return true;
-      
-  case TemplateArgument::Type:
-    return Context.IsStructurallyEquivalent(Arg1.getAsType(), Arg2.getAsType());
-
-  case TemplateArgument::Integral:
-    if (!Context.IsStructurallyEquivalent(Arg1.getIntegralType(), 
-                                          Arg2.getIntegralType()))
-      return false;
-    
-    return llvm::APSInt::isSameValue(Arg1.getAsIntegral(), Arg2.getAsIntegral());
-      
-  case TemplateArgument::Declaration:
-    return Context.IsStructurallyEquivalent(Arg1.getAsDecl(), Arg2.getAsDecl());
-
-  case TemplateArgument::NullPtr:
-    return true; // FIXME: Is this correct?
-
-  case TemplateArgument::Template:
-    return IsStructurallyEquivalent(Context, 
-                                    Arg1.getAsTemplate(), 
-                                    Arg2.getAsTemplate());
-
-  case TemplateArgument::TemplateExpansion:
-    return IsStructurallyEquivalent(Context, 
-                                    Arg1.getAsTemplateOrTemplatePattern(), 
-                                    Arg2.getAsTemplateOrTemplatePattern());
-
-  case TemplateArgument::Expression:
-    return IsStructurallyEquivalent(Context, 
-                                    Arg1.getAsExpr(), Arg2.getAsExpr());
-      
-  case TemplateArgument::Pack:
-    if (Arg1.pack_size() != Arg2.pack_size())
-      return false;
-      
-    for (unsigned I = 0, N = Arg1.pack_size(); I != N; ++I)
-      if (!IsStructurallyEquivalent(Context, 
-                                    Arg1.pack_begin()[I],
-                                    Arg2.pack_begin()[I]))
-        return false;
-      
-    return true;
-  }
-  
-  llvm_unreachable("Invalid template argument kind");
-}
-
-/// \brief Determine structural equivalence for the common part of array 
-/// types.
-static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                          const ArrayType *Array1, 
-                                          const ArrayType *Array2) {
-  if (!IsStructurallyEquivalent(Context, 
-                                Array1->getElementType(), 
-                                Array2->getElementType()))
-    return false;
-  if (Array1->getSizeModifier() != Array2->getSizeModifier())
-    return false;
-  if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
-    return false;
-  
-  return true;
-}
-
-/// \brief Determine structural equivalence of two types.
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     QualType T1, QualType T2) {
-  if (T1.isNull() || T2.isNull())
-    return T1.isNull() && T2.isNull();
-  
-  if (!Context.StrictTypeSpelling) {
-    // We aren't being strict about token-to-token equivalence of types,
-    // so map down to the canonical type.
-    T1 = Context.C1.getCanonicalType(T1);
-    T2 = Context.C2.getCanonicalType(T2);
-  }
-  
-  if (T1.getQualifiers() != T2.getQualifiers())
-    return false;
-  
-  Type::TypeClass TC = T1->getTypeClass();
-  
-  if (T1->getTypeClass() != T2->getTypeClass()) {
-    // Compare function types with prototypes vs. without prototypes as if
-    // both did not have prototypes.
-    if (T1->getTypeClass() == Type::FunctionProto &&
-        T2->getTypeClass() == Type::FunctionNoProto)
-      TC = Type::FunctionNoProto;
-    else if (T1->getTypeClass() == Type::FunctionNoProto &&
-             T2->getTypeClass() == Type::FunctionProto)
-      TC = Type::FunctionNoProto;
-    else
-      return false;
-  }
-  
-  switch (TC) {
-  case Type::Builtin:
-    // FIXME: Deal with Char_S/Char_U. 
-    if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
-      return false;
-    break;
-  
-  case Type::Complex:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<ComplexType>(T1)->getElementType(),
-                                  cast<ComplexType>(T2)->getElementType()))
-      return false;
-    break;
-  
-  case Type::Adjusted:
-  case Type::Decayed:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<AdjustedType>(T1)->getOriginalType(),
-                                  cast<AdjustedType>(T2)->getOriginalType()))
-      return false;
-    break;
-
-  case Type::Pointer:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<PointerType>(T1)->getPointeeType(),
-                                  cast<PointerType>(T2)->getPointeeType()))
-      return false;
-    break;
-
-  case Type::BlockPointer:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<BlockPointerType>(T1)->getPointeeType(),
-                                  cast<BlockPointerType>(T2)->getPointeeType()))
-      return false;
-    break;
-
-  case Type::LValueReference:
-  case Type::RValueReference: {
-    const ReferenceType *Ref1 = cast<ReferenceType>(T1);
-    const ReferenceType *Ref2 = cast<ReferenceType>(T2);
-    if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
-      return false;
-    if (Ref1->isInnerRef() != Ref2->isInnerRef())
-      return false;
-    if (!IsStructurallyEquivalent(Context,
-                                  Ref1->getPointeeTypeAsWritten(),
-                                  Ref2->getPointeeTypeAsWritten()))
-      return false;
-    break;
-  }
-      
-  case Type::MemberPointer: {
-    const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
-    const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
-    if (!IsStructurallyEquivalent(Context,
-                                  MemPtr1->getPointeeType(),
-                                  MemPtr2->getPointeeType()))
-      return false;
-    if (!IsStructurallyEquivalent(Context,
-                                  QualType(MemPtr1->getClass(), 0),
-                                  QualType(MemPtr2->getClass(), 0)))
-      return false;
-    break;
-  }
-      
-  case Type::ConstantArray: {
-    const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
-    const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
-    if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
-      return false;
-    
-    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
-      return false;
-    break;
-  }
-
-  case Type::IncompleteArray:
-    if (!IsArrayStructurallyEquivalent(Context, 
-                                       cast<ArrayType>(T1), 
-                                       cast<ArrayType>(T2)))
-      return false;
-    break;
-      
-  case Type::VariableArray: {
-    const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
-    const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
-    if (!IsStructurallyEquivalent(Context, 
-                                  Array1->getSizeExpr(), Array2->getSizeExpr()))
-      return false;
-    
-    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
-      return false;
-    
-    break;
-  }
-  
-  case Type::DependentSizedArray: {
-    const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
-    const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
-    if (!IsStructurallyEquivalent(Context, 
-                                  Array1->getSizeExpr(), Array2->getSizeExpr()))
-      return false;
-    
-    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
-      return false;
-    
-    break;
-  }
-      
-  case Type::DependentSizedExtVector: {
-    const DependentSizedExtVectorType *Vec1
-      = cast<DependentSizedExtVectorType>(T1);
-    const DependentSizedExtVectorType *Vec2
-      = cast<DependentSizedExtVectorType>(T2);
-    if (!IsStructurallyEquivalent(Context, 
-                                  Vec1->getSizeExpr(), Vec2->getSizeExpr()))
-      return false;
-    if (!IsStructurallyEquivalent(Context, 
-                                  Vec1->getElementType(), 
-                                  Vec2->getElementType()))
-      return false;
-    break;
-  }
-   
-  case Type::Vector: 
-  case Type::ExtVector: {
-    const VectorType *Vec1 = cast<VectorType>(T1);
-    const VectorType *Vec2 = cast<VectorType>(T2);
-    if (!IsStructurallyEquivalent(Context, 
-                                  Vec1->getElementType(),
-                                  Vec2->getElementType()))
-      return false;
-    if (Vec1->getNumElements() != Vec2->getNumElements())
-      return false;
-    if (Vec1->getVectorKind() != Vec2->getVectorKind())
-      return false;
-    break;
-  }
-
-  case Type::FunctionProto: {
-    const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
-    const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
-    if (Proto1->getNumParams() != Proto2->getNumParams())
-      return false;
-    for (unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
-      if (!IsStructurallyEquivalent(Context, Proto1->getParamType(I),
-                                    Proto2->getParamType(I)))
-        return false;
-    }
-    if (Proto1->isVariadic() != Proto2->isVariadic())
-      return false;
-    if (Proto1->getExceptionSpecType() != Proto2->getExceptionSpecType())
-      return false;
-    if (Proto1->getExceptionSpecType() == EST_Dynamic) {
-      if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
-        return false;
-      for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
-        if (!IsStructurallyEquivalent(Context,
-                                      Proto1->getExceptionType(I),
-                                      Proto2->getExceptionType(I)))
-          return false;
-      }
-    } else if (Proto1->getExceptionSpecType() == EST_ComputedNoexcept) {
-      if (!IsStructurallyEquivalent(Context,
-                                    Proto1->getNoexceptExpr(),
-                                    Proto2->getNoexceptExpr()))
-        return false;
-    }
-    if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
-      return false;
-    
-    // Fall through to check the bits common with FunctionNoProtoType.
-  }
-      
-  case Type::FunctionNoProto: {
-    const FunctionType *Function1 = cast<FunctionType>(T1);
-    const FunctionType *Function2 = cast<FunctionType>(T2);
-    if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
-                                  Function2->getReturnType()))
-      return false;
-    if (Function1->getExtInfo() != Function2->getExtInfo())
-      return false;
-    break;
-  }
-   
-  case Type::UnresolvedUsing:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<UnresolvedUsingType>(T1)->getDecl(),
-                                  cast<UnresolvedUsingType>(T2)->getDecl()))
-      return false;
-      
-    break;
-
-  case Type::Attributed:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<AttributedType>(T1)->getModifiedType(),
-                                  cast<AttributedType>(T2)->getModifiedType()))
-      return false;
-    if (!IsStructurallyEquivalent(Context,
-                                cast<AttributedType>(T1)->getEquivalentType(),
-                                cast<AttributedType>(T2)->getEquivalentType()))
-      return false;
-    break;
-      
-  case Type::Paren:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<ParenType>(T1)->getInnerType(),
-                                  cast<ParenType>(T2)->getInnerType()))
-      return false;
-    break;
-
-  case Type::Typedef:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<TypedefType>(T1)->getDecl(),
-                                  cast<TypedefType>(T2)->getDecl()))
-      return false;
-    break;
-      
-  case Type::TypeOfExpr:
-    if (!IsStructurallyEquivalent(Context,
-                                cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
-                                cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
-      return false;
-    break;
-      
-  case Type::TypeOf:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<TypeOfType>(T1)->getUnderlyingType(),
-                                  cast<TypeOfType>(T2)->getUnderlyingType()))
-      return false;
-    break;
-
-  case Type::UnaryTransform:
-    if (!IsStructurallyEquivalent(Context,
-                             cast<UnaryTransformType>(T1)->getUnderlyingType(),
-                             cast<UnaryTransformType>(T1)->getUnderlyingType()))
-      return false;
-    break;
-
-  case Type::Decltype:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<DecltypeType>(T1)->getUnderlyingExpr(),
-                                  cast<DecltypeType>(T2)->getUnderlyingExpr()))
-      return false;
-    break;
-
-  case Type::Auto:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<AutoType>(T1)->getDeducedType(),
-                                  cast<AutoType>(T2)->getDeducedType()))
-      return false;
-    break;
-
-  case Type::Record:
-  case Type::Enum:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<TagType>(T1)->getDecl(),
-                                  cast<TagType>(T2)->getDecl()))
-      return false;
-    break;
-
-  case Type::TemplateTypeParm: {
-    const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
-    const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
-    if (Parm1->getDepth() != Parm2->getDepth())
-      return false;
-    if (Parm1->getIndex() != Parm2->getIndex())
-      return false;
-    if (Parm1->isParameterPack() != Parm2->isParameterPack())
-      return false;
-    
-    // Names of template type parameters are never significant.
-    break;
-  }
-      
-  case Type::SubstTemplateTypeParm: {
-    const SubstTemplateTypeParmType *Subst1
-      = cast<SubstTemplateTypeParmType>(T1);
-    const SubstTemplateTypeParmType *Subst2
-      = cast<SubstTemplateTypeParmType>(T2);
-    if (!IsStructurallyEquivalent(Context,
-                                  QualType(Subst1->getReplacedParameter(), 0),
-                                  QualType(Subst2->getReplacedParameter(), 0)))
-      return false;
-    if (!IsStructurallyEquivalent(Context, 
-                                  Subst1->getReplacementType(),
-                                  Subst2->getReplacementType()))
-      return false;
-    break;
-  }
-
-  case Type::SubstTemplateTypeParmPack: {
-    const SubstTemplateTypeParmPackType *Subst1
-      = cast<SubstTemplateTypeParmPackType>(T1);
-    const SubstTemplateTypeParmPackType *Subst2
-      = cast<SubstTemplateTypeParmPackType>(T2);
-    if (!IsStructurallyEquivalent(Context,
-                                  QualType(Subst1->getReplacedParameter(), 0),
-                                  QualType(Subst2->getReplacedParameter(), 0)))
-      return false;
-    if (!IsStructurallyEquivalent(Context, 
-                                  Subst1->getArgumentPack(),
-                                  Subst2->getArgumentPack()))
-      return false;
-    break;
-  }
-  case Type::TemplateSpecialization: {
-    const TemplateSpecializationType *Spec1
-      = cast<TemplateSpecializationType>(T1);
-    const TemplateSpecializationType *Spec2
-      = cast<TemplateSpecializationType>(T2);
-    if (!IsStructurallyEquivalent(Context,
-                                  Spec1->getTemplateName(),
-                                  Spec2->getTemplateName()))
-      return false;
-    if (Spec1->getNumArgs() != Spec2->getNumArgs())
-      return false;
-    for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
-      if (!IsStructurallyEquivalent(Context, 
-                                    Spec1->getArg(I), Spec2->getArg(I)))
-        return false;
-    }
-    break;
-  }
-      
-  case Type::Elaborated: {
-    const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
-    const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
-    // CHECKME: what if a keyword is ETK_None or ETK_typename ?
-    if (Elab1->getKeyword() != Elab2->getKeyword())
-      return false;
-    if (!IsStructurallyEquivalent(Context, 
-                                  Elab1->getQualifier(), 
-                                  Elab2->getQualifier()))
-      return false;
-    if (!IsStructurallyEquivalent(Context,
-                                  Elab1->getNamedType(),
-                                  Elab2->getNamedType()))
-      return false;
-    break;
-  }
-
-  case Type::InjectedClassName: {
-    const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
-    const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
-    if (!IsStructurallyEquivalent(Context,
-                                  Inj1->getInjectedSpecializationType(),
-                                  Inj2->getInjectedSpecializationType()))
-      return false;
-    break;
-  }
-
-  case Type::DependentName: {
-    const DependentNameType *Typename1 = cast<DependentNameType>(T1);
-    const DependentNameType *Typename2 = cast<DependentNameType>(T2);
-    if (!IsStructurallyEquivalent(Context, 
-                                  Typename1->getQualifier(),
-                                  Typename2->getQualifier()))
-      return false;
-    if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
-                                  Typename2->getIdentifier()))
-      return false;
-    
-    break;
-  }
-  
-  case Type::DependentTemplateSpecialization: {
-    const DependentTemplateSpecializationType *Spec1 =
-      cast<DependentTemplateSpecializationType>(T1);
-    const DependentTemplateSpecializationType *Spec2 =
-      cast<DependentTemplateSpecializationType>(T2);
-    if (!IsStructurallyEquivalent(Context, 
-                                  Spec1->getQualifier(),
-                                  Spec2->getQualifier()))
-      return false;
-    if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
-                                  Spec2->getIdentifier()))
-      return false;
-    if (Spec1->getNumArgs() != Spec2->getNumArgs())
-      return false;
-    for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
-      if (!IsStructurallyEquivalent(Context,
-                                    Spec1->getArg(I), Spec2->getArg(I)))
-        return false;
-    }
-    break;
-  }
-
-  case Type::PackExpansion:
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<PackExpansionType>(T1)->getPattern(),
-                                  cast<PackExpansionType>(T2)->getPattern()))
-      return false;
-    break;
-
-  case Type::ObjCInterface: {
-    const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
-    const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
-    if (!IsStructurallyEquivalent(Context, 
-                                  Iface1->getDecl(), Iface2->getDecl()))
-      return false;
-    break;
-  }
-
-  case Type::ObjCTypeParam: {
-    const ObjCTypeParamType *Obj1 = cast<ObjCTypeParamType>(T1);
-    const ObjCTypeParamType *Obj2 = cast<ObjCTypeParamType>(T2);
-    if (!IsStructurallyEquivalent(Context, Obj1->getDecl(),
-                                  Obj2->getDecl()))
-      return false;
-
-    if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
-      return false;
-    for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
-      if (!IsStructurallyEquivalent(Context,
-                                    Obj1->getProtocol(I),
-                                    Obj2->getProtocol(I)))
-        return false;
-    }
-    break;
-  }
-  case Type::ObjCObject: {
-    const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
-    const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
-    if (!IsStructurallyEquivalent(Context,
-                                  Obj1->getBaseType(),
-                                  Obj2->getBaseType()))
-      return false;
-    if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
-      return false;
-    for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
-      if (!IsStructurallyEquivalent(Context,
-                                    Obj1->getProtocol(I),
-                                    Obj2->getProtocol(I)))
-        return false;
-    }
-    break;
-  }
-
-  case Type::ObjCObjectPointer: {
-    const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
-    const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
-    if (!IsStructurallyEquivalent(Context, 
-                                  Ptr1->getPointeeType(),
-                                  Ptr2->getPointeeType()))
-      return false;
-    break;
-  }
-
-  case Type::Atomic: {
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<AtomicType>(T1)->getValueType(),
-                                  cast<AtomicType>(T2)->getValueType()))
-      return false;
-    break;
-  }
-
-  case Type::Pipe: {
-    if (!IsStructurallyEquivalent(Context,
-                                  cast<PipeType>(T1)->getElementType(),
-                                  cast<PipeType>(T2)->getElementType()))
-      return false;
-    break;
-  }
-
-  } // end switch
-
-  return true;
-}
-
-/// \brief Determine structural equivalence of two fields.
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     FieldDecl *Field1, FieldDecl *Field2) {
-  RecordDecl *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
-
-  // For anonymous structs/unions, match up the anonymous struct/union type
-  // declarations directly, so that we don't go off searching for anonymous
-  // types
-  if (Field1->isAnonymousStructOrUnion() &&
-      Field2->isAnonymousStructOrUnion()) {
-    RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl();
-    RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl();
-    return IsStructurallyEquivalent(Context, D1, D2);
-  }
-    
-  // Check for equivalent field names.
-  IdentifierInfo *Name1 = Field1->getIdentifier();
-  IdentifierInfo *Name2 = Field2->getIdentifier();
-  if (!::IsStructurallyEquivalent(Name1, Name2))
-    return false;
-
-  if (!IsStructurallyEquivalent(Context,
-                                Field1->getType(), Field2->getType())) {
-    if (Context.Complain) {
-      Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-        << Context.C2.getTypeDeclType(Owner2);
-      Context.Diag2(Field2->getLocation(), diag::note_odr_field)
-        << Field2->getDeclName() << Field2->getType();
-      Context.Diag1(Field1->getLocation(), diag::note_odr_field)
-        << Field1->getDeclName() << Field1->getType();
-    }
-    return false;
-  }
-  
-  if (Field1->isBitField() != Field2->isBitField()) {
-    if (Context.Complain) {
-      Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-        << Context.C2.getTypeDeclType(Owner2);
-      if (Field1->isBitField()) {
-        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
-        << Field1->getDeclName() << Field1->getType()
-        << Field1->getBitWidthValue(Context.C1);
-        Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
-        << Field2->getDeclName();
-      } else {
-        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
-        << Field2->getDeclName() << Field2->getType()
-        << Field2->getBitWidthValue(Context.C2);
-        Context.Diag1(Field1->getLocation(), diag::note_odr_not_bit_field)
-        << Field1->getDeclName();
-      }
-    }
-    return false;
-  }
-  
-  if (Field1->isBitField()) {
-    // Make sure that the bit-fields are the same length.
-    unsigned Bits1 = Field1->getBitWidthValue(Context.C1);
-    unsigned Bits2 = Field2->getBitWidthValue(Context.C2);
-    
-    if (Bits1 != Bits2) {
-      if (Context.Complain) {
-        Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-          << Context.C2.getTypeDeclType(Owner2);
-        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
-          << Field2->getDeclName() << Field2->getType() << Bits2;
-        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
-          << Field1->getDeclName() << Field1->getType() << Bits1;
-      }
-      return false;
-    }
-  }
-
-  return true;
-}
-
-/// \brief Find the index of the given anonymous struct/union within its
-/// context.
-///
-/// \returns Returns the index of this anonymous struct/union in its context,
-/// including the next assigned index (if none of them match). Returns an
-/// empty option if the context is not a record, i.e.. if the anonymous
-/// struct/union is at namespace or block scope.
-static Optional<unsigned> findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
-  ASTContext &Context = Anon->getASTContext();
-  QualType AnonTy = Context.getRecordType(Anon);
-
-  RecordDecl *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
-  if (!Owner)
-    return None;
-
-  unsigned Index = 0;
-  for (const auto *D : Owner->noload_decls()) {
-    const auto *F = dyn_cast<FieldDecl>(D);
-    if (!F)
-      continue;
-
-    if (F->isAnonymousStructOrUnion()) {
-      if (Context.hasSameType(F->getType(), AnonTy))
-        break;
-      ++Index;
-      continue;
-    }
-
-    // If the field looks like this:
-    // struct { ... } A;
-    QualType FieldType = F->getType();
-    if (const auto *RecType = dyn_cast<RecordType>(FieldType)) {
-      const RecordDecl *RecDecl = RecType->getDecl();
-      if (RecDecl->getDeclContext() == Owner &&
-          !RecDecl->getIdentifier()) {
-        if (Context.hasSameType(FieldType, AnonTy))
-          break;
-        ++Index;
-        continue;
-      }
-    }
-  }
-
-  return Index;
-}
-
-/// \brief Determine structural equivalence of two records.
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     RecordDecl *D1, RecordDecl *D2) {
-  if (D1->isUnion() != D2->isUnion()) {
-    if (Context.Complain) {
-      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-        << Context.C2.getTypeDeclType(D2);
-      Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
-        << D1->getDeclName() << (unsigned)D1->getTagKind();
-    }
-    return false;
-  }
-
-  if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) {
-    // If both anonymous structs/unions are in a record context, make sure
-    // they occur in the same location in the context records.
-    if (Optional<unsigned> Index1 = findUntaggedStructOrUnionIndex(D1)) {
-      if (Optional<unsigned> Index2 = findUntaggedStructOrUnionIndex(D2)) {
-        if (*Index1 != *Index2)
-          return false;
-      }
-    }
-  }
-
-  // If both declarations are class template specializations, we know
-  // the ODR applies, so check the template and template arguments.
-  ClassTemplateSpecializationDecl *Spec1
-    = dyn_cast<ClassTemplateSpecializationDecl>(D1);
-  ClassTemplateSpecializationDecl *Spec2
-    = dyn_cast<ClassTemplateSpecializationDecl>(D2);
-  if (Spec1 && Spec2) {
-    // Check that the specialized templates are the same.
-    if (!IsStructurallyEquivalent(Context, Spec1->getSpecializedTemplate(),
-                                  Spec2->getSpecializedTemplate()))
-      return false;
-    
-    // Check that the template arguments are the same.
-    if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
-      return false;
-    
-    for (unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
-      if (!IsStructurallyEquivalent(Context, 
-                                    Spec1->getTemplateArgs().get(I),
-                                    Spec2->getTemplateArgs().get(I)))
-        return false;
-  }  
-  // If one is a class template specialization and the other is not, these
-  // structures are different.
-  else if (Spec1 || Spec2)
-    return false;
-
-  // Compare the definitions of these two records. If either or both are
-  // incomplete, we assume that they are equivalent.
-  D1 = D1->getDefinition();
-  D2 = D2->getDefinition();
-  if (!D1 || !D2)
-    return true;
-  
-  if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
-    if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
-      if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
-        if (Context.Complain) {
-          Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-            << Context.C2.getTypeDeclType(D2);
-          Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
-            << D2CXX->getNumBases();
-          Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
-            << D1CXX->getNumBases();
-        }
-        return false;
-      }
-      
-      // Check the base classes. 
-      for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(), 
-                                           BaseEnd1 = D1CXX->bases_end(),
-                                                Base2 = D2CXX->bases_begin();
-           Base1 != BaseEnd1;
-           ++Base1, ++Base2) {        
-        if (!IsStructurallyEquivalent(Context, 
-                                      Base1->getType(), Base2->getType())) {
-          if (Context.Complain) {
-            Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-              << Context.C2.getTypeDeclType(D2);
-            Context.Diag2(Base2->getLocStart(), diag::note_odr_base)
-              << Base2->getType()
-              << Base2->getSourceRange();
-            Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
-              << Base1->getType()
-              << Base1->getSourceRange();
-          }
-          return false;
-        }
-        
-        // Check virtual vs. non-virtual inheritance mismatch.
-        if (Base1->isVirtual() != Base2->isVirtual()) {
-          if (Context.Complain) {
-            Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-              << Context.C2.getTypeDeclType(D2);
-            Context.Diag2(Base2->getLocStart(),
-                          diag::note_odr_virtual_base)
-              << Base2->isVirtual() << Base2->getSourceRange();
-            Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
-              << Base1->isVirtual()
-              << Base1->getSourceRange();
-          }
-          return false;
-        }
-      }
-    } else if (D1CXX->getNumBases() > 0) {
-      if (Context.Complain) {
-        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-          << Context.C2.getTypeDeclType(D2);
-        const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
-        Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
-          << Base1->getType()
-          << Base1->getSourceRange();
-        Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
-      }
-      return false;
-    }
-  }
-  
-  // Check the fields for consistency.
-  RecordDecl::field_iterator Field2 = D2->field_begin(),
-                             Field2End = D2->field_end();
-  for (RecordDecl::field_iterator Field1 = D1->field_begin(),
-                                  Field1End = D1->field_end();
-       Field1 != Field1End;
-       ++Field1, ++Field2) {
-    if (Field2 == Field2End) {
-      if (Context.Complain) {
-        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-          << Context.C2.getTypeDeclType(D2);
-        Context.Diag1(Field1->getLocation(), diag::note_odr_field)
-          << Field1->getDeclName() << Field1->getType();
-        Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
-      }
-      return false;
-    }
-    
-    if (!IsStructurallyEquivalent(Context, *Field1, *Field2))
-      return false;    
-  }
-  
-  if (Field2 != Field2End) {
-    if (Context.Complain) {
-      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-        << Context.C2.getTypeDeclType(D2);
-      Context.Diag2(Field2->getLocation(), diag::note_odr_field)
-        << Field2->getDeclName() << Field2->getType();
-      Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
-    }
-    return false;
-  }
-  
-  return true;
-}
-     
-/// \brief Determine structural equivalence of two enums.
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     EnumDecl *D1, EnumDecl *D2) {
-  EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
-                             EC2End = D2->enumerator_end();
-  for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
-                                  EC1End = D1->enumerator_end();
-       EC1 != EC1End; ++EC1, ++EC2) {
-    if (EC2 == EC2End) {
-      if (Context.Complain) {
-        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-          << Context.C2.getTypeDeclType(D2);
-        Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
-          << EC1->getDeclName() 
-          << EC1->getInitVal().toString(10);
-        Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
-      }
-      return false;
-    }
-    
-    llvm::APSInt Val1 = EC1->getInitVal();
-    llvm::APSInt Val2 = EC2->getInitVal();
-    if (!llvm::APSInt::isSameValue(Val1, Val2) || 
-        !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
-      if (Context.Complain) {
-        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-          << Context.C2.getTypeDeclType(D2);
-        Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
-          << EC2->getDeclName() 
-          << EC2->getInitVal().toString(10);
-        Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
-          << EC1->getDeclName() 
-          << EC1->getInitVal().toString(10);
-      }
-      return false;
-    }
-  }
-  
-  if (EC2 != EC2End) {
-    if (Context.Complain) {
-      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
-        << Context.C2.getTypeDeclType(D2);
-      Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
-        << EC2->getDeclName() 
-        << EC2->getInitVal().toString(10);
-      Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
-    }
-    return false;
-  }
-  
-  return true;
-}
-
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     TemplateParameterList *Params1,
-                                     TemplateParameterList *Params2) {
-  if (Params1->size() != Params2->size()) {
-    if (Context.Complain) {
-      Context.Diag2(Params2->getTemplateLoc(), 
-                    diag::err_odr_different_num_template_parameters)
-        << Params1->size() << Params2->size();
-      Context.Diag1(Params1->getTemplateLoc(), 
-                    diag::note_odr_template_parameter_list);
-    }
-    return false;
-  }
-  
-  for (unsigned I = 0, N = Params1->size(); I != N; ++I) {
-    if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
-      if (Context.Complain) {
-        Context.Diag2(Params2->getParam(I)->getLocation(), 
-                      diag::err_odr_different_template_parameter_kind);
-        Context.Diag1(Params1->getParam(I)->getLocation(),
-                      diag::note_odr_template_parameter_here);
-      }
-      return false;
-    }
-    
-    if (!Context.IsStructurallyEquivalent(Params1->getParam(I),
-                                          Params2->getParam(I))) {
-      
-      return false;
-    }
-  }
-  
-  return true;
-}
-
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     TemplateTypeParmDecl *D1,
-                                     TemplateTypeParmDecl *D2) {
-  if (D1->isParameterPack() != D2->isParameterPack()) {
-    if (Context.Complain) {
-      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
-        << D2->isParameterPack();
-      Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
-        << D1->isParameterPack();
-    }
-    return false;
-  }
-  
-  return true;
-}
-
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     NonTypeTemplateParmDecl *D1,
-                                     NonTypeTemplateParmDecl *D2) {
-  if (D1->isParameterPack() != D2->isParameterPack()) {
-    if (Context.Complain) {
-      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
-        << D2->isParameterPack();
-      Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
-        << D1->isParameterPack();
-    }
-    return false;
-  }
-  
-  // Check types.
-  if (!Context.IsStructurallyEquivalent(D1->getType(), D2->getType())) {
-    if (Context.Complain) {
-      Context.Diag2(D2->getLocation(),
-                    diag::err_odr_non_type_parameter_type_inconsistent)
-        << D2->getType() << D1->getType();
-      Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
-        << D1->getType();
-    }
-    return false;
-  }
-  
-  return true;
-}
-
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     TemplateTemplateParmDecl *D1,
-                                     TemplateTemplateParmDecl *D2) {
-  if (D1->isParameterPack() != D2->isParameterPack()) {
-    if (Context.Complain) {
-      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
-        << D2->isParameterPack();
-      Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
-        << D1->isParameterPack();
-    }
-    return false;
-  }
-
-  // Check template parameter lists.
-  return IsStructurallyEquivalent(Context, D1->getTemplateParameters(),
-                                  D2->getTemplateParameters());
-}
-
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     ClassTemplateDecl *D1, 
-                                     ClassTemplateDecl *D2) {
-  // Check template parameters.
-  if (!IsStructurallyEquivalent(Context,
-                                D1->getTemplateParameters(),
-                                D2->getTemplateParameters()))
-    return false;
-  
-  // Check the templated declaration.
-  return Context.IsStructurallyEquivalent(D1->getTemplatedDecl(), 
-                                          D2->getTemplatedDecl());
-}
-
-/// \brief Determine structural equivalence of two declarations.
-static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
-                                     Decl *D1, Decl *D2) {
-  // FIXME: Check for known structural equivalences via a callback of some sort.
-  
-  // Check whether we already know that these two declarations are not
-  // structurally equivalent.
-  if (Context.NonEquivalentDecls.count(std::make_pair(D1->getCanonicalDecl(),
-                                                      D2->getCanonicalDecl())))
-    return false;
-  
-  // Determine whether we've already produced a tentative equivalence for D1.
-  Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
-  if (EquivToD1)
-    return EquivToD1 == D2->getCanonicalDecl();
-  
-  // Produce a tentative equivalence D1 <-> D2, which will be checked later.
-  EquivToD1 = D2->getCanonicalDecl();
-  Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
-  return true;
-}
-
-bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1, 
-                                                            Decl *D2) {
-  if (!::IsStructurallyEquivalent(*this, D1, D2))
-    return false;
-  
-  return !Finish();
-}
-
-bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1, 
-                                                            QualType T2) {
-  if (!::IsStructurallyEquivalent(*this, T1, T2))
-    return false;
-  
-  return !Finish();
-}
-
-bool StructuralEquivalenceContext::Finish() {
-  while (!DeclsToCheck.empty()) {
-    // Check the next declaration.
-    Decl *D1 = DeclsToCheck.front();
-    DeclsToCheck.pop_front();
-    
-    Decl *D2 = TentativeEquivalences[D1];
-    assert(D2 && "Unrecorded tentative equivalence?");
-    
-    bool Equivalent = true;
-    
-    // FIXME: Switch on all declaration kinds. For now, we're just going to
-    // check the obvious ones.
-    if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
-      if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
-        // Check for equivalent structure names.
-        IdentifierInfo *Name1 = Record1->getIdentifier();
-        if (!Name1 && Record1->getTypedefNameForAnonDecl())
-          Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
-        IdentifierInfo *Name2 = Record2->getIdentifier();
-        if (!Name2 && Record2->getTypedefNameForAnonDecl())
-          Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
-        if (!::IsStructurallyEquivalent(Name1, Name2) ||
-            !::IsStructurallyEquivalent(*this, Record1, Record2))
-          Equivalent = false;
-      } else {
-        // Record/non-record mismatch.
-        Equivalent = false;
-      }
-    } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
-      if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
-        // Check for equivalent enum names.
-        IdentifierInfo *Name1 = Enum1->getIdentifier();
-        if (!Name1 && Enum1->getTypedefNameForAnonDecl())
-          Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
-        IdentifierInfo *Name2 = Enum2->getIdentifier();
-        if (!Name2 && Enum2->getTypedefNameForAnonDecl())
-          Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
-        if (!::IsStructurallyEquivalent(Name1, Name2) ||
-            !::IsStructurallyEquivalent(*this, Enum1, Enum2))
-          Equivalent = false;
-      } else {
-        // Enum/non-enum mismatch
-        Equivalent = false;
-      }
-    } else if (TypedefNameDecl *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
-      if (TypedefNameDecl *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
-        if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
-                                        Typedef2->getIdentifier()) ||
-            !::IsStructurallyEquivalent(*this,
-                                        Typedef1->getUnderlyingType(),
-                                        Typedef2->getUnderlyingType()))
-          Equivalent = false;
-      } else {
-        // Typedef/non-typedef mismatch.
-        Equivalent = false;
-      }
-    } else if (ClassTemplateDecl *ClassTemplate1 
-                                           = dyn_cast<ClassTemplateDecl>(D1)) {
-      if (ClassTemplateDecl *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
-        if (!::IsStructurallyEquivalent(ClassTemplate1->getIdentifier(),
-                                        ClassTemplate2->getIdentifier()) ||
-            !::IsStructurallyEquivalent(*this, ClassTemplate1, ClassTemplate2))
-          Equivalent = false;
-      } else {
-        // Class template/non-class-template mismatch.
-        Equivalent = false;
-      }
-    } else if (TemplateTypeParmDecl *TTP1= dyn_cast<TemplateTypeParmDecl>(D1)) {
-      if (TemplateTypeParmDecl *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
-        if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
-          Equivalent = false;
-      } else {
-        // Kind mismatch.
-        Equivalent = false;
-      }
-    } else if (NonTypeTemplateParmDecl *NTTP1
-                                     = dyn_cast<NonTypeTemplateParmDecl>(D1)) {
-      if (NonTypeTemplateParmDecl *NTTP2
-                                      = dyn_cast<NonTypeTemplateParmDecl>(D2)) {
-        if (!::IsStructurallyEquivalent(*this, NTTP1, NTTP2))
-          Equivalent = false;
-      } else {
-        // Kind mismatch.
-        Equivalent = false;
-      }
-    } else if (TemplateTemplateParmDecl *TTP1
-                                  = dyn_cast<TemplateTemplateParmDecl>(D1)) {
-      if (TemplateTemplateParmDecl *TTP2
-                                    = dyn_cast<TemplateTemplateParmDecl>(D2)) {
-        if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
-          Equivalent = false;
-      } else {
-        // Kind mismatch.
-        Equivalent = false;
-      }
-    }
-    
-    if (!Equivalent) {
-      // Note that these two declarations are not equivalent (and we already
-      // know about it).
-      NonEquivalentDecls.insert(std::make_pair(D1->getCanonicalDecl(),
-                                               D2->getCanonicalDecl()));
-      return true;
-    }
-    // FIXME: Check other declaration kinds!
-  }
-  
-  return false;
-}
-
 //----------------------------------------------------------------------------
 // Import Types
 //----------------------------------------------------------------------------
 
+using namespace clang;
+
 QualType ASTNodeImporter::VisitType(const Type *T) {
   Importer.FromDiag(SourceLocation(), diag::err_unsupported_ast_node)
     << T->getTypeClassName();
@@ -2500,7 +1229,7 @@
   StructuralEquivalenceContext Ctx(Importer.getFromContext(),
                                    Importer.getToContext(),
                                    Importer.getNonEquivalentDecls());
-  return Ctx.IsStructurallyEquivalent(From, To);  
+  return Ctx.IsStructurallyEquivalent(From, To);
 }
 
 bool ASTNodeImporter::IsStructuralMatch(VarTemplateDecl *From,
@@ -2679,10 +1408,10 @@
                                             FoundTypedef->getUnderlyingType()))
           return Importer.Imported(D, FoundTypedef);
       }
-      
+
       ConflictingDecls.push_back(FoundDecls[I]);
     }
-    
+
     if (!ConflictingDecls.empty()) {
       Name = Importer.HandleNameConflict(Name, DC, IDNS,
                                          ConflictingDecls.data(), 
@@ -2691,7 +1420,7 @@
         return nullptr;
     }
   }
-  
+
   // Import the underlying type of this typedef;
   QualType T = Importer.Import(D->getUnderlyingType());
   if (T.isNull())
@@ -2711,12 +1440,12 @@
                                     StartL, Loc,
                                     Name.getAsIdentifierInfo(),
                                     TInfo);
-  
+
   ToTypedef->setAccess(D->getAccess());
   ToTypedef->setLexicalDeclContext(LexicalDC);
   Importer.Imported(D, ToTypedef);
   LexicalDC->addDeclInternal(ToTypedef);
-  
+
   return ToTypedef;
 }
 
@@ -2890,9 +1619,10 @@
             FoundRecord->isAnonymousStructOrUnion()) {
           // If both anonymous structs/unions are in a record context, make sure
           // they occur in the same location in the context records.
-          if (Optional<unsigned> Index1
-              = findUntaggedStructOrUnionIndex(D)) {
-            if (Optional<unsigned> Index2 =
+          if (Optional<unsigned> Index1 =
+                  StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
+                      D)) {
+            if (Optional<unsigned> Index2 = StructuralEquivalenceContext::
                     findUntaggedStructOrUnionIndex(FoundRecord)) {
               if (*Index1 != *Index2)
                 continue;
@@ -3082,7 +1812,7 @@
     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
       if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
         continue;
-    
+
       if (FunctionDecl *FoundFunction = dyn_cast<FunctionDecl>(FoundDecls[I])) {
         if (FoundFunction->hasExternalFormalLinkage() &&
             D->hasExternalFormalLinkage()) {
@@ -3091,14 +1821,14 @@
             // FIXME: Actually try to merge the body and other attributes.
             return Importer.Imported(D, FoundFunction);
           }
-        
+
           // FIXME: Check for overloading more carefully, e.g., by boosting
           // Sema::IsOverload out to the AST library.
-          
+
           // Function overloading is okay in C++.
           if (Importer.getToContext().getLangOpts().CPlusPlus)
             continue;
-          
+
           // Complain about inconsistent function types.
           Importer.ToDiag(Loc, diag::err_odr_function_type_inconsistent)
             << Name << D->getType() << FoundFunction->getType();
@@ -3107,10 +1837,10 @@
             << FoundFunction->getType();
         }
       }
-      
+
       ConflictingDecls.push_back(FoundDecls[I]);
     }
-    
+
     if (!ConflictingDecls.empty()) {
       Name = Importer.HandleNameConflict(Name, DC, IDNS,
                                          ConflictingDecls.data(), 
@@ -3315,12 +2045,12 @@
       if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
         continue;
 
-      if (Importer.IsStructurallyEquivalent(D->getType(), 
+      if (Importer.IsStructurallyEquivalent(D->getType(),
                                             FoundField->getType())) {
         Importer.Imported(D, FoundField);
         return FoundField;
       }
-      
+
       Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
         << Name << D->getType() << FoundField->getType();
       Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
@@ -3380,7 +2110,7 @@
       if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
         continue;
 
-      if (Importer.IsStructurallyEquivalent(D->getType(), 
+      if (Importer.IsStructurallyEquivalent(D->getType(),
                                             FoundField->getType(),
                                             !Name.isEmpty())) {
         Importer.Imported(D, FoundField);
@@ -3504,12 +2234,12 @@
   if (ToD)
     return ToD;
 
-  // Determine whether we've already imported this ivar 
+  // Determine whether we've already imported this ivar
   SmallVector<NamedDecl *, 2> FoundDecls;
   DC->getRedeclContext()->localUncachedLookup(Name, FoundDecls);
   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
     if (ObjCIvarDecl *FoundIvar = dyn_cast<ObjCIvarDecl>(FoundDecls[I])) {
-      if (Importer.IsStructurallyEquivalent(D->getType(), 
+      if (Importer.IsStructurallyEquivalent(D->getType(),
                                             FoundIvar->getType())) {
         Importer.Imported(D, FoundIvar);
         return FoundIvar;
@@ -3568,12 +2298,12 @@
     for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
       if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
         continue;
-      
+
       if (VarDecl *FoundVar = dyn_cast<VarDecl>(FoundDecls[I])) {
         // We have found a variable that we may need to merge with. Check it.
         if (FoundVar->hasExternalFormalLinkage() &&
             D->hasExternalFormalLinkage()) {
-          if (Importer.IsStructurallyEquivalent(D->getType(), 
+          if (Importer.IsStructurallyEquivalent(D->getType(),
                                                 FoundVar->getType())) {
             MergeWithVar = FoundVar;
             break;
@@ -3775,12 +2505,12 @@
       }
 
       // Check parameter types.
-      for (ObjCMethodDecl::param_iterator P = D->param_begin(), 
+      for (ObjCMethodDecl::param_iterator P = D->param_begin(),
              PEnd = D->param_end(), FoundP = FoundMethod->param_begin();
            P != PEnd; ++P, ++FoundP) {
-        if (!Importer.IsStructurallyEquivalent((*P)->getType(), 
+        if (!Importer.IsStructurallyEquivalent((*P)->getType(),
                                                (*FoundP)->getType())) {
-          Importer.FromDiag((*P)->getLocation(), 
+          Importer.FromDiag((*P)->getLocation(),
                             diag::err_odr_objc_method_param_type_inconsistent)
             << D->isInstanceMethod() << Name
             << (*P)->getType() << (*FoundP)->getType();
@@ -4386,7 +3116,7 @@
     if (ObjCPropertyDecl *FoundProp
                                 = dyn_cast<ObjCPropertyDecl>(FoundDecls[I])) {
       // Check property types.
-      if (!Importer.IsStructurallyEquivalent(D->getType(), 
+      if (!Importer.IsStructurallyEquivalent(D->getType(),
                                              FoundProp->getType())) {
         Importer.ToDiag(Loc, diag::err_odr_objc_property_type_inconsistent)
           << Name << D->getType() << FoundProp->getType();
@@ -4424,8 +3154,10 @@
   ToProperty->setPropertyAttributes(D->getPropertyAttributes());
   ToProperty->setPropertyAttributesAsWritten(
                                       D->getPropertyAttributesAsWritten());
-  ToProperty->setGetterName(Importer.Import(D->getGetterName()));
-  ToProperty->setSetterName(Importer.Import(D->getSetterName()));
+  ToProperty->setGetterName(Importer.Import(D->getGetterName()),
+                            Importer.Import(D->getGetterNameLoc()));
+  ToProperty->setSetterName(Importer.Import(D->getSetterName()),
+                            Importer.Import(D->getSetterNameLoc()));
   ToProperty->setGetterMethodDecl(
      cast_or_null<ObjCMethodDecl>(Importer.Import(D->getGetterMethodDecl())));
   ToProperty->setSetterMethodDecl(
@@ -5860,7 +4592,7 @@
                                                       T, E->getValueKind(),
                                                       E->getObjectKind(),
                                            Importer.Import(E->getOperatorLoc()),
-                                                      E->isFPContractable());
+                                                      E->getFPFeatures());
 }
 
 Expr *ASTNodeImporter::VisitConditionalOperator(ConditionalOperator *E) {
@@ -6010,7 +4742,7 @@
                                                E->getObjectKind(),
                                                CompLHSType, CompResultType,
                                            Importer.Import(E->getOperatorLoc()),
-                                               E->isFPContractable());
+                                               E->getFPFeatures());
 }
 
 bool ASTNodeImporter::ImportCastPath(CastExpr *CE, CXXCastPath &Path) {
@@ -7288,7 +6020,7 @@
    = ImportedTypes.find(From.getTypePtr());
   if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
     return true;
-      
+
   StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls,
                                    false, Complain);
   return Ctx.IsStructurallyEquivalent(From, To);
diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp
new file mode 100644
index 0000000..5f7d255
--- /dev/null
+++ b/lib/AST/ASTStructuralEquivalence.cpp
@@ -0,0 +1,1208 @@
+//===--- ASTStructuralEquivalence.cpp - -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implement StructuralEquivalenceContext class and helper functions
+//  for layout matching.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTStructuralEquivalence.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTDiagnostic.h"
+#include "clang/AST/ASTImporter.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclVisitor.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/AST/TypeVisitor.h"
+#include "clang/Basic/SourceManager.h"
+
+namespace {
+
+using namespace clang;
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     QualType T1, QualType T2);
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     Decl *D1, Decl *D2);
+
+/// Determine structural equivalence of two expressions.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     Expr *E1, Expr *E2) {
+  if (!E1 || !E2)
+    return E1 == E2;
+
+  // FIXME: Actually perform a structural comparison!
+  return true;
+}
+
+/// Determine whether two identifiers are equivalent.
+static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
+                                     const IdentifierInfo *Name2) {
+  if (!Name1 || !Name2)
+    return Name1 == Name2;
+
+  return Name1->getName() == Name2->getName();
+}
+
+/// Determine whether two nested-name-specifiers are equivalent.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     NestedNameSpecifier *NNS1,
+                                     NestedNameSpecifier *NNS2) {
+  // FIXME: Implement!
+  return true;
+}
+
+/// Determine whether two template arguments are equivalent.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     const TemplateArgument &Arg1,
+                                     const TemplateArgument &Arg2) {
+  if (Arg1.getKind() != Arg2.getKind())
+    return false;
+
+  switch (Arg1.getKind()) {
+  case TemplateArgument::Null:
+    return true;
+
+  case TemplateArgument::Type:
+    return Context.IsStructurallyEquivalent(Arg1.getAsType(), Arg2.getAsType());
+
+  case TemplateArgument::Integral:
+    if (!Context.IsStructurallyEquivalent(Arg1.getIntegralType(),
+                                          Arg2.getIntegralType()))
+      return false;
+
+    return llvm::APSInt::isSameValue(Arg1.getAsIntegral(),
+                                     Arg2.getAsIntegral());
+
+  case TemplateArgument::Declaration:
+    return Context.IsStructurallyEquivalent(Arg1.getAsDecl(), Arg2.getAsDecl());
+
+  case TemplateArgument::NullPtr:
+    return true; // FIXME: Is this correct?
+
+  case TemplateArgument::Template:
+    return IsStructurallyEquivalent(Context, Arg1.getAsTemplate(),
+                                    Arg2.getAsTemplate());
+
+  case TemplateArgument::TemplateExpansion:
+    return IsStructurallyEquivalent(Context,
+                                    Arg1.getAsTemplateOrTemplatePattern(),
+                                    Arg2.getAsTemplateOrTemplatePattern());
+
+  case TemplateArgument::Expression:
+    return IsStructurallyEquivalent(Context, Arg1.getAsExpr(),
+                                    Arg2.getAsExpr());
+
+  case TemplateArgument::Pack:
+    if (Arg1.pack_size() != Arg2.pack_size())
+      return false;
+
+    for (unsigned I = 0, N = Arg1.pack_size(); I != N; ++I)
+      if (!IsStructurallyEquivalent(Context, Arg1.pack_begin()[I],
+                                    Arg2.pack_begin()[I]))
+        return false;
+
+    return true;
+  }
+
+  llvm_unreachable("Invalid template argument kind");
+}
+
+/// Determine structural equivalence for the common part of array
+/// types.
+static bool IsArrayStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                          const ArrayType *Array1,
+                                          const ArrayType *Array2) {
+  if (!IsStructurallyEquivalent(Context, Array1->getElementType(),
+                                Array2->getElementType()))
+    return false;
+  if (Array1->getSizeModifier() != Array2->getSizeModifier())
+    return false;
+  if (Array1->getIndexTypeQualifiers() != Array2->getIndexTypeQualifiers())
+    return false;
+
+  return true;
+}
+
+/// Determine structural equivalence of two types.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     QualType T1, QualType T2) {
+  if (T1.isNull() || T2.isNull())
+    return T1.isNull() && T2.isNull();
+
+  if (!Context.StrictTypeSpelling) {
+    // We aren't being strict about token-to-token equivalence of types,
+    // so map down to the canonical type.
+    T1 = Context.FromCtx.getCanonicalType(T1);
+    T2 = Context.ToCtx.getCanonicalType(T2);
+  }
+
+  if (T1.getQualifiers() != T2.getQualifiers())
+    return false;
+
+  Type::TypeClass TC = T1->getTypeClass();
+
+  if (T1->getTypeClass() != T2->getTypeClass()) {
+    // Compare function types with prototypes vs. without prototypes as if
+    // both did not have prototypes.
+    if (T1->getTypeClass() == Type::FunctionProto &&
+        T2->getTypeClass() == Type::FunctionNoProto)
+      TC = Type::FunctionNoProto;
+    else if (T1->getTypeClass() == Type::FunctionNoProto &&
+             T2->getTypeClass() == Type::FunctionProto)
+      TC = Type::FunctionNoProto;
+    else
+      return false;
+  }
+
+  switch (TC) {
+  case Type::Builtin:
+    // FIXME: Deal with Char_S/Char_U.
+    if (cast<BuiltinType>(T1)->getKind() != cast<BuiltinType>(T2)->getKind())
+      return false;
+    break;
+
+  case Type::Complex:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<ComplexType>(T1)->getElementType(),
+                                  cast<ComplexType>(T2)->getElementType()))
+      return false;
+    break;
+
+  case Type::Adjusted:
+  case Type::Decayed:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<AdjustedType>(T1)->getOriginalType(),
+                                  cast<AdjustedType>(T2)->getOriginalType()))
+      return false;
+    break;
+
+  case Type::Pointer:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<PointerType>(T1)->getPointeeType(),
+                                  cast<PointerType>(T2)->getPointeeType()))
+      return false;
+    break;
+
+  case Type::BlockPointer:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<BlockPointerType>(T1)->getPointeeType(),
+                                  cast<BlockPointerType>(T2)->getPointeeType()))
+      return false;
+    break;
+
+  case Type::LValueReference:
+  case Type::RValueReference: {
+    const ReferenceType *Ref1 = cast<ReferenceType>(T1);
+    const ReferenceType *Ref2 = cast<ReferenceType>(T2);
+    if (Ref1->isSpelledAsLValue() != Ref2->isSpelledAsLValue())
+      return false;
+    if (Ref1->isInnerRef() != Ref2->isInnerRef())
+      return false;
+    if (!IsStructurallyEquivalent(Context, Ref1->getPointeeTypeAsWritten(),
+                                  Ref2->getPointeeTypeAsWritten()))
+      return false;
+    break;
+  }
+
+  case Type::MemberPointer: {
+    const MemberPointerType *MemPtr1 = cast<MemberPointerType>(T1);
+    const MemberPointerType *MemPtr2 = cast<MemberPointerType>(T2);
+    if (!IsStructurallyEquivalent(Context, MemPtr1->getPointeeType(),
+                                  MemPtr2->getPointeeType()))
+      return false;
+    if (!IsStructurallyEquivalent(Context, QualType(MemPtr1->getClass(), 0),
+                                  QualType(MemPtr2->getClass(), 0)))
+      return false;
+    break;
+  }
+
+  case Type::ConstantArray: {
+    const ConstantArrayType *Array1 = cast<ConstantArrayType>(T1);
+    const ConstantArrayType *Array2 = cast<ConstantArrayType>(T2);
+    if (!llvm::APInt::isSameValue(Array1->getSize(), Array2->getSize()))
+      return false;
+
+    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
+      return false;
+    break;
+  }
+
+  case Type::IncompleteArray:
+    if (!IsArrayStructurallyEquivalent(Context, cast<ArrayType>(T1),
+                                       cast<ArrayType>(T2)))
+      return false;
+    break;
+
+  case Type::VariableArray: {
+    const VariableArrayType *Array1 = cast<VariableArrayType>(T1);
+    const VariableArrayType *Array2 = cast<VariableArrayType>(T2);
+    if (!IsStructurallyEquivalent(Context, Array1->getSizeExpr(),
+                                  Array2->getSizeExpr()))
+      return false;
+
+    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
+      return false;
+
+    break;
+  }
+
+  case Type::DependentSizedArray: {
+    const DependentSizedArrayType *Array1 = cast<DependentSizedArrayType>(T1);
+    const DependentSizedArrayType *Array2 = cast<DependentSizedArrayType>(T2);
+    if (!IsStructurallyEquivalent(Context, Array1->getSizeExpr(),
+                                  Array2->getSizeExpr()))
+      return false;
+
+    if (!IsArrayStructurallyEquivalent(Context, Array1, Array2))
+      return false;
+
+    break;
+  }
+
+  case Type::DependentSizedExtVector: {
+    const DependentSizedExtVectorType *Vec1 =
+        cast<DependentSizedExtVectorType>(T1);
+    const DependentSizedExtVectorType *Vec2 =
+        cast<DependentSizedExtVectorType>(T2);
+    if (!IsStructurallyEquivalent(Context, Vec1->getSizeExpr(),
+                                  Vec2->getSizeExpr()))
+      return false;
+    if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
+                                  Vec2->getElementType()))
+      return false;
+    break;
+  }
+
+  case Type::Vector:
+  case Type::ExtVector: {
+    const VectorType *Vec1 = cast<VectorType>(T1);
+    const VectorType *Vec2 = cast<VectorType>(T2);
+    if (!IsStructurallyEquivalent(Context, Vec1->getElementType(),
+                                  Vec2->getElementType()))
+      return false;
+    if (Vec1->getNumElements() != Vec2->getNumElements())
+      return false;
+    if (Vec1->getVectorKind() != Vec2->getVectorKind())
+      return false;
+    break;
+  }
+
+  case Type::FunctionProto: {
+    const FunctionProtoType *Proto1 = cast<FunctionProtoType>(T1);
+    const FunctionProtoType *Proto2 = cast<FunctionProtoType>(T2);
+    if (Proto1->getNumParams() != Proto2->getNumParams())
+      return false;
+    for (unsigned I = 0, N = Proto1->getNumParams(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context, Proto1->getParamType(I),
+                                    Proto2->getParamType(I)))
+        return false;
+    }
+    if (Proto1->isVariadic() != Proto2->isVariadic())
+      return false;
+    if (Proto1->getExceptionSpecType() != Proto2->getExceptionSpecType())
+      return false;
+    if (Proto1->getExceptionSpecType() == EST_Dynamic) {
+      if (Proto1->getNumExceptions() != Proto2->getNumExceptions())
+        return false;
+      for (unsigned I = 0, N = Proto1->getNumExceptions(); I != N; ++I) {
+        if (!IsStructurallyEquivalent(Context, Proto1->getExceptionType(I),
+                                      Proto2->getExceptionType(I)))
+          return false;
+      }
+    } else if (Proto1->getExceptionSpecType() == EST_ComputedNoexcept) {
+      if (!IsStructurallyEquivalent(Context, Proto1->getNoexceptExpr(),
+                                    Proto2->getNoexceptExpr()))
+        return false;
+    }
+    if (Proto1->getTypeQuals() != Proto2->getTypeQuals())
+      return false;
+
+    // Fall through to check the bits common with FunctionNoProtoType.
+  }
+
+  case Type::FunctionNoProto: {
+    const FunctionType *Function1 = cast<FunctionType>(T1);
+    const FunctionType *Function2 = cast<FunctionType>(T2);
+    if (!IsStructurallyEquivalent(Context, Function1->getReturnType(),
+                                  Function2->getReturnType()))
+      return false;
+    if (Function1->getExtInfo() != Function2->getExtInfo())
+      return false;
+    break;
+  }
+
+  case Type::UnresolvedUsing:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<UnresolvedUsingType>(T1)->getDecl(),
+                                  cast<UnresolvedUsingType>(T2)->getDecl()))
+      return false;
+
+    break;
+
+  case Type::Attributed:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<AttributedType>(T1)->getModifiedType(),
+                                  cast<AttributedType>(T2)->getModifiedType()))
+      return false;
+    if (!IsStructurallyEquivalent(
+            Context, cast<AttributedType>(T1)->getEquivalentType(),
+            cast<AttributedType>(T2)->getEquivalentType()))
+      return false;
+    break;
+
+  case Type::Paren:
+    if (!IsStructurallyEquivalent(Context, cast<ParenType>(T1)->getInnerType(),
+                                  cast<ParenType>(T2)->getInnerType()))
+      return false;
+    break;
+
+  case Type::Typedef:
+    if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
+                                  cast<TypedefType>(T2)->getDecl()))
+      return false;
+    break;
+
+  case Type::TypeOfExpr:
+    if (!IsStructurallyEquivalent(
+            Context, cast<TypeOfExprType>(T1)->getUnderlyingExpr(),
+            cast<TypeOfExprType>(T2)->getUnderlyingExpr()))
+      return false;
+    break;
+
+  case Type::TypeOf:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<TypeOfType>(T1)->getUnderlyingType(),
+                                  cast<TypeOfType>(T2)->getUnderlyingType()))
+      return false;
+    break;
+
+  case Type::UnaryTransform:
+    if (!IsStructurallyEquivalent(
+            Context, cast<UnaryTransformType>(T1)->getUnderlyingType(),
+            cast<UnaryTransformType>(T1)->getUnderlyingType()))
+      return false;
+    break;
+
+  case Type::Decltype:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<DecltypeType>(T1)->getUnderlyingExpr(),
+                                  cast<DecltypeType>(T2)->getUnderlyingExpr()))
+      return false;
+    break;
+
+  case Type::Auto:
+    if (!IsStructurallyEquivalent(Context, cast<AutoType>(T1)->getDeducedType(),
+                                  cast<AutoType>(T2)->getDeducedType()))
+      return false;
+    break;
+
+  case Type::Record:
+  case Type::Enum:
+    if (!IsStructurallyEquivalent(Context, cast<TagType>(T1)->getDecl(),
+                                  cast<TagType>(T2)->getDecl()))
+      return false;
+    break;
+
+  case Type::TemplateTypeParm: {
+    const TemplateTypeParmType *Parm1 = cast<TemplateTypeParmType>(T1);
+    const TemplateTypeParmType *Parm2 = cast<TemplateTypeParmType>(T2);
+    if (Parm1->getDepth() != Parm2->getDepth())
+      return false;
+    if (Parm1->getIndex() != Parm2->getIndex())
+      return false;
+    if (Parm1->isParameterPack() != Parm2->isParameterPack())
+      return false;
+
+    // Names of template type parameters are never significant.
+    break;
+  }
+
+  case Type::SubstTemplateTypeParm: {
+    const SubstTemplateTypeParmType *Subst1 =
+        cast<SubstTemplateTypeParmType>(T1);
+    const SubstTemplateTypeParmType *Subst2 =
+        cast<SubstTemplateTypeParmType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  QualType(Subst1->getReplacedParameter(), 0),
+                                  QualType(Subst2->getReplacedParameter(), 0)))
+      return false;
+    if (!IsStructurallyEquivalent(Context, Subst1->getReplacementType(),
+                                  Subst2->getReplacementType()))
+      return false;
+    break;
+  }
+
+  case Type::SubstTemplateTypeParmPack: {
+    const SubstTemplateTypeParmPackType *Subst1 =
+        cast<SubstTemplateTypeParmPackType>(T1);
+    const SubstTemplateTypeParmPackType *Subst2 =
+        cast<SubstTemplateTypeParmPackType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  QualType(Subst1->getReplacedParameter(), 0),
+                                  QualType(Subst2->getReplacedParameter(), 0)))
+      return false;
+    if (!IsStructurallyEquivalent(Context, Subst1->getArgumentPack(),
+                                  Subst2->getArgumentPack()))
+      return false;
+    break;
+  }
+  case Type::TemplateSpecialization: {
+    const TemplateSpecializationType *Spec1 =
+        cast<TemplateSpecializationType>(T1);
+    const TemplateSpecializationType *Spec2 =
+        cast<TemplateSpecializationType>(T2);
+    if (!IsStructurallyEquivalent(Context, Spec1->getTemplateName(),
+                                  Spec2->getTemplateName()))
+      return false;
+    if (Spec1->getNumArgs() != Spec2->getNumArgs())
+      return false;
+    for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context, Spec1->getArg(I),
+                                    Spec2->getArg(I)))
+        return false;
+    }
+    break;
+  }
+
+  case Type::Elaborated: {
+    const ElaboratedType *Elab1 = cast<ElaboratedType>(T1);
+    const ElaboratedType *Elab2 = cast<ElaboratedType>(T2);
+    // CHECKME: what if a keyword is ETK_None or ETK_typename ?
+    if (Elab1->getKeyword() != Elab2->getKeyword())
+      return false;
+    if (!IsStructurallyEquivalent(Context, Elab1->getQualifier(),
+                                  Elab2->getQualifier()))
+      return false;
+    if (!IsStructurallyEquivalent(Context, Elab1->getNamedType(),
+                                  Elab2->getNamedType()))
+      return false;
+    break;
+  }
+
+  case Type::InjectedClassName: {
+    const InjectedClassNameType *Inj1 = cast<InjectedClassNameType>(T1);
+    const InjectedClassNameType *Inj2 = cast<InjectedClassNameType>(T2);
+    if (!IsStructurallyEquivalent(Context,
+                                  Inj1->getInjectedSpecializationType(),
+                                  Inj2->getInjectedSpecializationType()))
+      return false;
+    break;
+  }
+
+  case Type::DependentName: {
+    const DependentNameType *Typename1 = cast<DependentNameType>(T1);
+    const DependentNameType *Typename2 = cast<DependentNameType>(T2);
+    if (!IsStructurallyEquivalent(Context, Typename1->getQualifier(),
+                                  Typename2->getQualifier()))
+      return false;
+    if (!IsStructurallyEquivalent(Typename1->getIdentifier(),
+                                  Typename2->getIdentifier()))
+      return false;
+
+    break;
+  }
+
+  case Type::DependentTemplateSpecialization: {
+    const DependentTemplateSpecializationType *Spec1 =
+        cast<DependentTemplateSpecializationType>(T1);
+    const DependentTemplateSpecializationType *Spec2 =
+        cast<DependentTemplateSpecializationType>(T2);
+    if (!IsStructurallyEquivalent(Context, Spec1->getQualifier(),
+                                  Spec2->getQualifier()))
+      return false;
+    if (!IsStructurallyEquivalent(Spec1->getIdentifier(),
+                                  Spec2->getIdentifier()))
+      return false;
+    if (Spec1->getNumArgs() != Spec2->getNumArgs())
+      return false;
+    for (unsigned I = 0, N = Spec1->getNumArgs(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context, Spec1->getArg(I),
+                                    Spec2->getArg(I)))
+        return false;
+    }
+    break;
+  }
+
+  case Type::PackExpansion:
+    if (!IsStructurallyEquivalent(Context,
+                                  cast<PackExpansionType>(T1)->getPattern(),
+                                  cast<PackExpansionType>(T2)->getPattern()))
+      return false;
+    break;
+
+  case Type::ObjCInterface: {
+    const ObjCInterfaceType *Iface1 = cast<ObjCInterfaceType>(T1);
+    const ObjCInterfaceType *Iface2 = cast<ObjCInterfaceType>(T2);
+    if (!IsStructurallyEquivalent(Context, Iface1->getDecl(),
+                                  Iface2->getDecl()))
+      return false;
+    break;
+  }
+
+  case Type::ObjCTypeParam: {
+    const ObjCTypeParamType *Obj1 = cast<ObjCTypeParamType>(T1);
+    const ObjCTypeParamType *Obj2 = cast<ObjCTypeParamType>(T2);
+    if (!IsStructurallyEquivalent(Context, Obj1->getDecl(), Obj2->getDecl()))
+      return false;
+
+    if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
+      return false;
+    for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context, Obj1->getProtocol(I),
+                                    Obj2->getProtocol(I)))
+        return false;
+    }
+    break;
+  }
+  case Type::ObjCObject: {
+    const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
+    const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
+    if (!IsStructurallyEquivalent(Context, Obj1->getBaseType(),
+                                  Obj2->getBaseType()))
+      return false;
+    if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
+      return false;
+    for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
+      if (!IsStructurallyEquivalent(Context, Obj1->getProtocol(I),
+                                    Obj2->getProtocol(I)))
+        return false;
+    }
+    break;
+  }
+
+  case Type::ObjCObjectPointer: {
+    const ObjCObjectPointerType *Ptr1 = cast<ObjCObjectPointerType>(T1);
+    const ObjCObjectPointerType *Ptr2 = cast<ObjCObjectPointerType>(T2);
+    if (!IsStructurallyEquivalent(Context, Ptr1->getPointeeType(),
+                                  Ptr2->getPointeeType()))
+      return false;
+    break;
+  }
+
+  case Type::Atomic: {
+    if (!IsStructurallyEquivalent(Context, cast<AtomicType>(T1)->getValueType(),
+                                  cast<AtomicType>(T2)->getValueType()))
+      return false;
+    break;
+  }
+
+  case Type::Pipe: {
+    if (!IsStructurallyEquivalent(Context, cast<PipeType>(T1)->getElementType(),
+                                  cast<PipeType>(T2)->getElementType()))
+      return false;
+    break;
+  }
+
+  } // end switch
+
+  return true;
+}
+
+/// Determine structural equivalence of two fields.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     FieldDecl *Field1, FieldDecl *Field2) {
+  RecordDecl *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
+
+  // For anonymous structs/unions, match up the anonymous struct/union type
+  // declarations directly, so that we don't go off searching for anonymous
+  // types
+  if (Field1->isAnonymousStructOrUnion() &&
+      Field2->isAnonymousStructOrUnion()) {
+    RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl();
+    RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl();
+    return IsStructurallyEquivalent(Context, D1, D2);
+  }
+
+  // Check for equivalent field names.
+  IdentifierInfo *Name1 = Field1->getIdentifier();
+  IdentifierInfo *Name2 = Field2->getIdentifier();
+  if (!::IsStructurallyEquivalent(Name1, Name2))
+    return false;
+
+  if (!IsStructurallyEquivalent(Context, Field1->getType(),
+                                Field2->getType())) {
+    if (Context.Complain) {
+      Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+          << Context.ToCtx.getTypeDeclType(Owner2);
+      Context.Diag2(Field2->getLocation(), diag::note_odr_field)
+          << Field2->getDeclName() << Field2->getType();
+      Context.Diag1(Field1->getLocation(), diag::note_odr_field)
+          << Field1->getDeclName() << Field1->getType();
+    }
+    return false;
+  }
+
+  if (Field1->isBitField() != Field2->isBitField()) {
+    if (Context.Complain) {
+      Context.Diag2(Owner2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+          << Context.ToCtx.getTypeDeclType(Owner2);
+      if (Field1->isBitField()) {
+        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
+            << Field1->getDeclName() << Field1->getType()
+            << Field1->getBitWidthValue(Context.FromCtx);
+        Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
+            << Field2->getDeclName();
+      } else {
+        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
+            << Field2->getDeclName() << Field2->getType()
+            << Field2->getBitWidthValue(Context.ToCtx);
+        Context.Diag1(Field1->getLocation(), diag::note_odr_not_bit_field)
+            << Field1->getDeclName();
+      }
+    }
+    return false;
+  }
+
+  if (Field1->isBitField()) {
+    // Make sure that the bit-fields are the same length.
+    unsigned Bits1 = Field1->getBitWidthValue(Context.FromCtx);
+    unsigned Bits2 = Field2->getBitWidthValue(Context.ToCtx);
+
+    if (Bits1 != Bits2) {
+      if (Context.Complain) {
+        Context.Diag2(Owner2->getLocation(),
+                      diag::warn_odr_tag_type_inconsistent)
+            << Context.ToCtx.getTypeDeclType(Owner2);
+        Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
+            << Field2->getDeclName() << Field2->getType() << Bits2;
+        Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
+            << Field1->getDeclName() << Field1->getType() << Bits1;
+      }
+      return false;
+    }
+  }
+
+  return true;
+}
+
+/// Determine structural equivalence of two records.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     RecordDecl *D1, RecordDecl *D2) {
+  if (D1->isUnion() != D2->isUnion()) {
+    if (Context.Complain) {
+      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+          << Context.ToCtx.getTypeDeclType(D2);
+      Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
+          << D1->getDeclName() << (unsigned)D1->getTagKind();
+    }
+    return false;
+  }
+
+  if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) {
+    // If both anonymous structs/unions are in a record context, make sure
+    // they occur in the same location in the context records.
+    if (Optional<unsigned> Index1 =
+            StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(D1)) {
+      if (Optional<unsigned> Index2 =
+              StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(
+                  D2)) {
+        if (*Index1 != *Index2)
+          return false;
+      }
+    }
+  }
+
+  // If both declarations are class template specializations, we know
+  // the ODR applies, so check the template and template arguments.
+  ClassTemplateSpecializationDecl *Spec1 =
+      dyn_cast<ClassTemplateSpecializationDecl>(D1);
+  ClassTemplateSpecializationDecl *Spec2 =
+      dyn_cast<ClassTemplateSpecializationDecl>(D2);
+  if (Spec1 && Spec2) {
+    // Check that the specialized templates are the same.
+    if (!IsStructurallyEquivalent(Context, Spec1->getSpecializedTemplate(),
+                                  Spec2->getSpecializedTemplate()))
+      return false;
+
+    // Check that the template arguments are the same.
+    if (Spec1->getTemplateArgs().size() != Spec2->getTemplateArgs().size())
+      return false;
+
+    for (unsigned I = 0, N = Spec1->getTemplateArgs().size(); I != N; ++I)
+      if (!IsStructurallyEquivalent(Context, Spec1->getTemplateArgs().get(I),
+                                    Spec2->getTemplateArgs().get(I)))
+        return false;
+  }
+  // If one is a class template specialization and the other is not, these
+  // structures are different.
+  else if (Spec1 || Spec2)
+    return false;
+
+  // Compare the definitions of these two records. If either or both are
+  // incomplete, we assume that they are equivalent.
+  D1 = D1->getDefinition();
+  D2 = D2->getDefinition();
+  if (!D1 || !D2)
+    return true;
+
+  if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
+    if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
+      if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
+        if (Context.Complain) {
+          Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+              << Context.ToCtx.getTypeDeclType(D2);
+          Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
+              << D2CXX->getNumBases();
+          Context.Diag1(D1->getLocation(), diag::note_odr_number_of_bases)
+              << D1CXX->getNumBases();
+        }
+        return false;
+      }
+
+      // Check the base classes.
+      for (CXXRecordDecl::base_class_iterator Base1 = D1CXX->bases_begin(),
+                                              BaseEnd1 = D1CXX->bases_end(),
+                                              Base2 = D2CXX->bases_begin();
+           Base1 != BaseEnd1; ++Base1, ++Base2) {
+        if (!IsStructurallyEquivalent(Context, Base1->getType(),
+                                      Base2->getType())) {
+          if (Context.Complain) {
+            Context.Diag2(D2->getLocation(),
+                          diag::warn_odr_tag_type_inconsistent)
+                << Context.ToCtx.getTypeDeclType(D2);
+            Context.Diag2(Base2->getLocStart(), diag::note_odr_base)
+                << Base2->getType() << Base2->getSourceRange();
+            Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
+                << Base1->getType() << Base1->getSourceRange();
+          }
+          return false;
+        }
+
+        // Check virtual vs. non-virtual inheritance mismatch.
+        if (Base1->isVirtual() != Base2->isVirtual()) {
+          if (Context.Complain) {
+            Context.Diag2(D2->getLocation(),
+                          diag::warn_odr_tag_type_inconsistent)
+                << Context.ToCtx.getTypeDeclType(D2);
+            Context.Diag2(Base2->getLocStart(), diag::note_odr_virtual_base)
+                << Base2->isVirtual() << Base2->getSourceRange();
+            Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
+                << Base1->isVirtual() << Base1->getSourceRange();
+          }
+          return false;
+        }
+      }
+    } else if (D1CXX->getNumBases() > 0) {
+      if (Context.Complain) {
+        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+            << Context.ToCtx.getTypeDeclType(D2);
+        const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
+        Context.Diag1(Base1->getLocStart(), diag::note_odr_base)
+            << Base1->getType() << Base1->getSourceRange();
+        Context.Diag2(D2->getLocation(), diag::note_odr_missing_base);
+      }
+      return false;
+    }
+  }
+
+  // Check the fields for consistency.
+  RecordDecl::field_iterator Field2 = D2->field_begin(),
+                             Field2End = D2->field_end();
+  for (RecordDecl::field_iterator Field1 = D1->field_begin(),
+                                  Field1End = D1->field_end();
+       Field1 != Field1End; ++Field1, ++Field2) {
+    if (Field2 == Field2End) {
+      if (Context.Complain) {
+        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+            << Context.ToCtx.getTypeDeclType(D2);
+        Context.Diag1(Field1->getLocation(), diag::note_odr_field)
+            << Field1->getDeclName() << Field1->getType();
+        Context.Diag2(D2->getLocation(), diag::note_odr_missing_field);
+      }
+      return false;
+    }
+
+    if (!IsStructurallyEquivalent(Context, *Field1, *Field2))
+      return false;
+  }
+
+  if (Field2 != Field2End) {
+    if (Context.Complain) {
+      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+          << Context.ToCtx.getTypeDeclType(D2);
+      Context.Diag2(Field2->getLocation(), diag::note_odr_field)
+          << Field2->getDeclName() << Field2->getType();
+      Context.Diag1(D1->getLocation(), diag::note_odr_missing_field);
+    }
+    return false;
+  }
+
+  return true;
+}
+
+/// Determine structural equivalence of two enums.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     EnumDecl *D1, EnumDecl *D2) {
+  EnumDecl::enumerator_iterator EC2 = D2->enumerator_begin(),
+                                EC2End = D2->enumerator_end();
+  for (EnumDecl::enumerator_iterator EC1 = D1->enumerator_begin(),
+                                     EC1End = D1->enumerator_end();
+       EC1 != EC1End; ++EC1, ++EC2) {
+    if (EC2 == EC2End) {
+      if (Context.Complain) {
+        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+            << Context.ToCtx.getTypeDeclType(D2);
+        Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
+            << EC1->getDeclName() << EC1->getInitVal().toString(10);
+        Context.Diag2(D2->getLocation(), diag::note_odr_missing_enumerator);
+      }
+      return false;
+    }
+
+    llvm::APSInt Val1 = EC1->getInitVal();
+    llvm::APSInt Val2 = EC2->getInitVal();
+    if (!llvm::APSInt::isSameValue(Val1, Val2) ||
+        !IsStructurallyEquivalent(EC1->getIdentifier(), EC2->getIdentifier())) {
+      if (Context.Complain) {
+        Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+            << Context.ToCtx.getTypeDeclType(D2);
+        Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
+            << EC2->getDeclName() << EC2->getInitVal().toString(10);
+        Context.Diag1(EC1->getLocation(), diag::note_odr_enumerator)
+            << EC1->getDeclName() << EC1->getInitVal().toString(10);
+      }
+      return false;
+    }
+  }
+
+  if (EC2 != EC2End) {
+    if (Context.Complain) {
+      Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
+          << Context.ToCtx.getTypeDeclType(D2);
+      Context.Diag2(EC2->getLocation(), diag::note_odr_enumerator)
+          << EC2->getDeclName() << EC2->getInitVal().toString(10);
+      Context.Diag1(D1->getLocation(), diag::note_odr_missing_enumerator);
+    }
+    return false;
+  }
+
+  return true;
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     TemplateParameterList *Params1,
+                                     TemplateParameterList *Params2) {
+  if (Params1->size() != Params2->size()) {
+    if (Context.Complain) {
+      Context.Diag2(Params2->getTemplateLoc(),
+                    diag::err_odr_different_num_template_parameters)
+          << Params1->size() << Params2->size();
+      Context.Diag1(Params1->getTemplateLoc(),
+                    diag::note_odr_template_parameter_list);
+    }
+    return false;
+  }
+
+  for (unsigned I = 0, N = Params1->size(); I != N; ++I) {
+    if (Params1->getParam(I)->getKind() != Params2->getParam(I)->getKind()) {
+      if (Context.Complain) {
+        Context.Diag2(Params2->getParam(I)->getLocation(),
+                      diag::err_odr_different_template_parameter_kind);
+        Context.Diag1(Params1->getParam(I)->getLocation(),
+                      diag::note_odr_template_parameter_here);
+      }
+      return false;
+    }
+
+    if (!Context.IsStructurallyEquivalent(Params1->getParam(I),
+                                          Params2->getParam(I))) {
+
+      return false;
+    }
+  }
+
+  return true;
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     TemplateTypeParmDecl *D1,
+                                     TemplateTypeParmDecl *D2) {
+  if (D1->isParameterPack() != D2->isParameterPack()) {
+    if (Context.Complain) {
+      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+          << D2->isParameterPack();
+      Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
+          << D1->isParameterPack();
+    }
+    return false;
+  }
+
+  return true;
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     NonTypeTemplateParmDecl *D1,
+                                     NonTypeTemplateParmDecl *D2) {
+  if (D1->isParameterPack() != D2->isParameterPack()) {
+    if (Context.Complain) {
+      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+          << D2->isParameterPack();
+      Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
+          << D1->isParameterPack();
+    }
+    return false;
+  }
+
+  // Check types.
+  if (!Context.IsStructurallyEquivalent(D1->getType(), D2->getType())) {
+    if (Context.Complain) {
+      Context.Diag2(D2->getLocation(),
+                    diag::err_odr_non_type_parameter_type_inconsistent)
+          << D2->getType() << D1->getType();
+      Context.Diag1(D1->getLocation(), diag::note_odr_value_here)
+          << D1->getType();
+    }
+    return false;
+  }
+
+  return true;
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     TemplateTemplateParmDecl *D1,
+                                     TemplateTemplateParmDecl *D2) {
+  if (D1->isParameterPack() != D2->isParameterPack()) {
+    if (Context.Complain) {
+      Context.Diag2(D2->getLocation(), diag::err_odr_parameter_pack_non_pack)
+          << D2->isParameterPack();
+      Context.Diag1(D1->getLocation(), diag::note_odr_parameter_pack_non_pack)
+          << D1->isParameterPack();
+    }
+    return false;
+  }
+
+  // Check template parameter lists.
+  return IsStructurallyEquivalent(Context, D1->getTemplateParameters(),
+                                  D2->getTemplateParameters());
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     ClassTemplateDecl *D1,
+                                     ClassTemplateDecl *D2) {
+  // Check template parameters.
+  if (!IsStructurallyEquivalent(Context, D1->getTemplateParameters(),
+                                D2->getTemplateParameters()))
+    return false;
+
+  // Check the templated declaration.
+  return Context.IsStructurallyEquivalent(D1->getTemplatedDecl(),
+                                          D2->getTemplatedDecl());
+}
+
+/// Determine structural equivalence of two declarations.
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     Decl *D1, Decl *D2) {
+  // FIXME: Check for known structural equivalences via a callback of some sort.
+
+  // Check whether we already know that these two declarations are not
+  // structurally equivalent.
+  if (Context.NonEquivalentDecls.count(
+          std::make_pair(D1->getCanonicalDecl(), D2->getCanonicalDecl())))
+    return false;
+
+  // Determine whether we've already produced a tentative equivalence for D1.
+  Decl *&EquivToD1 = Context.TentativeEquivalences[D1->getCanonicalDecl()];
+  if (EquivToD1)
+    return EquivToD1 == D2->getCanonicalDecl();
+
+  // Produce a tentative equivalence D1 <-> D2, which will be checked later.
+  EquivToD1 = D2->getCanonicalDecl();
+  Context.DeclsToCheck.push_back(D1->getCanonicalDecl());
+  return true;
+}
+} // namespace
+
+namespace clang {
+
+DiagnosticBuilder StructuralEquivalenceContext::Diag1(SourceLocation Loc,
+                                                      unsigned DiagID) {
+  assert(Complain && "Not allowed to complain");
+  if (LastDiagFromC2)
+    FromCtx.getDiagnostics().notePriorDiagnosticFrom(ToCtx.getDiagnostics());
+  LastDiagFromC2 = false;
+  return FromCtx.getDiagnostics().Report(Loc, DiagID);
+}
+
+DiagnosticBuilder StructuralEquivalenceContext::Diag2(SourceLocation Loc,
+                                                      unsigned DiagID) {
+  assert(Complain && "Not allowed to complain");
+  if (!LastDiagFromC2)
+    ToCtx.getDiagnostics().notePriorDiagnosticFrom(FromCtx.getDiagnostics());
+  LastDiagFromC2 = true;
+  return ToCtx.getDiagnostics().Report(Loc, DiagID);
+}
+
+Optional<unsigned>
+StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
+  ASTContext &Context = Anon->getASTContext();
+  QualType AnonTy = Context.getRecordType(Anon);
+
+  RecordDecl *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
+  if (!Owner)
+    return None;
+
+  unsigned Index = 0;
+  for (const auto *D : Owner->noload_decls()) {
+    const auto *F = dyn_cast<FieldDecl>(D);
+    if (!F)
+      continue;
+
+    if (F->isAnonymousStructOrUnion()) {
+      if (Context.hasSameType(F->getType(), AnonTy))
+        break;
+      ++Index;
+      continue;
+    }
+
+    // If the field looks like this:
+    // struct { ... } A;
+    QualType FieldType = F->getType();
+    if (const auto *RecType = dyn_cast<RecordType>(FieldType)) {
+      const RecordDecl *RecDecl = RecType->getDecl();
+      if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) {
+        if (Context.hasSameType(FieldType, AnonTy))
+          break;
+        ++Index;
+        continue;
+      }
+    }
+  }
+
+  return Index;
+}
+
+bool StructuralEquivalenceContext::IsStructurallyEquivalent(Decl *D1,
+                                                            Decl *D2) {
+  if (!::IsStructurallyEquivalent(*this, D1, D2))
+    return false;
+
+  return !Finish();
+}
+
+bool StructuralEquivalenceContext::IsStructurallyEquivalent(QualType T1,
+                                                            QualType T2) {
+  if (!::IsStructurallyEquivalent(*this, T1, T2))
+    return false;
+
+  return !Finish();
+}
+
+bool StructuralEquivalenceContext::Finish() {
+  while (!DeclsToCheck.empty()) {
+    // Check the next declaration.
+    Decl *D1 = DeclsToCheck.front();
+    DeclsToCheck.pop_front();
+
+    Decl *D2 = TentativeEquivalences[D1];
+    assert(D2 && "Unrecorded tentative equivalence?");
+
+    bool Equivalent = true;
+
+    // FIXME: Switch on all declaration kinds. For now, we're just going to
+    // check the obvious ones.
+    if (RecordDecl *Record1 = dyn_cast<RecordDecl>(D1)) {
+      if (RecordDecl *Record2 = dyn_cast<RecordDecl>(D2)) {
+        // Check for equivalent structure names.
+        IdentifierInfo *Name1 = Record1->getIdentifier();
+        if (!Name1 && Record1->getTypedefNameForAnonDecl())
+          Name1 = Record1->getTypedefNameForAnonDecl()->getIdentifier();
+        IdentifierInfo *Name2 = Record2->getIdentifier();
+        if (!Name2 && Record2->getTypedefNameForAnonDecl())
+          Name2 = Record2->getTypedefNameForAnonDecl()->getIdentifier();
+        if (!::IsStructurallyEquivalent(Name1, Name2) ||
+            !::IsStructurallyEquivalent(*this, Record1, Record2))
+          Equivalent = false;
+      } else {
+        // Record/non-record mismatch.
+        Equivalent = false;
+      }
+    } else if (EnumDecl *Enum1 = dyn_cast<EnumDecl>(D1)) {
+      if (EnumDecl *Enum2 = dyn_cast<EnumDecl>(D2)) {
+        // Check for equivalent enum names.
+        IdentifierInfo *Name1 = Enum1->getIdentifier();
+        if (!Name1 && Enum1->getTypedefNameForAnonDecl())
+          Name1 = Enum1->getTypedefNameForAnonDecl()->getIdentifier();
+        IdentifierInfo *Name2 = Enum2->getIdentifier();
+        if (!Name2 && Enum2->getTypedefNameForAnonDecl())
+          Name2 = Enum2->getTypedefNameForAnonDecl()->getIdentifier();
+        if (!::IsStructurallyEquivalent(Name1, Name2) ||
+            !::IsStructurallyEquivalent(*this, Enum1, Enum2))
+          Equivalent = false;
+      } else {
+        // Enum/non-enum mismatch
+        Equivalent = false;
+      }
+    } else if (TypedefNameDecl *Typedef1 = dyn_cast<TypedefNameDecl>(D1)) {
+      if (TypedefNameDecl *Typedef2 = dyn_cast<TypedefNameDecl>(D2)) {
+        if (!::IsStructurallyEquivalent(Typedef1->getIdentifier(),
+                                        Typedef2->getIdentifier()) ||
+            !::IsStructurallyEquivalent(*this, Typedef1->getUnderlyingType(),
+                                        Typedef2->getUnderlyingType()))
+          Equivalent = false;
+      } else {
+        // Typedef/non-typedef mismatch.
+        Equivalent = false;
+      }
+    } else if (ClassTemplateDecl *ClassTemplate1 =
+                   dyn_cast<ClassTemplateDecl>(D1)) {
+      if (ClassTemplateDecl *ClassTemplate2 = dyn_cast<ClassTemplateDecl>(D2)) {
+        if (!::IsStructurallyEquivalent(ClassTemplate1->getIdentifier(),
+                                        ClassTemplate2->getIdentifier()) ||
+            !::IsStructurallyEquivalent(*this, ClassTemplate1, ClassTemplate2))
+          Equivalent = false;
+      } else {
+        // Class template/non-class-template mismatch.
+        Equivalent = false;
+      }
+    } else if (TemplateTypeParmDecl *TTP1 =
+                   dyn_cast<TemplateTypeParmDecl>(D1)) {
+      if (TemplateTypeParmDecl *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
+        if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
+          Equivalent = false;
+      } else {
+        // Kind mismatch.
+        Equivalent = false;
+      }
+    } else if (NonTypeTemplateParmDecl *NTTP1 =
+                   dyn_cast<NonTypeTemplateParmDecl>(D1)) {
+      if (NonTypeTemplateParmDecl *NTTP2 =
+              dyn_cast<NonTypeTemplateParmDecl>(D2)) {
+        if (!::IsStructurallyEquivalent(*this, NTTP1, NTTP2))
+          Equivalent = false;
+      } else {
+        // Kind mismatch.
+        Equivalent = false;
+      }
+    } else if (TemplateTemplateParmDecl *TTP1 =
+                   dyn_cast<TemplateTemplateParmDecl>(D1)) {
+      if (TemplateTemplateParmDecl *TTP2 =
+              dyn_cast<TemplateTemplateParmDecl>(D2)) {
+        if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
+          Equivalent = false;
+      } else {
+        // Kind mismatch.
+        Equivalent = false;
+      }
+    }
+
+    if (!Equivalent) {
+      // Note that these two declarations are not equivalent (and we already
+      // know about it).
+      NonEquivalentDecls.insert(
+          std::make_pair(D1->getCanonicalDecl(), D2->getCanonicalDecl()));
+      return true;
+    }
+    // FIXME: Check other declaration kinds!
+  }
+
+  return false;
+}
+} // namespace clang
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index e28bd2e..020057e 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -7,6 +7,7 @@
   ASTDiagnostic.cpp
   ASTDumper.cpp
   ASTImporter.cpp
+  ASTStructuralEquivalence.cpp
   ASTTypeTraits.cpp
   AttrImpl.cpp
   CXXInheritance.cpp
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index a97d6a2..e66616f 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -13,6 +13,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/RecordLayout.h"
 #include "llvm/ADT/SetVector.h"
 #include <algorithm>
@@ -56,6 +57,7 @@
 void CXXBasePaths::clear() {
   Paths.clear();
   ClassSubobjects.clear();
+  VisitedDependentRecords.clear();
   ScratchPath.clear();
   DetectedVirtual = nullptr;
 }
@@ -66,6 +68,7 @@
   std::swap(Origin, Other.Origin);
   Paths.swap(Other.Paths);
   ClassSubobjects.swap(Other.ClassSubobjects);
+  VisitedDependentRecords.swap(Other.VisitedDependentRecords);
   std::swap(FindAmbiguities, Other.FindAmbiguities);
   std::swap(RecordPaths, Other.RecordPaths);
   std::swap(DetectVirtual, Other.DetectVirtual);
@@ -174,9 +177,10 @@
   return AllMatches;
 }
 
-bool CXXBasePaths::lookupInBases(
-    ASTContext &Context, const CXXRecordDecl *Record,
-    CXXRecordDecl::BaseMatchesCallback BaseMatches) {
+bool CXXBasePaths::lookupInBases(ASTContext &Context,
+                                 const CXXRecordDecl *Record,
+                                 CXXRecordDecl::BaseMatchesCallback BaseMatches,
+                                 bool LookupInDependent) {
   bool FoundPath = false;
 
   // The access of the path down to this record.
@@ -194,7 +198,7 @@
     //   the base class scope is not examined during unqualified name lookup 
     //   either at the point of definition of the class template or member or 
     //   during an instantiation of the class tem- plate or member.
-    if (BaseType->isDependentType())
+    if (!LookupInDependent && BaseType->isDependentType())
       continue;
     
     // Determine whether we need to visit this base class at all,
@@ -262,10 +266,34 @@
         return FoundPath;
       }
     } else if (VisitBase) {
-      CXXRecordDecl *BaseRecord
-        = cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>()
-                                ->getDecl());
-      if (lookupInBases(Context, BaseRecord, BaseMatches)) {
+      CXXRecordDecl *BaseRecord;
+      if (LookupInDependent) {
+        BaseRecord = nullptr;
+        const TemplateSpecializationType *TST =
+            BaseSpec.getType()->getAs<TemplateSpecializationType>();
+        if (!TST) {
+          if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
+            BaseRecord = cast<CXXRecordDecl>(RT->getDecl());
+        } else {
+          TemplateName TN = TST->getTemplateName();
+          if (auto *TD =
+                  dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()))
+            BaseRecord = TD->getTemplatedDecl();
+        }
+        if (BaseRecord) {
+          if (!BaseRecord->hasDefinition() ||
+              VisitedDependentRecords.count(BaseRecord)) {
+            BaseRecord = nullptr;
+          } else {
+            VisitedDependentRecords.insert(BaseRecord);
+          }
+        }
+      } else {
+        BaseRecord = cast<CXXRecordDecl>(
+            BaseSpec.getType()->castAs<RecordType>()->getDecl());
+      }
+      if (BaseRecord &&
+          lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) {
         // C++ [class.member.lookup]p2:
         //   A member name f in one sub-object B hides a member name f in
         //   a sub-object A if A is a base class sub-object of B. Any
@@ -299,9 +327,11 @@
 }
 
 bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
-                                  CXXBasePaths &Paths) const {
+                                  CXXBasePaths &Paths,
+                                  bool LookupInDependent) const {
   // If we didn't find anything, report that.
-  if (!Paths.lookupInBases(getASTContext(), this, BaseMatches))
+  if (!Paths.lookupInBases(getASTContext(), this, BaseMatches,
+                           LookupInDependent))
     return false;
 
   // If we're not recording paths or we won't ever find ambiguities,
@@ -387,23 +417,49 @@
   return false;
 }
 
-bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier, 
-                                       CXXBasePath &Path,
-                                       DeclarationName Name) {
-  RecordDecl *BaseRecord =
-    Specifier->getType()->castAs<RecordType>()->getDecl();
-  
-  const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member;
+static bool findOrdinaryMember(RecordDecl *BaseRecord, CXXBasePath &Path,
+                               DeclarationName Name) {
+  const unsigned IDNS = clang::Decl::IDNS_Ordinary | clang::Decl::IDNS_Tag |
+                        clang::Decl::IDNS_Member;
   for (Path.Decls = BaseRecord->lookup(Name);
        !Path.Decls.empty();
        Path.Decls = Path.Decls.slice(1)) {
     if (Path.Decls.front()->isInIdentifierNamespace(IDNS))
       return true;
   }
-  
+
   return false;
 }
 
+bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
+                                       CXXBasePath &Path,
+                                       DeclarationName Name) {
+  RecordDecl *BaseRecord =
+      Specifier->getType()->castAs<RecordType>()->getDecl();
+  return findOrdinaryMember(BaseRecord, Path, Name);
+}
+
+bool CXXRecordDecl::FindOrdinaryMemberInDependentClasses(
+    const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
+    DeclarationName Name) {
+  const TemplateSpecializationType *TST =
+      Specifier->getType()->getAs<TemplateSpecializationType>();
+  if (!TST) {
+    auto *RT = Specifier->getType()->getAs<RecordType>();
+    if (!RT)
+      return false;
+    return findOrdinaryMember(RT->getDecl(), Path, Name);
+  }
+  TemplateName TN = TST->getTemplateName();
+  const auto *TD = dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
+  if (!TD)
+    return false;
+  CXXRecordDecl *RD = TD->getTemplatedDecl();
+  if (!RD)
+    return false;
+  return findOrdinaryMember(RD, Path, Name);
+}
+
 bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
                                            CXXBasePath &Path,
                                            DeclarationName Name) {
@@ -438,6 +494,36 @@
   return false;
 }
 
+std::vector<const NamedDecl *> CXXRecordDecl::lookupDependentName(
+    const DeclarationName &Name,
+    llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
+  std::vector<const NamedDecl *> Results;
+  // Lookup in the class.
+  DeclContext::lookup_result DirectResult = lookup(Name);
+  if (!DirectResult.empty()) {
+    for (const NamedDecl *ND : DirectResult) {
+      if (Filter(ND))
+        Results.push_back(ND);
+    }
+    return Results;
+  }
+  // Perform lookup into our base classes.
+  CXXBasePaths Paths;
+  Paths.setOrigin(this);
+  if (!lookupInBases(
+          [&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
+            return CXXRecordDecl::FindOrdinaryMemberInDependentClasses(
+                Specifier, Path, Name);
+          },
+          Paths, /*LookupInDependent=*/true))
+    return Results;
+  for (const NamedDecl *ND : Paths.front().Decls) {
+    if (Filter(ND))
+      Results.push_back(ND);
+  }
+  return Results;
+}
+
 void OverridingMethods::add(unsigned OverriddenSubobject, 
                             UniqueVirtualMethod Overriding) {
   SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides
diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index 7a7d3dd..dfa2a16 100644
--- a/lib/AST/Comment.cpp
+++ b/lib/AST/Comment.cpp
@@ -116,6 +116,9 @@
 static TypeLoc lookThroughTypedefOrTypeAliasLocs(TypeLoc &SrcTL) {
   TypeLoc TL = SrcTL.IgnoreParens();
 
+  // Look through attribute types.
+  if (AttributedTypeLoc AttributeTL = TL.getAs<AttributedTypeLoc>())
+    return AttributeTL.getModifiedLoc();
   // Look through qualified types.
   if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>())
     return QualifiedTL.getUnqualifiedLoc();
@@ -280,8 +283,25 @@
   case Decl::EnumConstant:
   case Decl::ObjCIvar:
   case Decl::ObjCAtDefsField:
+  case Decl::ObjCProperty: {
+    const TypeSourceInfo *TSI;
+    if (const auto *VD = dyn_cast<DeclaratorDecl>(CommentDecl))
+      TSI = VD->getTypeSourceInfo();
+    else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(CommentDecl))
+      TSI = PD->getTypeSourceInfo();
+    else
+      TSI = nullptr;
+    if (TSI) {
+      TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc();
+      FunctionTypeLoc FTL;
+      if (getFunctionTypeLoc(TL, FTL)) {
+        ParamVars = FTL.getParams();
+        ReturnType = FTL.getReturnLoc().getType();
+      }
+    }
     Kind = VariableKind;
     break;
+  }
   case Decl::Namespace:
     Kind = NamespaceKind;
     break;
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index d39a9b2..403454d 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -86,7 +86,7 @@
       new (Allocator) ParamCommandComment(LocBegin, LocEnd, CommandID,
                                           CommandMarker);
 
-  if (!isFunctionDecl())
+  if (!isFunctionDecl() && !isFunctionOrBlockPointerVarLikeDecl())
     Diag(Command->getLocation(),
          diag::warn_doc_param_not_attached_to_a_function_decl)
       << CommandMarker
@@ -584,7 +584,11 @@
 
   assert(ThisDeclInfo && "should not call this check on a bare comment");
 
-  if (isFunctionDecl()) {
+  // We allow the return command for all @properties because it can be used
+  // to document the value that the property getter returns.
+  if (isObjCPropertyDecl())
+    return;
+  if (isFunctionDecl() || isFunctionOrBlockPointerVarLikeDecl()) {
     if (ThisDeclInfo->ReturnType->isVoidType()) {
       unsigned DiagKind;
       switch (ThisDeclInfo->CommentDecl->getKind()) {
@@ -610,8 +614,6 @@
     }
     return;
   }
-  else if (isObjCPropertyDecl())
-    return;
 
   Diag(Command->getLocation(),
        diag::warn_doc_returns_not_attached_to_a_function_decl)
@@ -844,6 +846,30 @@
   return false;
 }
 
+bool Sema::isFunctionOrBlockPointerVarLikeDecl() {
+  if (!ThisDeclInfo)
+    return false;
+  if (!ThisDeclInfo->IsFilled)
+    inspectThisDecl();
+  if (ThisDeclInfo->getKind() != DeclInfo::VariableKind ||
+      !ThisDeclInfo->CurrentDecl)
+    return false;
+  QualType QT;
+  if (const auto *VD = dyn_cast<DeclaratorDecl>(ThisDeclInfo->CurrentDecl))
+    QT = VD->getType();
+  else if (const auto *PD =
+               dyn_cast<ObjCPropertyDecl>(ThisDeclInfo->CurrentDecl))
+    QT = PD->getType();
+  else
+    return false;
+  // We would like to warn about the 'returns'/'param' commands for
+  // variables that don't directly specify the function type, so type aliases
+  // can be ignored.
+  if (QT->getAs<TypedefType>())
+    return false;
+  return QT->isFunctionPointerType() || QT->isBlockPointerType();
+}
+
 bool Sema::isObjCPropertyDecl() {
   if (!ThisDeclInfo)
     return false;
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 81f0878..6d5a618 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1414,6 +1414,11 @@
                                    const PrintingPolicy &P) const {
   const DeclContext *Ctx = getDeclContext();
 
+  // For ObjC methods, look through categories and use the interface as context.
+  if (auto *MD = dyn_cast<ObjCMethodDecl>(this))
+    if (auto *ID = MD->getClassInterface())
+      Ctx = ID;
+
   if (Ctx->isFunctionOrMethod()) {
     printName(OS);
     return;
@@ -3744,6 +3749,20 @@
   TagDecl::completeDefinition();
 }
 
+bool EnumDecl::isClosed() const {
+  if (const auto *A = getAttr<EnumExtensibilityAttr>())
+    return A->getExtensibility() == EnumExtensibilityAttr::Closed;
+  return true;
+}
+
+bool EnumDecl::isClosedFlag() const {
+  return isClosed() && hasAttr<FlagEnumAttr>();
+}
+
+bool EnumDecl::isClosedNonFlag() const {
+  return isClosed() && !hasAttr<FlagEnumAttr>();
+}
+
 TemplateSpecializationKind EnumDecl::getTemplateSpecializationKind() const {
   if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
     return MSI->getTemplateSpecializationKind();
@@ -4230,6 +4249,30 @@
   return nullptr;
 }
 
+bool TypedefNameDecl::isTransparentTagSlow() const {
+  auto determineIsTransparent = [&]() {
+    if (auto *TT = getUnderlyingType()->getAs<TagType>()) {
+      if (auto *TD = TT->getDecl()) {
+        if (TD->getName() != getName())
+          return false;
+        SourceLocation TTLoc = getLocation();
+        SourceLocation TDLoc = TD->getLocation();
+        if (!TTLoc.isMacroID() || !TDLoc.isMacroID())
+          return false;
+        SourceManager &SM = getASTContext().getSourceManager();
+        return SM.getSpellingLoc(TTLoc) == SM.getSpellingLoc(TDLoc);
+      }
+    }
+    return false;
+  };
+
+  bool isTransparent = determineIsTransparent();
+  CacheIsTransparentTag = 1;
+  if (isTransparent)
+    CacheIsTransparentTag |= 0x2;
+  return isTransparent;
+}
+
 TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
   return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(),
                                  nullptr, nullptr);
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 6111aba..4ab06b4 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -403,6 +403,27 @@
   return false;
 }
 
+ExternalSourceSymbolAttr *Decl::getExternalSourceSymbolAttr() const {
+  const Decl *Definition = nullptr;
+  if (auto ID = dyn_cast<ObjCInterfaceDecl>(this)) {
+    Definition = ID->getDefinition();
+  } else if (auto PD = dyn_cast<ObjCProtocolDecl>(this)) {
+    Definition = PD->getDefinition();
+  } else if (auto TD = dyn_cast<TagDecl>(this)) {
+    Definition = TD->getDefinition();
+  }
+  if (!Definition)
+    Definition = this;
+
+  if (auto *attr = Definition->getAttr<ExternalSourceSymbolAttr>())
+    return attr;
+  if (auto *dcd = dyn_cast<Decl>(getDeclContext())) {
+    return dcd->getAttr<ExternalSourceSymbolAttr>();
+  }
+
+  return nullptr;
+}
+
 bool Decl::hasDefiningAttr() const {
   return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
 }
@@ -415,6 +436,19 @@
   return nullptr;
 }
 
+StringRef getRealizedPlatform(const AvailabilityAttr *A,
+                              const ASTContext &Context) {
+  // Check if this is an App Extension "platform", and if so chop off
+  // the suffix for matching with the actual platform.
+  StringRef RealizedPlatform = A->getPlatform()->getName();
+  if (!Context.getLangOpts().AppExt)
+    return RealizedPlatform;
+  size_t suffix = RealizedPlatform.rfind("_app_extension");
+  if (suffix != StringRef::npos)
+    return RealizedPlatform.slice(0, suffix);
+  return RealizedPlatform;
+}
+
 /// \brief Determine the availability of the given declaration based on
 /// the target platform.
 ///
@@ -434,20 +468,11 @@
   if (EnclosingVersion.empty())
     return AR_Available;
 
-  // Check if this is an App Extension "platform", and if so chop off
-  // the suffix for matching with the actual platform.
   StringRef ActualPlatform = A->getPlatform()->getName();
-  StringRef RealizedPlatform = ActualPlatform;
-  if (Context.getLangOpts().AppExt) {
-    size_t suffix = RealizedPlatform.rfind("_app_extension");
-    if (suffix != StringRef::npos)
-      RealizedPlatform = RealizedPlatform.slice(0, suffix);
-  }
-
   StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
 
   // Match the platform name.
-  if (RealizedPlatform != TargetPlatform)
+  if (getRealizedPlatform(A, Context) != TargetPlatform)
     return AR_Available;
 
   StringRef PrettyPlatformName
@@ -567,6 +592,20 @@
   return Result;
 }
 
+VersionTuple Decl::getVersionIntroduced() const {
+  const ASTContext &Context = getASTContext();
+  StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
+  for (const auto *A : attrs()) {
+    if (const auto *Availability = dyn_cast<AvailabilityAttr>(A)) {
+      if (getRealizedPlatform(Availability, Context) != TargetPlatform)
+        continue;
+      if (!Availability->getIntroduced().empty())
+        return Availability->getIntroduced();
+    }
+  }
+  return VersionTuple();
+}
+
 bool Decl::canBeWeakImported(bool &IsDefinition) const {
   IsDefinition = false;
 
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index a9db65a..1edc5ae 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -702,9 +702,7 @@
     ASTContext &Context = getASTContext();
     QualType T = Context.getBaseElementType(Field->getType());
     if (T->isObjCRetainableType() || T.isObjCGCStrong()) {
-      if (!Context.getLangOpts().ObjCAutoRefCount) {
-        setHasObjectMember(true);
-      } else if (T.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
+      if (T.hasNonTrivialObjCLifetime()) {
         // Objective-C Automatic Reference Counting:
         //   If a class has a non-static data member of Objective-C pointer
         //   type (or array thereof), it is a non-POD type and its
@@ -716,6 +714,8 @@
         Data.PlainOldData = false;
         Data.HasTrivialSpecialMembers = 0;
         Data.HasIrrelevantDestructor = false;
+      } else if (!Context.getLangOpts().ObjCAutoRefCount) {
+        setHasObjectMember(true);
       }
     } else if (!T.isCXX98PODType(Context))
       data().PlainOldData = false;
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 60d05f6..a55d8aa 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -162,10 +162,10 @@
         return nullptr;
   }
 
-  // If context is class, then lookup property in its extensions.
+  // If context is class, then lookup property in its visible extensions.
   // This comes before property is looked up in primary class.
   if (auto *IDecl = dyn_cast<ObjCInterfaceDecl>(DC)) {
-    for (const auto *Ext : IDecl->known_extensions())
+    for (const auto *Ext : IDecl->visible_extensions())
       if (ObjCPropertyDecl *PD = ObjCPropertyDecl::findPropertyDecl(Ext,
                                                        propertyID,
                                                        queryKind))
@@ -539,9 +539,18 @@
 
 bool ObjCInterfaceDecl::isDesignatedInitializer(Selector Sel,
                                       const ObjCMethodDecl **InitMethod) const {
+  bool HasCompleteDef = isThisDeclarationADefinition();
+  // During deserialization the data record for the ObjCInterfaceDecl could
+  // be made invariant by reusing the canonical decl. Take this into account
+  // when checking for the complete definition.
+  if (!HasCompleteDef && getCanonicalDecl()->hasDefinition() &&
+      getCanonicalDecl()->getDefinition() == getDefinition())
+    HasCompleteDef = true;
+
   // Check for a complete definition and recover if not so.
-  if (!isThisDeclarationADefinition())
+  if (!HasCompleteDef)
     return false;
+
   if (data().ExternallyCompleted)
     LoadExternalDefinition();
 
@@ -1329,12 +1338,8 @@
                                              IdentifierInfo *name,
                                              SourceLocation colonLoc,
                                              TypeSourceInfo *boundInfo) {
-  auto *TPDecl =
-    new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
-                                    nameLoc, name, colonLoc, boundInfo);
-  QualType TPType = ctx.getObjCTypeParamType(TPDecl, {});
-  TPDecl->setTypeForDecl(TPType.getTypePtr());
-  return TPDecl;
+  return new (ctx, dc) ObjCTypeParamDecl(ctx, dc, variance, varianceLoc, index,
+                                         nameLoc, name, colonLoc, boundInfo);
 }
 
 ObjCTypeParamDecl *ObjCTypeParamDecl::CreateDeserialized(ASTContext &ctx,
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index b8ebe1c..e7a276d 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -501,7 +501,14 @@
 
   PrintingPolicy SubPolicy(Policy);
   SubPolicy.SuppressSpecifiers = false;
-  std::string Proto = D->getNameInfo().getAsString();
+  std::string Proto;
+  if (!Policy.SuppressScope) {
+    if (const NestedNameSpecifier *NS = D->getQualifier()) {
+      llvm::raw_string_ostream OS(Proto);
+      NS->print(OS, Policy);
+    }
+  }
+  Proto += D->getNameInfo().getAsString();
   if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {
     llvm::raw_string_ostream POut(Proto);
     DeclPrinter TArgPrinter(POut, SubPolicy, Indentation);
@@ -1231,6 +1238,9 @@
     return;
   }
   bool eolnOut = false;
+  prettyPrintAttributes(OID);
+  if (OID->hasAttrs()) Out << "\n";
+
   Out << "@interface " << I;
 
   if (auto TypeParams = OID->getTypeParamListAsWritten()) {
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 52791e5..23bcd6d 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -574,7 +574,9 @@
       LangOptions LO;
       LO.CPlusPlus = true;
       LO.Bool = true;
-      OS << TInfo->getType().getAsString(PrintingPolicy(LO));
+      PrintingPolicy PP(LO);
+      PP.SuppressScope = true;
+      OS << TInfo->getType().getAsString(PP);
     } else
       OS << Name;
     return;
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 2c0fce9..1bf0981 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1404,7 +1404,8 @@
                                     EvalInfo &Info);
 static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
 static bool EvaluateComplex(const Expr *E, ComplexValue &Res, EvalInfo &Info);
-static bool EvaluateAtomic(const Expr *E, APValue &Result, EvalInfo &Info);
+static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
+                           EvalInfo &Info);
 static bool EvaluateAsRValue(EvalInfo &Info, const Expr *E, APValue &Result);
 
 //===----------------------------------------------------------------------===//
@@ -4691,7 +4692,10 @@
 
     case CK_AtomicToNonAtomic: {
       APValue AtomicVal;
-      if (!EvaluateAtomic(E->getSubExpr(), AtomicVal, Info))
+      // This does not need to be done in place even for class/array types:
+      // atomic-to-non-atomic conversion implies copying the object
+      // representation.
+      if (!Evaluate(AtomicVal, Info, E->getSubExpr()))
         return false;
       return DerivedSuccess(AtomicVal, E);
     }
@@ -9565,10 +9569,11 @@
 namespace {
 class AtomicExprEvaluator :
     public ExprEvaluatorBase<AtomicExprEvaluator> {
+  const LValue *This;
   APValue &Result;
 public:
-  AtomicExprEvaluator(EvalInfo &Info, APValue &Result)
-      : ExprEvaluatorBaseTy(Info), Result(Result) {}
+  AtomicExprEvaluator(EvalInfo &Info, const LValue *This, APValue &Result)
+      : ExprEvaluatorBaseTy(Info), This(This), Result(Result) {}
 
   bool Success(const APValue &V, const Expr *E) {
     Result = V;
@@ -9578,7 +9583,10 @@
   bool ZeroInitialization(const Expr *E) {
     ImplicitValueInitExpr VIE(
         E->getType()->castAs<AtomicType>()->getValueType());
-    return Evaluate(Result, Info, &VIE);
+    // For atomic-qualified class (and array) types in C++, initialize the
+    // _Atomic-wrapped subobject directly, in-place.
+    return This ? EvaluateInPlace(Result, Info, *This, &VIE)
+                : Evaluate(Result, Info, &VIE);
   }
 
   bool VisitCastExpr(const CastExpr *E) {
@@ -9586,15 +9594,17 @@
     default:
       return ExprEvaluatorBaseTy::VisitCastExpr(E);
     case CK_NonAtomicToAtomic:
-      return Evaluate(Result, Info, E->getSubExpr());
+      return This ? EvaluateInPlace(Result, Info, *This, E->getSubExpr())
+                  : Evaluate(Result, Info, E->getSubExpr());
     }
   }
 };
 } // end anonymous namespace
 
-static bool EvaluateAtomic(const Expr *E, APValue &Result, EvalInfo &Info) {
+static bool EvaluateAtomic(const Expr *E, const LValue *This, APValue &Result,
+                           EvalInfo &Info) {
   assert(E->isRValue() && E->getType()->isAtomicType());
-  return AtomicExprEvaluator(Info, Result).Visit(E);
+  return AtomicExprEvaluator(Info, This, Result).Visit(E);
 }
 
 //===----------------------------------------------------------------------===//
@@ -9699,8 +9709,17 @@
     if (!EvaluateVoid(E, Info))
       return false;
   } else if (T->isAtomicType()) {
-    if (!EvaluateAtomic(E, Result, Info))
-      return false;
+    QualType Unqual = T.getAtomicUnqualifiedType();
+    if (Unqual->isArrayType() || Unqual->isRecordType()) {
+      LValue LV;
+      LV.set(E, Info.CurrentCall->Index);
+      APValue &Value = Info.CurrentCall->createTemporary(E, false);
+      if (!EvaluateAtomic(E, &LV, Value, Info))
+        return false;
+    } else {
+      if (!EvaluateAtomic(E, nullptr, Result, Info))
+        return false;
+    }
   } else if (Info.getLangOpts().CPlusPlus11) {
     Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->getType();
     return false;
@@ -9725,10 +9744,16 @@
   if (E->isRValue()) {
     // Evaluate arrays and record types in-place, so that later initializers can
     // refer to earlier-initialized members of the object.
-    if (E->getType()->isArrayType())
+    QualType T = E->getType();
+    if (T->isArrayType())
       return EvaluateArray(E, This, Result, Info);
-    else if (E->getType()->isRecordType())
+    else if (T->isRecordType())
       return EvaluateRecord(E, This, Result, Info);
+    else if (T->isAtomicType()) {
+      QualType Unqual = T.getAtomicUnqualifiedType();
+      if (Unqual->isArrayType() || Unqual->isRecordType())
+        return EvaluateAtomic(E, &This, Result, Info);
+    }
   }
 
   // For any other type, in-place evaluation is unimportant.
diff --git a/lib/AST/Mangle.cpp b/lib/AST/Mangle.cpp
index 05dd886..00d50c0 100644
--- a/lib/AST/Mangle.cpp
+++ b/lib/AST/Mangle.cpp
@@ -262,9 +262,13 @@
   const ObjCContainerDecl *CD =
   dyn_cast<ObjCContainerDecl>(MD->getDeclContext());
   assert (CD && "Missing container decl in GetNameForMethod");
-  OS << (MD->isInstanceMethod() ? '-' : '+') << '[' << CD->getName();
-  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD))
+  OS << (MD->isInstanceMethod() ? '-' : '+') << '[';
+  if (const ObjCCategoryImplDecl *CID = dyn_cast<ObjCCategoryImplDecl>(CD)) {
+    OS << CID->getClassInterface()->getName();
     OS << '(' << *CID << ')';
+  } else {
+    OS << CD->getName();
+  }
   OS << ' ';
   MD->getSelector().print(OS);
   OS << ']';
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 0d0cd2e..f5c2523 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1081,24 +1081,13 @@
 
     // Replace an Objective-C type parameter reference with the corresponding
     // type argument.
-    if (const auto *OTPTy = dyn_cast<ObjCTypeParamType>(splitType.Ty)) {
-      if (auto *typeParam = dyn_cast<ObjCTypeParamDecl>(OTPTy->getDecl())) {
+    if (const auto *typedefTy = dyn_cast<TypedefType>(splitType.Ty)) {
+      if (auto *typeParam = dyn_cast<ObjCTypeParamDecl>(typedefTy->getDecl())) {
         // If we have type arguments, use them.
         if (!typeArgs.empty()) {
+          // FIXME: Introduce SubstObjCTypeParamType ?
           QualType argType = typeArgs[typeParam->getIndex()];
-          if (OTPTy->qual_empty())
-            return ctx.getQualifiedType(argType, splitType.Quals);
-
-          // Apply protocol lists if exists.
-          bool hasError;
-          SmallVector<ObjCProtocolDecl*, 8> protocolsVec;
-          protocolsVec.append(OTPTy->qual_begin(),
-                              OTPTy->qual_end());
-          ArrayRef<ObjCProtocolDecl *> protocolsToApply = protocolsVec;
-          QualType resultTy = ctx.applyObjCProtocolQualifiers(argType,
-              protocolsToApply, hasError, true/*allowOnPointerType*/);
-
-          return ctx.getQualifiedType(resultTy, splitType.Quals);
+          return ctx.getQualifiedType(argType, splitType.Quals);
         }
 
         switch (context) {
@@ -2005,20 +1994,8 @@
   if ((*this)->isIncompleteType())
     return false;
 
-  if (Context.getLangOpts().ObjCAutoRefCount) {
-    switch (getObjCLifetime()) {
-    case Qualifiers::OCL_ExplicitNone:
-      return true;
-      
-    case Qualifiers::OCL_Strong:
-    case Qualifiers::OCL_Weak:
-    case Qualifiers::OCL_Autoreleasing:
-      return false;
-
-    case Qualifiers::OCL_None:
-      break;
-    }        
-  }
+  if (hasNonTrivialObjCLifetime())
+    return false;
   
   QualType CanonicalType = getTypePtr()->CanonicalType;
   switch (CanonicalType->getTypeClass()) {
@@ -2067,22 +2044,8 @@
   if ((*this)->isIncompleteType())
     return false;
   
-  if (Context.getLangOpts().ObjCAutoRefCount) {
-    switch (getObjCLifetime()) {
-    case Qualifiers::OCL_ExplicitNone:
-      return true;
-      
-    case Qualifiers::OCL_Strong:
-    case Qualifiers::OCL_Weak:
-    case Qualifiers::OCL_Autoreleasing:
-      return false;
-      
-    case Qualifiers::OCL_None:
-      if ((*this)->isObjCLifetimeType())
-        return false;
-      break;
-    }        
-  }
+  if (hasNonTrivialObjCLifetime())
+    return false;
   
   QualType CanonicalType = getTypePtr()->CanonicalType;
   if (CanonicalType->isDependentType())
@@ -2119,22 +2082,8 @@
   if ((*this)->isArrayType())
     return Context.getBaseElementType(*this).isTriviallyCopyableType(Context);
 
-  if (Context.getLangOpts().ObjCAutoRefCount) {
-    switch (getObjCLifetime()) {
-    case Qualifiers::OCL_ExplicitNone:
-      return true;
-      
-    case Qualifiers::OCL_Strong:
-    case Qualifiers::OCL_Weak:
-    case Qualifiers::OCL_Autoreleasing:
-      return false;
-      
-    case Qualifiers::OCL_None:
-      if ((*this)->isObjCLifetimeType())
-        return false;
-      break;
-    }        
-  }
+  if (hasNonTrivialObjCLifetime())
+    return false;
 
   // C++11 [basic.types]p9
   //   Scalar types, trivially copyable class types, arrays of such types, and
@@ -2170,7 +2119,11 @@
   return false;
 }
 
-
+bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const {
+  return !Context.getLangOpts().ObjCAutoRefCount &&
+         Context.getLangOpts().ObjCWeak &&
+         getObjCLifetime() != Qualifiers::OCL_Weak;
+}
 
 bool Type::isLiteralType(const ASTContext &Ctx) const {
   if (isDependentType())
@@ -2280,20 +2233,8 @@
   if (ty->isDependentType())
     return false;
 
-  if (Context.getLangOpts().ObjCAutoRefCount) {
-    switch (getObjCLifetime()) {
-    case Qualifiers::OCL_ExplicitNone:
-      return true;
-      
-    case Qualifiers::OCL_Strong:
-    case Qualifiers::OCL_Weak:
-    case Qualifiers::OCL_Autoreleasing:
-      return false;
-
-    case Qualifiers::OCL_None:
-      break;
-    }        
-  }
+  if (hasNonTrivialObjCLifetime())
+    return false;
 
   // C++11 [basic.types]p9:
   //   Scalar types, POD classes, arrays of such types, and cv-qualified
diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp
index 56c812c..5912724 100644
--- a/lib/Analysis/BodyFarm.cpp
+++ b/lib/Analysis/BodyFarm.cpp
@@ -87,7 +87,7 @@
                                          QualType Ty) {
  return new (C) BinaryOperator(const_cast<Expr*>(LHS), const_cast<Expr*>(RHS),
                                BO_Assign, Ty, VK_RValue,
-                               OK_Ordinary, SourceLocation(), false);
+                               OK_Ordinary, SourceLocation(), FPOptions());
 }
 
 BinaryOperator *ASTMaker::makeComparison(const Expr *LHS, const Expr *RHS,
@@ -99,7 +99,7 @@
                                 Op,
                                 C.getLogicalOperationType(),
                                 VK_RValue,
-                                OK_Ordinary, SourceLocation(), false);
+                                OK_Ordinary, SourceLocation(), FPOptions());
 }
 
 CompoundStmt *ASTMaker::makeCompound(ArrayRef<Stmt *> Stmts) {
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index d56e0e8..2a2b3d7 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -1390,7 +1390,7 @@
 
   // Check if type is a C++ class with non-trivial destructor.
   if (const CXXRecordDecl *CD = QT->getAsCXXRecordDecl())
-    if (!CD->hasTrivialDestructor()) {
+    if (CD->hasDefinition() && !CD->hasTrivialDestructor()) {
       // Add the variable to scope
       Scope = createOrReuseLocalScope(Scope);
       Scope->addVar(VD);
diff --git a/lib/Analysis/CallGraph.cpp b/lib/Analysis/CallGraph.cpp
index 8c126b0..6d9530b 100644
--- a/lib/Analysis/CallGraph.cpp
+++ b/lib/Analysis/CallGraph.cpp
@@ -62,6 +62,7 @@
   void VisitCallExpr(CallExpr *CE) {
     if (Decl *D = getDeclFromCall(CE))
       addCalledDecl(D);
+    VisitChildren(CE);
   }
 
   // Adds may-call edges for the ObjC message sends.
diff --git a/lib/Analysis/CloneDetection.cpp b/lib/Analysis/CloneDetection.cpp
index e761738..033329a 100644
--- a/lib/Analysis/CloneDetection.cpp
+++ b/lib/Analysis/CloneDetection.cpp
@@ -24,27 +24,27 @@
 
 using namespace clang;
 
-StmtSequence::StmtSequence(const CompoundStmt *Stmt, ASTContext &Context,
+StmtSequence::StmtSequence(const CompoundStmt *Stmt, const Decl *D,
                            unsigned StartIndex, unsigned EndIndex)
-    : S(Stmt), Context(&Context), StartIndex(StartIndex), EndIndex(EndIndex) {
+    : S(Stmt), D(D), StartIndex(StartIndex), EndIndex(EndIndex) {
   assert(Stmt && "Stmt must not be a nullptr");
   assert(StartIndex < EndIndex && "Given array should not be empty");
   assert(EndIndex <= Stmt->size() && "Given array too big for this Stmt");
 }
 
-StmtSequence::StmtSequence(const Stmt *Stmt, ASTContext &Context)
-    : S(Stmt), Context(&Context), StartIndex(0), EndIndex(0) {}
+StmtSequence::StmtSequence(const Stmt *Stmt, const Decl *D)
+    : S(Stmt), D(D), StartIndex(0), EndIndex(0) {}
 
 StmtSequence::StmtSequence()
-    : S(nullptr), Context(nullptr), StartIndex(0), EndIndex(0) {}
+    : S(nullptr), D(nullptr), StartIndex(0), EndIndex(0) {}
 
 bool StmtSequence::contains(const StmtSequence &Other) const {
-  // If both sequences reside in different translation units, they can never
-  // contain each other.
-  if (Context != Other.Context)
+  // If both sequences reside in different declarations, they can never contain
+  // each other.
+  if (D != Other.D)
     return false;
 
-  const SourceManager &SM = Context->getSourceManager();
+  const SourceManager &SM = getASTContext().getSourceManager();
 
   // Otherwise check if the start and end locations of the current sequence
   // surround the other sequence.
@@ -76,6 +76,11 @@
   return CS->body_begin() + EndIndex;
 }
 
+ASTContext &StmtSequence::getASTContext() const {
+  assert(D);
+  return D->getASTContext();
+}
+
 SourceLocation StmtSequence::getStartLoc() const {
   return front()->getLocStart();
 }
@@ -86,168 +91,8 @@
   return SourceRange(getStartLoc(), getEndLoc());
 }
 
-namespace {
-
-/// \brief Analyzes the pattern of the referenced variables in a statement.
-class VariablePattern {
-
-  /// \brief Describes an occurence of a variable reference in a statement.
-  struct VariableOccurence {
-    /// The index of the associated VarDecl in the Variables vector.
-    size_t KindID;
-    /// The statement in the code where the variable was referenced.
-    const Stmt *Mention;
-
-    VariableOccurence(size_t KindID, const Stmt *Mention)
-        : KindID(KindID), Mention(Mention) {}
-  };
-
-  /// All occurences of referenced variables in the order of appearance.
-  std::vector<VariableOccurence> Occurences;
-  /// List of referenced variables in the order of appearance.
-  /// Every item in this list is unique.
-  std::vector<const VarDecl *> Variables;
-
-  /// \brief Adds a new variable referenced to this pattern.
-  /// \param VarDecl The declaration of the variable that is referenced.
-  /// \param Mention The SourceRange where this variable is referenced.
-  void addVariableOccurence(const VarDecl *VarDecl, const Stmt *Mention) {
-    // First check if we already reference this variable
-    for (size_t KindIndex = 0; KindIndex < Variables.size(); ++KindIndex) {
-      if (Variables[KindIndex] == VarDecl) {
-        // If yes, add a new occurence that points to the existing entry in
-        // the Variables vector.
-        Occurences.emplace_back(KindIndex, Mention);
-        return;
-      }
-    }
-    // If this variable wasn't already referenced, add it to the list of
-    // referenced variables and add a occurence that points to this new entry.
-    Occurences.emplace_back(Variables.size(), Mention);
-    Variables.push_back(VarDecl);
-  }
-
-  /// \brief Adds each referenced variable from the given statement.
-  void addVariables(const Stmt *S) {
-    // Sometimes we get a nullptr (such as from IfStmts which often have nullptr
-    // children). We skip such statements as they don't reference any
-    // variables.
-    if (!S)
-      return;
-
-    // Check if S is a reference to a variable. If yes, add it to the pattern.
-    if (auto D = dyn_cast<DeclRefExpr>(S)) {
-      if (auto VD = dyn_cast<VarDecl>(D->getDecl()->getCanonicalDecl()))
-        addVariableOccurence(VD, D);
-    }
-
-    // Recursively check all children of the given statement.
-    for (const Stmt *Child : S->children()) {
-      addVariables(Child);
-    }
-  }
-
-public:
-  /// \brief Creates an VariablePattern object with information about the given
-  ///        StmtSequence.
-  VariablePattern(const StmtSequence &Sequence) {
-    for (const Stmt *S : Sequence)
-      addVariables(S);
-  }
-
-  /// \brief Counts the differences between this pattern and the given one.
-  /// \param Other The given VariablePattern to compare with.
-  /// \param FirstMismatch Output parameter that will be filled with information
-  ///        about the first difference between the two patterns. This parameter
-  ///        can be a nullptr, in which case it will be ignored.
-  /// \return Returns the number of differences between the pattern this object
-  ///         is following and the given VariablePattern.
-  ///
-  /// For example, the following statements all have the same pattern and this
-  /// function would return zero:
-  ///
-  ///   if (a < b) return a; return b;
-  ///   if (x < y) return x; return y;
-  ///   if (u2 < u1) return u2; return u1;
-  ///
-  /// But the following statement has a different pattern (note the changed
-  /// variables in the return statements) and would have two differences when
-  /// compared with one of the statements above.
-  ///
-  ///   if (a < b) return b; return a;
-  ///
-  /// This function should only be called if the related statements of the given
-  /// pattern and the statements of this objects are clones of each other.
-  unsigned countPatternDifferences(
-      const VariablePattern &Other,
-      CloneDetector::SuspiciousClonePair *FirstMismatch = nullptr) {
-    unsigned NumberOfDifferences = 0;
-
-    assert(Other.Occurences.size() == Occurences.size());
-    for (unsigned i = 0; i < Occurences.size(); ++i) {
-      auto ThisOccurence = Occurences[i];
-      auto OtherOccurence = Other.Occurences[i];
-      if (ThisOccurence.KindID == OtherOccurence.KindID)
-        continue;
-
-      ++NumberOfDifferences;
-
-      // If FirstMismatch is not a nullptr, we need to store information about
-      // the first difference between the two patterns.
-      if (FirstMismatch == nullptr)
-        continue;
-
-      // Only proceed if we just found the first difference as we only store
-      // information about the first difference.
-      if (NumberOfDifferences != 1)
-        continue;
-
-      const VarDecl *FirstSuggestion = nullptr;
-      // If there is a variable available in the list of referenced variables
-      // which wouldn't break the pattern if it is used in place of the
-      // current variable, we provide this variable as the suggested fix.
-      if (OtherOccurence.KindID < Variables.size())
-        FirstSuggestion = Variables[OtherOccurence.KindID];
-
-      // Store information about the first clone.
-      FirstMismatch->FirstCloneInfo =
-          CloneDetector::SuspiciousClonePair::SuspiciousCloneInfo(
-              Variables[ThisOccurence.KindID], ThisOccurence.Mention,
-              FirstSuggestion);
-
-      // Same as above but with the other clone. We do this for both clones as
-      // we don't know which clone is the one containing the unintended
-      // pattern error.
-      const VarDecl *SecondSuggestion = nullptr;
-      if (ThisOccurence.KindID < Other.Variables.size())
-        SecondSuggestion = Other.Variables[ThisOccurence.KindID];
-
-      // Store information about the second clone.
-      FirstMismatch->SecondCloneInfo =
-          CloneDetector::SuspiciousClonePair::SuspiciousCloneInfo(
-              Other.Variables[OtherOccurence.KindID], OtherOccurence.Mention,
-              SecondSuggestion);
-
-      // SuspiciousClonePair guarantees that the first clone always has a
-      // suggested variable associated with it. As we know that one of the two
-      // clones in the pair always has suggestion, we swap the two clones
-      // in case the first clone has no suggested variable which means that
-      // the second clone has a suggested variable and should be first.
-      if (!FirstMismatch->FirstCloneInfo.Suggestion)
-        std::swap(FirstMismatch->FirstCloneInfo,
-                  FirstMismatch->SecondCloneInfo);
-
-      // This ensures that we always have at least one suggestion in a pair.
-      assert(FirstMismatch->FirstCloneInfo.Suggestion);
-    }
-
-    return NumberOfDifferences;
-  }
-};
-}
-
-/// \brief Prints the macro name that contains the given SourceLocation into
-///        the given raw_string_ostream.
+/// Prints the macro name that contains the given SourceLocation into the given
+/// raw_string_ostream.
 static void printMacroName(llvm::raw_string_ostream &MacroStack,
                            ASTContext &Context, SourceLocation Loc) {
   MacroStack << Lexer::getImmediateMacroName(Loc, Context.getSourceManager(),
@@ -258,8 +103,8 @@
   MacroStack << " ";
 }
 
-/// \brief Returns a string that represents all macro expansions that
-///        expanded into the given SourceLocation.
+/// Returns a string that represents all macro expansions that expanded into the
+/// given SourceLocation.
 ///
 /// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
 /// A and B are expanded from the same macros in the same order.
@@ -279,7 +124,9 @@
 }
 
 namespace {
-/// \brief Collects the data of a single Stmt.
+typedef unsigned DataPiece;
+
+/// Collects the data of a single Stmt.
 ///
 /// This class defines what a code clone is: If it collects for two statements
 /// the same data, then those two statements are considered to be clones of each
@@ -292,11 +139,11 @@
 class StmtDataCollector : public ConstStmtVisitor<StmtDataCollector<T>> {
 
   ASTContext &Context;
-  /// \brief The data sink to which all data is forwarded.
+  /// The data sink to which all data is forwarded.
   T &DataConsumer;
 
 public:
-  /// \brief Collects data of the given Stmt.
+  /// Collects data of the given Stmt.
   /// \param S The given statement.
   /// \param Context The ASTContext of S.
   /// \param DataConsumer The data sink to which all data is forwarded.
@@ -307,7 +154,7 @@
 
   // Below are utility methods for appending different data to the vector.
 
-  void addData(CloneDetector::DataPiece Integer) {
+  void addData(DataPiece Integer) {
     DataConsumer.update(
         StringRef(reinterpret_cast<char *>(&Integer), sizeof(Integer)));
   }
@@ -425,7 +272,7 @@
   })
   DEF_ADD_DATA(DeclStmt, {
     auto numDecls = std::distance(S->decl_begin(), S->decl_end());
-    addData(static_cast<CloneDetector::DataPiece>(numDecls));
+    addData(static_cast<DataPiece>(numDecls));
     for (const Decl *D : S->decls()) {
       if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
         addData(VD->getType());
@@ -454,384 +301,44 @@
 };
 } // end anonymous namespace
 
-namespace {
-/// Generates CloneSignatures for a set of statements and stores the results in
-/// a CloneDetector object.
-class CloneSignatureGenerator {
-
-  CloneDetector &CD;
-  ASTContext &Context;
-
-  /// \brief Generates CloneSignatures for all statements in the given statement
-  /// tree and stores them in the CloneDetector.
-  ///
-  /// \param S The root of the given statement tree.
-  /// \param ParentMacroStack A string representing the macros that generated
-  ///                         the parent statement or an empty string if no
-  ///                         macros generated the parent statement.
-  ///                         See getMacroStack() for generating such a string.
-  /// \return The CloneSignature of the root statement.
-  CloneDetector::CloneSignature
-  generateSignatures(const Stmt *S, const std::string &ParentMacroStack) {
-    // Create an empty signature that will be filled in this method.
-    CloneDetector::CloneSignature Signature;
-
-    llvm::MD5 Hash;
-
-    // Collect all relevant data from S and hash it.
-    StmtDataCollector<llvm::MD5>(S, Context, Hash);
-
-    // Look up what macros expanded into the current statement.
-    std::string StartMacroStack = getMacroStack(S->getLocStart(), Context);
-    std::string EndMacroStack = getMacroStack(S->getLocEnd(), Context);
-
-    // First, check if ParentMacroStack is not empty which means we are currently
-    // dealing with a parent statement which was expanded from a macro.
-    // If this parent statement was expanded from the same macros as this
-    // statement, we reduce the initial complexity of this statement to zero.
-    // This causes that a group of statements that were generated by a single
-    // macro expansion will only increase the total complexity by one.
-    // Note: This is not the final complexity of this statement as we still
-    // add the complexity of the child statements to the complexity value.
-    if (!ParentMacroStack.empty() && (StartMacroStack == ParentMacroStack &&
-                                      EndMacroStack == ParentMacroStack)) {
-      Signature.Complexity = 0;
-    }
-
-    // Storage for the signatures of the direct child statements. This is only
-    // needed if the current statement is a CompoundStmt.
-    std::vector<CloneDetector::CloneSignature> ChildSignatures;
-    const CompoundStmt *CS = dyn_cast<const CompoundStmt>(S);
-
-    // The signature of a statement includes the signatures of its children.
-    // Therefore we create the signatures for every child and add them to the
-    // current signature.
-    for (const Stmt *Child : S->children()) {
-      // Some statements like 'if' can have nullptr children that we will skip.
-      if (!Child)
-        continue;
-
-      // Recursive call to create the signature of the child statement. This
-      // will also create and store all clone groups in this child statement.
-      // We pass only the StartMacroStack along to keep things simple.
-      auto ChildSignature = generateSignatures(Child, StartMacroStack);
-
-      // Add the collected data to the signature of the current statement.
-      Signature.Complexity += ChildSignature.Complexity;
-      Hash.update(StringRef(reinterpret_cast<char *>(&ChildSignature.Hash),
-                            sizeof(ChildSignature.Hash)));
-
-      // If the current statement is a CompoundStatement, we need to store the
-      // signature for the generation of the sub-sequences.
-      if (CS)
-        ChildSignatures.push_back(ChildSignature);
-    }
-
-    // If the current statement is a CompoundStmt, we also need to create the
-    // clone groups from the sub-sequences inside the children.
-    if (CS)
-      handleSubSequences(CS, ChildSignatures);
-
-    // Create the final hash code for the current signature.
-    llvm::MD5::MD5Result HashResult;
-    Hash.final(HashResult);
-
-    // Copy as much of the generated hash code to the signature's hash code.
-    std::memcpy(&Signature.Hash, &HashResult,
-                std::min(sizeof(Signature.Hash), sizeof(HashResult)));
-
-    // Save the signature for the current statement in the CloneDetector object.
-    CD.add(StmtSequence(S, Context), Signature);
-
-    return Signature;
-  }
-
-  /// \brief Adds all possible sub-sequences in the child array of the given
-  ///        CompoundStmt to the CloneDetector.
-  /// \param CS The given CompoundStmt.
-  /// \param ChildSignatures A list of calculated signatures for each child in
-  ///                        the given CompoundStmt.
-  void handleSubSequences(
-      const CompoundStmt *CS,
-      const std::vector<CloneDetector::CloneSignature> &ChildSignatures) {
-
-    // FIXME: This function has quadratic runtime right now. Check if skipping
-    // this function for too long CompoundStmts is an option.
-
-    // The length of the sub-sequence. We don't need to handle sequences with
-    // the length 1 as they are already handled in CollectData().
-    for (unsigned Length = 2; Length <= CS->size(); ++Length) {
-      // The start index in the body of the CompoundStmt. We increase the
-      // position until the end of the sub-sequence reaches the end of the
-      // CompoundStmt body.
-      for (unsigned Pos = 0; Pos <= CS->size() - Length; ++Pos) {
-        // Create an empty signature and add the signatures of all selected
-        // child statements to it.
-        CloneDetector::CloneSignature SubSignature;
-        llvm::MD5 SubHash;
-
-        for (unsigned i = Pos; i < Pos + Length; ++i) {
-          SubSignature.Complexity += ChildSignatures[i].Complexity;
-          size_t ChildHash = ChildSignatures[i].Hash;
-
-          SubHash.update(StringRef(reinterpret_cast<char *>(&ChildHash),
-                                sizeof(ChildHash)));
-        }
-
-        // Create the final hash code for the current signature.
-        llvm::MD5::MD5Result HashResult;
-        SubHash.final(HashResult);
-
-        // Copy as much of the generated hash code to the signature's hash code.
-        std::memcpy(&SubSignature.Hash, &HashResult,
-                    std::min(sizeof(SubSignature.Hash), sizeof(HashResult)));
-
-        // Save the signature together with the information about what children
-        // sequence we selected.
-        CD.add(StmtSequence(CS, Context, Pos, Pos + Length), SubSignature);
-      }
-    }
-  }
-
-public:
-  explicit CloneSignatureGenerator(CloneDetector &CD, ASTContext &Context)
-      : CD(CD), Context(Context) {}
-
-  /// \brief Generates signatures for all statements in the given function body.
-  void consumeCodeBody(const Stmt *S) { generateSignatures(S, ""); }
-};
-} // end anonymous namespace
-
 void CloneDetector::analyzeCodeBody(const Decl *D) {
   assert(D);
   assert(D->hasBody());
-  CloneSignatureGenerator Generator(*this, D->getASTContext());
-  Generator.consumeCodeBody(D->getBody());
+
+  Sequences.push_back(StmtSequence(D->getBody(), D));
 }
 
-void CloneDetector::add(const StmtSequence &S,
-                        const CloneSignature &Signature) {
-  Sequences.push_back(std::make_pair(Signature, S));
-}
-
-namespace {
-/// \brief Returns true if and only if \p Stmt contains at least one other
+/// Returns true if and only if \p Stmt contains at least one other
 /// sequence in the \p Group.
-bool containsAnyInGroup(StmtSequence &Stmt, CloneDetector::CloneGroup &Group) {
-  for (StmtSequence &GroupStmt : Group.Sequences) {
-    if (Stmt.contains(GroupStmt))
+static bool containsAnyInGroup(StmtSequence &Seq,
+                               CloneDetector::CloneGroup &Group) {
+  for (StmtSequence &GroupSeq : Group) {
+    if (Seq.contains(GroupSeq))
       return true;
   }
   return false;
 }
 
-/// \brief Returns true if and only if all sequences in \p OtherGroup are
+/// Returns true if and only if all sequences in \p OtherGroup are
 /// contained by a sequence in \p Group.
-bool containsGroup(CloneDetector::CloneGroup &Group,
-                   CloneDetector::CloneGroup &OtherGroup) {
+static bool containsGroup(CloneDetector::CloneGroup &Group,
+                          CloneDetector::CloneGroup &OtherGroup) {
   // We have less sequences in the current group than we have in the other,
   // so we will never fulfill the requirement for returning true. This is only
   // possible because we know that a sequence in Group can contain at most
   // one sequence in OtherGroup.
-  if (Group.Sequences.size() < OtherGroup.Sequences.size())
+  if (Group.size() < OtherGroup.size())
     return false;
 
-  for (StmtSequence &Stmt : Group.Sequences) {
+  for (StmtSequence &Stmt : Group) {
     if (!containsAnyInGroup(Stmt, OtherGroup))
       return false;
   }
   return true;
 }
-} // end anonymous namespace
 
-namespace {
-/// \brief Wrapper around FoldingSetNodeID that it can be used as the template
-///        argument of the StmtDataCollector.
-class FoldingSetNodeIDWrapper {
-
-  llvm::FoldingSetNodeID &FS;
-
-public:
-  FoldingSetNodeIDWrapper(llvm::FoldingSetNodeID &FS) : FS(FS) {}
-
-  void update(StringRef Str) { FS.AddString(Str); }
-};
-} // end anonymous namespace
-
-/// \brief Writes the relevant data from all statements and child statements
-///        in the given StmtSequence into the given FoldingSetNodeID.
-static void CollectStmtSequenceData(const StmtSequence &Sequence,
-                                    FoldingSetNodeIDWrapper &OutputData) {
-  for (const Stmt *S : Sequence) {
-    StmtDataCollector<FoldingSetNodeIDWrapper>(S, Sequence.getASTContext(),
-                                               OutputData);
-
-    for (const Stmt *Child : S->children()) {
-      if (!Child)
-        continue;
-
-      CollectStmtSequenceData(StmtSequence(Child, Sequence.getASTContext()),
-                              OutputData);
-    }
-  }
-}
-
-/// \brief Returns true if both sequences are clones of each other.
-static bool areSequencesClones(const StmtSequence &LHS,
-                               const StmtSequence &RHS) {
-  // We collect the data from all statements in the sequence as we did before
-  // when generating a hash value for each sequence. But this time we don't
-  // hash the collected data and compare the whole data set instead. This
-  // prevents any false-positives due to hash code collisions.
-  llvm::FoldingSetNodeID DataLHS, DataRHS;
-  FoldingSetNodeIDWrapper LHSWrapper(DataLHS);
-  FoldingSetNodeIDWrapper RHSWrapper(DataRHS);
-
-  CollectStmtSequenceData(LHS, LHSWrapper);
-  CollectStmtSequenceData(RHS, RHSWrapper);
-
-  return DataLHS == DataRHS;
-}
-
-/// \brief Finds all actual clone groups in a single group of presumed clones.
-/// \param Result Output parameter to which all found groups are added.
-/// \param Group A group of presumed clones. The clones are allowed to have a
-///              different variable pattern and may not be actual clones of each
-///              other.
-/// \param CheckVariablePattern If true, every clone in a group that was added
-///              to the output follows the same variable pattern as the other
-///              clones in its group.
-static void createCloneGroups(std::vector<CloneDetector::CloneGroup> &Result,
-                              const CloneDetector::CloneGroup &Group,
-                              bool CheckVariablePattern) {
-  // We remove the Sequences one by one, so a list is more appropriate.
-  std::list<StmtSequence> UnassignedSequences(Group.Sequences.begin(),
-                                              Group.Sequences.end());
-
-  // Search for clones as long as there could be clones in UnassignedSequences.
-  while (UnassignedSequences.size() > 1) {
-
-    // Pick the first Sequence as a protoype for a new clone group.
-    StmtSequence Prototype = UnassignedSequences.front();
-    UnassignedSequences.pop_front();
-
-    CloneDetector::CloneGroup FilteredGroup(Prototype, Group.Signature);
-
-    // Analyze the variable pattern of the prototype. Every other StmtSequence
-    // needs to have the same pattern to get into the new clone group.
-    VariablePattern PrototypeFeatures(Prototype);
-
-    // Search all remaining StmtSequences for an identical variable pattern
-    // and assign them to our new clone group.
-    auto I = UnassignedSequences.begin(), E = UnassignedSequences.end();
-    while (I != E) {
-      // If the sequence doesn't fit to the prototype, we have encountered
-      // an unintended hash code collision and we skip it.
-      if (!areSequencesClones(Prototype, *I)) {
-        ++I;
-        continue;
-      }
-
-      // If we weren't asked to check for a matching variable pattern in clone
-      // groups we can add the sequence now to the new clone group.
-      // If we were asked to check for matching variable pattern, we first have
-      // to check that there are no differences between the two patterns and
-      // only proceed if they match.
-      if (!CheckVariablePattern ||
-          VariablePattern(*I).countPatternDifferences(PrototypeFeatures) == 0) {
-        FilteredGroup.Sequences.push_back(*I);
-        I = UnassignedSequences.erase(I);
-        continue;
-      }
-
-      // We didn't found a matching variable pattern, so we continue with the
-      // next sequence.
-      ++I;
-    }
-
-    // Add a valid clone group to the list of found clone groups.
-    if (!FilteredGroup.isValid())
-      continue;
-
-    Result.push_back(FilteredGroup);
-  }
-}
-
-void CloneDetector::findClones(std::vector<CloneGroup> &Result,
-                               unsigned MinGroupComplexity,
-                               bool CheckPatterns) {
-  // A shortcut (and necessary for the for-loop later in this function).
-  if (Sequences.empty())
-    return;
-
-  // We need to search for groups of StmtSequences with the same hash code to
-  // create our initial clone groups. By sorting all known StmtSequences by
-  // their hash value we make sure that StmtSequences with the same hash code
-  // are grouped together in the Sequences vector.
-  // Note: We stable sort here because the StmtSequences are added in the order
-  // in which they appear in the source file. We want to preserve that order
-  // because we also want to report them in that order in the CloneChecker.
-  std::stable_sort(Sequences.begin(), Sequences.end(),
-                   [](std::pair<CloneSignature, StmtSequence> LHS,
-                      std::pair<CloneSignature, StmtSequence> RHS) {
-                     return LHS.first.Hash < RHS.first.Hash;
-                   });
-
-  std::vector<CloneGroup> CloneGroups;
-
-  // Check for each CloneSignature if its successor has the same hash value.
-  // We don't check the last CloneSignature as it has no successor.
-  // Note: The 'size - 1' in the condition is safe because we check for an empty
-  // Sequences vector at the beginning of this function.
-  for (unsigned i = 0; i < Sequences.size() - 1; ++i) {
-    const auto Current = Sequences[i];
-    const auto Next = Sequences[i + 1];
-
-    if (Current.first.Hash != Next.first.Hash)
-      continue;
-
-    // It's likely that we just found an sequence of CloneSignatures that
-    // represent a CloneGroup, so we create a new group and start checking and
-    // adding the CloneSignatures in this sequence.
-    CloneGroup Group;
-    Group.Signature = Current.first;
-
-    for (; i < Sequences.size(); ++i) {
-      const auto &Signature = Sequences[i];
-
-      // A different hash value means we have reached the end of the sequence.
-      if (Current.first.Hash != Signature.first.Hash) {
-        // The current Signature could be the start of a new CloneGroup. So we
-        // decrement i so that we visit it again in the outer loop.
-        // Note: i can never be 0 at this point because we are just comparing
-        // the hash of the Current CloneSignature with itself in the 'if' above.
-        assert(i != 0);
-        --i;
-        break;
-      }
-
-      // Skip CloneSignatures that won't pass the complexity requirement.
-      if (Signature.first.Complexity < MinGroupComplexity)
-        continue;
-
-      Group.Sequences.push_back(Signature.second);
-    }
-
-    // There is a chance that we haven't found more than two fitting
-    // CloneSignature because not enough CloneSignatures passed the complexity
-    // requirement. As a CloneGroup with less than two members makes no sense,
-    // we ignore this CloneGroup and won't add it to the result.
-    if (!Group.isValid())
-      continue;
-
-    CloneGroups.push_back(Group);
-  }
-
-  // Add every valid clone group that fulfills the complexity requirement.
-  for (const CloneGroup &Group : CloneGroups) {
-    createCloneGroups(Result, Group, CheckPatterns);
-  }
-
+void OnlyLargestCloneConstraint::constrain(
+    std::vector<CloneDetector::CloneGroup> &Result) {
   std::vector<unsigned> IndexesToRemove;
 
   // Compare every group in the result with the rest. If one groups contains
@@ -859,36 +366,378 @@
   }
 }
 
-void CloneDetector::findSuspiciousClones(
-    std::vector<CloneDetector::SuspiciousClonePair> &Result,
-    unsigned MinGroupComplexity) {
-  std::vector<CloneGroup> Clones;
-  // Reuse the normal search for clones but specify that the clone groups don't
-  // need to have a common referenced variable pattern so that we can manually
-  // search for the kind of pattern errors this function is supposed to find.
-  findClones(Clones, MinGroupComplexity, false);
+static size_t createHash(llvm::MD5 &Hash) {
+  size_t HashCode;
 
-  for (const CloneGroup &Group : Clones) {
-    for (unsigned i = 0; i < Group.Sequences.size(); ++i) {
-      VariablePattern PatternA(Group.Sequences[i]);
+  // Create the final hash code for the current Stmt.
+  llvm::MD5::MD5Result HashResult;
+  Hash.final(HashResult);
 
-      for (unsigned j = i + 1; j < Group.Sequences.size(); ++j) {
-        VariablePattern PatternB(Group.Sequences[j]);
+  // Copy as much as possible of the generated hash code to the Stmt's hash
+  // code.
+  std::memcpy(&HashCode, &HashResult,
+              std::min(sizeof(HashCode), sizeof(HashResult)));
 
-        CloneDetector::SuspiciousClonePair ClonePair;
-        // For now, we only report clones which break the variable pattern just
-        // once because multiple differences in a pattern are an indicator that
-        // those differences are maybe intended (e.g. because it's actually
-        // a different algorithm).
-        // TODO: In very big clones even multiple variables can be unintended,
-        // so replacing this number with a percentage could better handle such
-        // cases. On the other hand it could increase the false-positive rate
-        // for all clones if the percentage is too high.
-        if (PatternA.countPatternDifferences(PatternB, &ClonePair) == 1) {
-          Result.push_back(ClonePair);
-          break;
+  return HashCode;
+}
+
+size_t RecursiveCloneTypeIIConstraint::saveHash(
+    const Stmt *S, const Decl *D,
+    std::vector<std::pair<size_t, StmtSequence>> &StmtsByHash) {
+  llvm::MD5 Hash;
+  ASTContext &Context = D->getASTContext();
+
+  StmtDataCollector<llvm::MD5>(S, Context, Hash);
+
+  auto CS = dyn_cast<CompoundStmt>(S);
+  SmallVector<size_t, 8> ChildHashes;
+
+  for (const Stmt *Child : S->children()) {
+    if (Child == nullptr) {
+      ChildHashes.push_back(0);
+      continue;
+    }
+    size_t ChildHash = saveHash(Child, D, StmtsByHash);
+    Hash.update(
+        StringRef(reinterpret_cast<char *>(&ChildHash), sizeof(ChildHash)));
+    ChildHashes.push_back(ChildHash);
+  }
+
+  if (CS) {
+    for (unsigned Length = 2; Length <= CS->size(); ++Length) {
+      for (unsigned Pos = 0; Pos <= CS->size() - Length; ++Pos) {
+        llvm::MD5 Hash;
+        for (unsigned i = Pos; i < Pos + Length; ++i) {
+          size_t ChildHash = ChildHashes[i];
+          Hash.update(StringRef(reinterpret_cast<char *>(&ChildHash),
+                                sizeof(ChildHash)));
         }
+        StmtsByHash.push_back(std::make_pair(
+            createHash(Hash), StmtSequence(CS, D, Pos, Pos + Length)));
       }
     }
   }
+
+  size_t HashCode = createHash(Hash);
+  StmtsByHash.push_back(std::make_pair(HashCode, StmtSequence(S, D)));
+  return HashCode;
+}
+
+namespace {
+/// Wrapper around FoldingSetNodeID that it can be used as the template
+/// argument of the StmtDataCollector.
+class FoldingSetNodeIDWrapper {
+
+  llvm::FoldingSetNodeID &FS;
+
+public:
+  FoldingSetNodeIDWrapper(llvm::FoldingSetNodeID &FS) : FS(FS) {}
+
+  void update(StringRef Str) { FS.AddString(Str); }
+};
+} // end anonymous namespace
+
+/// Writes the relevant data from all statements and child statements
+/// in the given StmtSequence into the given FoldingSetNodeID.
+static void CollectStmtSequenceData(const StmtSequence &Sequence,
+                                    FoldingSetNodeIDWrapper &OutputData) {
+  for (const Stmt *S : Sequence) {
+    StmtDataCollector<FoldingSetNodeIDWrapper>(S, Sequence.getASTContext(),
+                                               OutputData);
+
+    for (const Stmt *Child : S->children()) {
+      if (!Child)
+        continue;
+
+      CollectStmtSequenceData(StmtSequence(Child, Sequence.getContainingDecl()),
+                              OutputData);
+    }
+  }
+}
+
+/// Returns true if both sequences are clones of each other.
+static bool areSequencesClones(const StmtSequence &LHS,
+                               const StmtSequence &RHS) {
+  // We collect the data from all statements in the sequence as we did before
+  // when generating a hash value for each sequence. But this time we don't
+  // hash the collected data and compare the whole data set instead. This
+  // prevents any false-positives due to hash code collisions.
+  llvm::FoldingSetNodeID DataLHS, DataRHS;
+  FoldingSetNodeIDWrapper LHSWrapper(DataLHS);
+  FoldingSetNodeIDWrapper RHSWrapper(DataRHS);
+
+  CollectStmtSequenceData(LHS, LHSWrapper);
+  CollectStmtSequenceData(RHS, RHSWrapper);
+
+  return DataLHS == DataRHS;
+}
+
+void RecursiveCloneTypeIIConstraint::constrain(
+    std::vector<CloneDetector::CloneGroup> &Sequences) {
+  // FIXME: Maybe we can do this in-place and don't need this additional vector.
+  std::vector<CloneDetector::CloneGroup> Result;
+
+  for (CloneDetector::CloneGroup &Group : Sequences) {
+    // We assume in the following code that the Group is non-empty, so we
+    // skip all empty groups.
+    if (Group.empty())
+      continue;
+
+    std::vector<std::pair<size_t, StmtSequence>> StmtsByHash;
+
+    // Generate hash codes for all children of S and save them in StmtsByHash.
+    for (const StmtSequence &S : Group) {
+      saveHash(S.front(), S.getContainingDecl(), StmtsByHash);
+    }
+
+    // Sort hash_codes in StmtsByHash.
+    std::stable_sort(StmtsByHash.begin(), StmtsByHash.end(),
+                     [this](std::pair<size_t, StmtSequence> LHS,
+                            std::pair<size_t, StmtSequence> RHS) {
+                       return LHS.first < RHS.first;
+                     });
+
+    // Check for each StmtSequence if its successor has the same hash value.
+    // We don't check the last StmtSequence as it has no successor.
+    // Note: The 'size - 1 ' in the condition is safe because we check for an
+    // empty Group vector at the beginning of this function.
+    for (unsigned i = 0; i < StmtsByHash.size() - 1; ++i) {
+      const auto Current = StmtsByHash[i];
+
+      // It's likely that we just found an sequence of StmtSequences that
+      // represent a CloneGroup, so we create a new group and start checking and
+      // adding the StmtSequences in this sequence.
+      CloneDetector::CloneGroup NewGroup;
+
+      size_t PrototypeHash = Current.first;
+
+      for (; i < StmtsByHash.size(); ++i) {
+        // A different hash value means we have reached the end of the sequence.
+        if (PrototypeHash != StmtsByHash[i].first ||
+            !areSequencesClones(StmtsByHash[i].second, Current.second)) {
+          // The current sequence could be the start of a new CloneGroup. So we
+          // decrement i so that we visit it again in the outer loop.
+          // Note: i can never be 0 at this point because we are just comparing
+          // the hash of the Current StmtSequence with itself in the 'if' above.
+          assert(i != 0);
+          --i;
+          break;
+        }
+        // Same hash value means we should add the StmtSequence to the current
+        // group.
+        NewGroup.push_back(StmtsByHash[i].second);
+      }
+
+      // We created a new clone group with matching hash codes and move it to
+      // the result vector.
+      Result.push_back(NewGroup);
+    }
+  }
+  // Sequences is the output parameter, so we copy our result into it.
+  Sequences = Result;
+}
+
+size_t MinComplexityConstraint::calculateStmtComplexity(
+    const StmtSequence &Seq, const std::string &ParentMacroStack) {
+  if (Seq.empty())
+    return 0;
+
+  size_t Complexity = 1;
+
+  ASTContext &Context = Seq.getASTContext();
+
+  // Look up what macros expanded into the current statement.
+  std::string StartMacroStack = getMacroStack(Seq.getStartLoc(), Context);
+  std::string EndMacroStack = getMacroStack(Seq.getEndLoc(), Context);
+
+  // First, check if ParentMacroStack is not empty which means we are currently
+  // dealing with a parent statement which was expanded from a macro.
+  // If this parent statement was expanded from the same macros as this
+  // statement, we reduce the initial complexity of this statement to zero.
+  // This causes that a group of statements that were generated by a single
+  // macro expansion will only increase the total complexity by one.
+  // Note: This is not the final complexity of this statement as we still
+  // add the complexity of the child statements to the complexity value.
+  if (!ParentMacroStack.empty() && (StartMacroStack == ParentMacroStack &&
+                                    EndMacroStack == ParentMacroStack)) {
+    Complexity = 0;
+  }
+
+  // Iterate over the Stmts in the StmtSequence and add their complexity values
+  // to the current complexity value.
+  if (Seq.holdsSequence()) {
+    for (const Stmt *S : Seq) {
+      Complexity += calculateStmtComplexity(
+          StmtSequence(S, Seq.getContainingDecl()), StartMacroStack);
+    }
+  } else {
+    for (const Stmt *S : Seq.front()->children()) {
+      Complexity += calculateStmtComplexity(
+          StmtSequence(S, Seq.getContainingDecl()), StartMacroStack);
+    }
+  }
+  return Complexity;
+}
+
+void MatchingVariablePatternConstraint::constrain(
+    std::vector<CloneDetector::CloneGroup> &CloneGroups) {
+  CloneConstraint::splitCloneGroups(
+      CloneGroups, [](const StmtSequence &A, const StmtSequence &B) {
+        VariablePattern PatternA(A);
+        VariablePattern PatternB(B);
+        return PatternA.countPatternDifferences(PatternB) == 0;
+      });
+}
+
+void CloneConstraint::splitCloneGroups(
+    std::vector<CloneDetector::CloneGroup> &CloneGroups,
+    std::function<bool(const StmtSequence &, const StmtSequence &)> Compare) {
+  std::vector<CloneDetector::CloneGroup> Result;
+  for (auto &HashGroup : CloneGroups) {
+    // Contains all indexes in HashGroup that were already added to a
+    // CloneGroup.
+    std::vector<char> Indexes;
+    Indexes.resize(HashGroup.size());
+
+    for (unsigned i = 0; i < HashGroup.size(); ++i) {
+      // Skip indexes that are already part of a CloneGroup.
+      if (Indexes[i])
+        continue;
+
+      // Pick the first unhandled StmtSequence and consider it as the
+      // beginning
+      // of a new CloneGroup for now.
+      // We don't add i to Indexes because we never iterate back.
+      StmtSequence Prototype = HashGroup[i];
+      CloneDetector::CloneGroup PotentialGroup = {Prototype};
+      ++Indexes[i];
+
+      // Check all following StmtSequences for clones.
+      for (unsigned j = i + 1; j < HashGroup.size(); ++j) {
+        // Skip indexes that are already part of a CloneGroup.
+        if (Indexes[j])
+          continue;
+
+        // If a following StmtSequence belongs to our CloneGroup, we add it to
+        // it.
+        const StmtSequence &Candidate = HashGroup[j];
+
+        if (!Compare(Prototype, Candidate))
+          continue;
+
+        PotentialGroup.push_back(Candidate);
+        // Make sure we never visit this StmtSequence again.
+        ++Indexes[j];
+      }
+
+      // Otherwise, add it to the result and continue searching for more
+      // groups.
+      Result.push_back(PotentialGroup);
+    }
+
+    assert(std::all_of(Indexes.begin(), Indexes.end(),
+                       [](char c) { return c == 1; }));
+  }
+  CloneGroups = Result;
+}
+
+void VariablePattern::addVariableOccurence(const VarDecl *VarDecl,
+                                           const Stmt *Mention) {
+  // First check if we already reference this variable
+  for (size_t KindIndex = 0; KindIndex < Variables.size(); ++KindIndex) {
+    if (Variables[KindIndex] == VarDecl) {
+      // If yes, add a new occurence that points to the existing entry in
+      // the Variables vector.
+      Occurences.emplace_back(KindIndex, Mention);
+      return;
+    }
+  }
+  // If this variable wasn't already referenced, add it to the list of
+  // referenced variables and add a occurence that points to this new entry.
+  Occurences.emplace_back(Variables.size(), Mention);
+  Variables.push_back(VarDecl);
+}
+
+void VariablePattern::addVariables(const Stmt *S) {
+  // Sometimes we get a nullptr (such as from IfStmts which often have nullptr
+  // children). We skip such statements as they don't reference any
+  // variables.
+  if (!S)
+    return;
+
+  // Check if S is a reference to a variable. If yes, add it to the pattern.
+  if (auto D = dyn_cast<DeclRefExpr>(S)) {
+    if (auto VD = dyn_cast<VarDecl>(D->getDecl()->getCanonicalDecl()))
+      addVariableOccurence(VD, D);
+  }
+
+  // Recursively check all children of the given statement.
+  for (const Stmt *Child : S->children()) {
+    addVariables(Child);
+  }
+}
+
+unsigned VariablePattern::countPatternDifferences(
+    const VariablePattern &Other,
+    VariablePattern::SuspiciousClonePair *FirstMismatch) {
+  unsigned NumberOfDifferences = 0;
+
+  assert(Other.Occurences.size() == Occurences.size());
+  for (unsigned i = 0; i < Occurences.size(); ++i) {
+    auto ThisOccurence = Occurences[i];
+    auto OtherOccurence = Other.Occurences[i];
+    if (ThisOccurence.KindID == OtherOccurence.KindID)
+      continue;
+
+    ++NumberOfDifferences;
+
+    // If FirstMismatch is not a nullptr, we need to store information about
+    // the first difference between the two patterns.
+    if (FirstMismatch == nullptr)
+      continue;
+
+    // Only proceed if we just found the first difference as we only store
+    // information about the first difference.
+    if (NumberOfDifferences != 1)
+      continue;
+
+    const VarDecl *FirstSuggestion = nullptr;
+    // If there is a variable available in the list of referenced variables
+    // which wouldn't break the pattern if it is used in place of the
+    // current variable, we provide this variable as the suggested fix.
+    if (OtherOccurence.KindID < Variables.size())
+      FirstSuggestion = Variables[OtherOccurence.KindID];
+
+    // Store information about the first clone.
+    FirstMismatch->FirstCloneInfo =
+        VariablePattern::SuspiciousClonePair::SuspiciousCloneInfo(
+            Variables[ThisOccurence.KindID], ThisOccurence.Mention,
+            FirstSuggestion);
+
+    // Same as above but with the other clone. We do this for both clones as
+    // we don't know which clone is the one containing the unintended
+    // pattern error.
+    const VarDecl *SecondSuggestion = nullptr;
+    if (ThisOccurence.KindID < Other.Variables.size())
+      SecondSuggestion = Other.Variables[ThisOccurence.KindID];
+
+    // Store information about the second clone.
+    FirstMismatch->SecondCloneInfo =
+        VariablePattern::SuspiciousClonePair::SuspiciousCloneInfo(
+            Other.Variables[OtherOccurence.KindID], OtherOccurence.Mention,
+            SecondSuggestion);
+
+    // SuspiciousClonePair guarantees that the first clone always has a
+    // suggested variable associated with it. As we know that one of the two
+    // clones in the pair always has suggestion, we swap the two clones
+    // in case the first clone has no suggested variable which means that
+    // the second clone has a suggested variable and should be first.
+    if (!FirstMismatch->FirstCloneInfo.Suggestion)
+      std::swap(FirstMismatch->FirstCloneInfo, FirstMismatch->SecondCloneInfo);
+
+    // This ensures that we always have at least one suggestion in a pair.
+    assert(FirstMismatch->FirstCloneInfo.Suggestion);
+  }
+
+  return NumberOfDifferences;
 }
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index a2f3203..60724ea 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -58,6 +58,14 @@
   return false;
 }
 
+static bool isBuiltinUnreachable(const Stmt *S) {
+  if (const auto *DRE = dyn_cast<DeclRefExpr>(S))
+    if (const auto *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl()))
+      return FDecl->getIdentifier() &&
+             FDecl->getBuiltinID() == Builtin::BI__builtin_unreachable;
+  return false;
+}
+
 static bool isDeadReturn(const CFGBlock *B, const Stmt *S) {
   // Look to see if the current control flow ends with a 'return', and see if
   // 'S' is a substatement. The 'return' may not be the last element in the
@@ -132,15 +140,21 @@
   // so that we can refine it later.
   SourceLocation L = S->getLocStart();
   if (L.isMacroID()) {
+    SourceManager &SM = PP.getSourceManager();
     if (IgnoreYES_NO) {
       // The Objective-C constant 'YES' and 'NO'
       // are defined as macros.  Do not treat them
       // as configuration values.
-      SourceManager &SM = PP.getSourceManager();
       SourceLocation TopL = getTopMostMacro(L, SM);
       StringRef MacroName = PP.getImmediateMacroName(TopL);
       if (MacroName == "YES" || MacroName == "NO")
         return false;
+    } else if (!PP.getLangOpts().CPlusPlus) {
+      // Do not treat C 'false' and 'true' macros as configuration values.
+      SourceLocation TopL = getTopMostMacro(L, SM);
+      StringRef MacroName = PP.getImmediateMacroName(TopL);
+      if (MacroName == "false" || MacroName == "true")
+        return false;
     }
     return true;
   }
@@ -586,8 +600,7 @@
 
   if (isa<BreakStmt>(S)) {
     UK = reachable_code::UK_Break;
-  }
-  else if (isTrivialDoWhile(B, S)) {
+  } else if (isTrivialDoWhile(B, S) || isBuiltinUnreachable(S)) {
     return;
   }
   else if (isDeadReturn(B, S)) {
diff --git a/lib/Basic/Attributes.cpp b/lib/Basic/Attributes.cpp
index c215366..b7570d0 100644
--- a/lib/Basic/Attributes.cpp
+++ b/lib/Basic/Attributes.cpp
@@ -1,4 +1,5 @@
 #include "clang/Basic/Attributes.h"
+#include "clang/Basic/AttrSubjectMatchRules.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "llvm/ADT/StringSwitch.h"
 using namespace clang;
@@ -15,3 +16,13 @@
 
   return 0;
 }
+
+const char *attr::getSubjectMatchRuleSpelling(attr::SubjectMatchRule Rule) {
+  switch (Rule) {
+#define ATTR_MATCH_RULE(NAME, SPELLING, IsAbstract)                            \
+  case attr::NAME:                                                             \
+    return SPELLING;
+#include "clang/Basic/AttrSubMatchRulesList.inc"
+  }
+  llvm_unreachable("Invalid subject match rule");
+}
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index 8929ec3..b6a289a 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -74,6 +74,7 @@
   FileSystemStatCache.cpp
   IdentifierTable.cpp
   LangOptions.cpp
+  MemoryBufferCache.cpp
   Module.cpp
   ObjCRuntime.cpp
   OpenMPKinds.cpp
@@ -82,6 +83,7 @@
   Sanitizers.cpp
   SourceLocation.cpp
   SourceManager.cpp
+  SourceMgrAdapter.cpp
   TargetInfo.cpp
   Targets.cpp
   TokenKinds.cpp
diff --git a/lib/Basic/Diagnostic.cpp b/lib/Basic/Diagnostic.cpp
index 7529c47..0c27ae4 100644
--- a/lib/Basic/Diagnostic.cpp
+++ b/lib/Basic/Diagnostic.cpp
@@ -16,6 +16,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/PartialDiagnostic.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/CrashRecoveryContext.h"
@@ -131,13 +132,13 @@
 
   // Clear state related to #pragma diagnostic.
   DiagStates.clear();
-  DiagStatePoints.clear();
+  DiagStatesByLoc.clear();
   DiagStateOnPushStack.clear();
 
   // Create a DiagState and DiagStatePoint representing diagnostic changes
   // through command-line.
   DiagStates.emplace_back();
-  DiagStatePoints.push_back(DiagStatePoint(&DiagStates.back(), FullSourceLoc()));
+  DiagStatesByLoc.appendFirst(&DiagStates.back());
 }
 
 void DiagnosticsEngine::SetDelayedDiagnostic(unsigned DiagID, StringRef Arg1,
@@ -157,27 +158,94 @@
   DelayedDiagArg2.clear();
 }
 
-DiagnosticsEngine::DiagStatePointsTy::iterator
-DiagnosticsEngine::GetDiagStatePointForLoc(SourceLocation L) const {
-  assert(!DiagStatePoints.empty());
-  assert(DiagStatePoints.front().Loc.isInvalid() &&
-         "Should have created a DiagStatePoint for command-line");
+void DiagnosticsEngine::DiagStateMap::appendFirst(
+                                             DiagState *State) {
+  assert(Files.empty() && "not first");
+  FirstDiagState = CurDiagState = State;
+  CurDiagStateLoc = SourceLocation();
+}
 
-  if (!SourceMgr)
-    return DiagStatePoints.end() - 1;
+void DiagnosticsEngine::DiagStateMap::append(SourceManager &SrcMgr,
+                                             SourceLocation Loc,
+                                             DiagState *State) {
+  CurDiagState = State;
+  CurDiagStateLoc = Loc;
 
-  FullSourceLoc Loc(L, *SourceMgr);
-  if (Loc.isInvalid())
-    return DiagStatePoints.end() - 1;
+  std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
+  unsigned Offset = Decomp.second;
+  for (File *F = getFile(SrcMgr, Decomp.first); F;
+       Offset = F->ParentOffset, F = F->Parent) {
+    F->HasLocalTransitions = true;
+    auto &Last = F->StateTransitions.back();
+    assert(Last.Offset <= Offset && "state transitions added out of order");
 
-  DiagStatePointsTy::iterator Pos = DiagStatePoints.end();
-  FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
-  if (LastStateChangePos.isValid() &&
-      Loc.isBeforeInTranslationUnitThan(LastStateChangePos))
-    Pos = std::upper_bound(DiagStatePoints.begin(), DiagStatePoints.end(),
-                           DiagStatePoint(nullptr, Loc));
-  --Pos;
-  return Pos;
+    if (Last.Offset == Offset) {
+      if (Last.State == State)
+        break;
+      Last.State = State;
+      continue;
+    }
+
+    F->StateTransitions.push_back({State, Offset});
+  }
+}
+
+DiagnosticsEngine::DiagState *
+DiagnosticsEngine::DiagStateMap::lookup(SourceManager &SrcMgr,
+                                        SourceLocation Loc) const {
+  // Common case: we have not seen any diagnostic pragmas.
+  if (Files.empty())
+    return FirstDiagState;
+
+  std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedLoc(Loc);
+  const File *F = getFile(SrcMgr, Decomp.first);
+  return F->lookup(Decomp.second);
+}
+
+DiagnosticsEngine::DiagState *
+DiagnosticsEngine::DiagStateMap::File::lookup(unsigned Offset) const {
+  auto OnePastIt = std::upper_bound(
+      StateTransitions.begin(), StateTransitions.end(), Offset,
+      [](unsigned Offset, const DiagStatePoint &P) {
+        return Offset < P.Offset;
+      });
+  assert(OnePastIt != StateTransitions.begin() && "missing initial state");
+  return OnePastIt[-1].State;
+}
+
+DiagnosticsEngine::DiagStateMap::File *
+DiagnosticsEngine::DiagStateMap::getFile(SourceManager &SrcMgr,
+                                         FileID ID) const {
+  // Get or insert the File for this ID.
+  auto Range = Files.equal_range(ID);
+  if (Range.first != Range.second)
+    return &Range.first->second;
+  auto &F = Files.insert(Range.first, std::make_pair(ID, File()))->second;
+
+  // We created a new File; look up the diagnostic state at the start of it and
+  // initialize it.
+  if (ID.isValid()) {
+    std::pair<FileID, unsigned> Decomp = SrcMgr.getDecomposedIncludedLoc(ID);
+    F.Parent = getFile(SrcMgr, Decomp.first);
+    F.ParentOffset = Decomp.second;
+    F.StateTransitions.push_back({F.Parent->lookup(Decomp.second), 0});
+  } else {
+    // This is the (imaginary) root file into which we pretend all top-level
+    // files are included; it descends from the initial state.
+    //
+    // FIXME: This doesn't guarantee that we use the same ordering as
+    // isBeforeInTranslationUnit in the cases where someone invented another
+    // top-level file and added diagnostic pragmas to it. See the code at the
+    // end of isBeforeInTranslationUnit for the quirks it deals with.
+    F.StateTransitions.push_back({FirstDiagState, 0});
+  }
+  return &F;
+}
+
+void DiagnosticsEngine::PushDiagStatePoint(DiagState *State,
+                                           SourceLocation Loc) {
+  assert(Loc.isValid() && "Adding invalid loc point");
+  DiagStatesByLoc.append(*SourceMgr, Loc, State);
 }
 
 void DiagnosticsEngine::setSeverity(diag::kind Diag, diag::Severity Map,
@@ -187,11 +255,8 @@
   assert((Diags->isBuiltinWarningOrExtension(Diag) ||
           (Map == diag::Severity::Fatal || Map == diag::Severity::Error)) &&
          "Cannot map errors into warnings!");
-  assert(!DiagStatePoints.empty());
   assert((L.isInvalid() || SourceMgr) && "No SourceMgr for valid location");
 
-  FullSourceLoc Loc = SourceMgr? FullSourceLoc(L, *SourceMgr) : FullSourceLoc();
-  FullSourceLoc LastStateChangePos = DiagStatePoints.back().Loc;
   // Don't allow a mapping to a warning override an error/fatal mapping.
   if (Map == diag::Severity::Warning) {
     DiagnosticMapping &Info = GetCurDiagState()->getOrAddMapping(Diag);
@@ -202,50 +267,22 @@
   DiagnosticMapping Mapping = makeUserMapping(Map, L);
 
   // Common case; setting all the diagnostics of a group in one place.
-  if (Loc.isInvalid() || Loc == LastStateChangePos) {
-    GetCurDiagState()->setMapping(Diag, Mapping);
+  if ((L.isInvalid() || L == DiagStatesByLoc.getCurDiagStateLoc()) &&
+      DiagStatesByLoc.getCurDiagState()) {
+    // FIXME: This is theoretically wrong: if the current state is shared with
+    // some other location (via push/pop) we will change the state for that
+    // other location as well. This cannot currently happen, as we can't update
+    // the diagnostic state at the same location at which we pop.
+    DiagStatesByLoc.getCurDiagState()->setMapping(Diag, Mapping);
     return;
   }
 
-  // Another common case; modifying diagnostic state in a source location
-  // after the previous one.
-  if ((Loc.isValid() && LastStateChangePos.isInvalid()) ||
-      LastStateChangePos.isBeforeInTranslationUnitThan(Loc)) {
-    // A diagnostic pragma occurred, create a new DiagState initialized with
-    // the current one and a new DiagStatePoint to record at which location
-    // the new state became active.
-    DiagStates.push_back(*GetCurDiagState());
-    PushDiagStatePoint(&DiagStates.back(), Loc);
-    GetCurDiagState()->setMapping(Diag, Mapping);
-    return;
-  }
-
-  // We allow setting the diagnostic state in random source order for
-  // completeness but it should not be actually happening in normal practice.
-
-  DiagStatePointsTy::iterator Pos = GetDiagStatePointForLoc(Loc);
-  assert(Pos != DiagStatePoints.end());
-
-  // Update all diagnostic states that are active after the given location.
-  for (DiagStatePointsTy::iterator
-         I = Pos+1, E = DiagStatePoints.end(); I != E; ++I) {
-    I->State->setMapping(Diag, Mapping);
-  }
-
-  // If the location corresponds to an existing point, just update its state.
-  if (Pos->Loc == Loc) {
-    Pos->State->setMapping(Diag, Mapping);
-    return;
-  }
-
-  // Create a new state/point and fit it into the vector of DiagStatePoints
-  // so that the vector is always ordered according to location.
-  assert(Pos->Loc.isBeforeInTranslationUnitThan(Loc));
-  DiagStates.push_back(*Pos->State);
-  DiagState *NewState = &DiagStates.back();
-  NewState->setMapping(Diag, Mapping);
-  DiagStatePoints.insert(Pos+1, DiagStatePoint(NewState,
-                                               FullSourceLoc(Loc, *SourceMgr)));
+  // A diagnostic pragma occurred, create a new DiagState initialized with
+  // the current one and a new DiagStatePoint to record at which location
+  // the new state became active.
+  DiagStates.push_back(*GetCurDiagState());
+  DiagStates.back().setMapping(Diag, Mapping);
+  PushDiagStatePoint(&DiagStates.back(), L);
 }
 
 bool DiagnosticsEngine::setSeverityForGroup(diag::Flavor Flavor,
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 3c370f6..e0580af 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -411,11 +411,8 @@
   // to error.  Errors can only be mapped to fatal.
   diag::Severity Result = diag::Severity::Fatal;
 
-  DiagnosticsEngine::DiagStatePointsTy::iterator
-    Pos = Diag.GetDiagStatePointForLoc(Loc);
-  DiagnosticsEngine::DiagState *State = Pos->State;
-
   // Get the mapping information, or compute it lazily.
+  DiagnosticsEngine::DiagState *State = Diag.GetDiagStateForLoc(Loc);
   DiagnosticMapping &Mapping = State->getOrAddMapping((diag::kind)DiagID);
 
   // TODO: Can a null severity really get here?
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index af424cd..6f67081 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -42,7 +42,6 @@
   NeedsHandleIdentifier = false;
   IsFromAST = false;
   ChangedAfterLoad = false;
-  FEChangedAfterLoad = false;
   RevertedTokenID = false;
   OutOfDate = false;
   IsModulesImport = false;
@@ -244,7 +243,7 @@
 
 /// \brief Returns true if the identifier represents a keyword in the
 /// specified language.
-bool IdentifierInfo::isKeyword(const LangOptions &LangOpts) {
+bool IdentifierInfo::isKeyword(const LangOptions &LangOpts) const {
   switch (getTokenKwStatus(LangOpts, getTokenID())) {
   case KS_Enabled:
   case KS_Extension:
@@ -254,6 +253,19 @@
   }
 }
 
+/// \brief Returns true if the identifier represents a C++ keyword in the
+/// specified language.
+bool IdentifierInfo::isCPlusPlusKeyword(const LangOptions &LangOpts) const {
+  if (!LangOpts.CPlusPlus || !isKeyword(LangOpts))
+    return false;
+  // This is a C++ keyword if this identifier is not a keyword when checked
+  // using LangOptions without C++ support.
+  LangOptions LangOptsNoCPP = LangOpts;
+  LangOptsNoCPP.CPlusPlus = false;
+  LangOptsNoCPP.CPlusPlus11 = false;
+  return !isKeyword(LangOptsNoCPP);
+}
+
 tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const {
   // We use a perfect hash function here involving the length of the keyword,
   // the first and third character.  For preprocessor ID's there are no
@@ -487,8 +499,10 @@
     if (name == "self") return OMF_self;
     if (name == "initialize") return OMF_initialize;
   }
- 
-  if (name == "performSelector") return OMF_performSelector;
+
+  if (name == "performSelector" || name == "performSelectorInBackground" ||
+      name == "performSelectorOnMainThread")
+    return OMF_performSelector;
 
   // The other method families may begin with a prefix of underscores.
   while (!name.empty() && name.front() == '_')
diff --git a/lib/Basic/MemoryBufferCache.cpp b/lib/Basic/MemoryBufferCache.cpp
new file mode 100644
index 0000000..c1fc571
--- /dev/null
+++ b/lib/Basic/MemoryBufferCache.cpp
@@ -0,0 +1,48 @@
+//===- MemoryBufferCache.cpp - Cache for loaded memory buffers ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/MemoryBufferCache.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace clang;
+
+llvm::MemoryBuffer &
+MemoryBufferCache::addBuffer(llvm::StringRef Filename,
+                             std::unique_ptr<llvm::MemoryBuffer> Buffer) {
+  auto Insertion =
+      Buffers.insert({Filename, BufferEntry{std::move(Buffer), NextIndex++}});
+  assert(Insertion.second && "Already has a buffer");
+  return *Insertion.first->second.Buffer;
+}
+
+llvm::MemoryBuffer *MemoryBufferCache::lookupBuffer(llvm::StringRef Filename) {
+  auto I = Buffers.find(Filename);
+  if (I == Buffers.end())
+    return nullptr;
+  return I->second.Buffer.get();
+}
+
+bool MemoryBufferCache::isBufferFinal(llvm::StringRef Filename) {
+  auto I = Buffers.find(Filename);
+  if (I == Buffers.end())
+    return false;
+  return I->second.Index < FirstRemovableIndex;
+}
+
+bool MemoryBufferCache::tryToRemoveBuffer(llvm::StringRef Filename) {
+  auto I = Buffers.find(Filename);
+  assert(I != Buffers.end() && "No buffer to remove...");
+  if (I->second.Index < FirstRemovableIndex)
+    return true;
+
+  Buffers.erase(I);
+  return false;
+}
+
+void MemoryBufferCache::finalizeCurrentBuffers() { FirstRemovableIndex = NextIndex; }
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index 80bbc24..a410a72 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -27,11 +27,12 @@
 Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
                bool IsFramework, bool IsExplicit, unsigned VisibilityID)
     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(),
-      Umbrella(), Signature(0), ASTFile(nullptr), VisibilityID(VisibilityID),
+      Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID),
       IsMissingRequirement(false), HasIncompatibleModuleFile(false),
       IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
       IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
-      IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
+      IsInferred(false), IsSwiftInferImportAsMember(false),
+      InferSubmodules(false), InferExplicitSubmodules(false),
       InferExportWildcard(false), ConfigMacrosExhaustive(false),
       NoUndeclaredIncludes(false), NameVisibility(Hidden) {
   if (Parent) {
@@ -83,11 +84,16 @@
 
 bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo &Target,
                          Requirement &Req,
-                         UnresolvedHeaderDirective &MissingHeader) const {
+                         UnresolvedHeaderDirective &MissingHeader,
+                         Module *&ShadowingModule) const {
   if (IsAvailable)
     return true;
 
   for (const Module *Current = this; Current; Current = Current->Parent) {
+    if (Current->ShadowingModule) {
+      ShadowingModule = Current->ShadowingModule;
+      return false;
+    }
     for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) {
       if (hasFeature(Current->Requirements[I].first, LangOpts, Target) !=
               Current->Requirements[I].second) {
@@ -341,6 +347,8 @@
       OS << " [system]";
     if (IsExternC)
       OS << " [extern_c]";
+    if (IsSwiftInferImportAsMember)
+      OS << " [swift_infer_import_as_member]";
   }
 
   OS << " {\n";
diff --git a/lib/Basic/SourceMgrAdapter.cpp b/lib/Basic/SourceMgrAdapter.cpp
new file mode 100644
index 0000000..1d52a24
--- /dev/null
+++ b/lib/Basic/SourceMgrAdapter.cpp
@@ -0,0 +1,137 @@
+//=== SourceMgrAdapter.cpp - SourceMgr to SourceManager Adapter -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the adapter that maps diagnostics from llvm::SourceMgr
+// to Clang's SourceManager.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/SourceMgrAdapter.h"
+#include "clang/Basic/Diagnostic.h"
+
+using namespace clang;
+
+void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &diag,
+                                  void *context) {
+  static_cast<SourceMgrAdapter *>(context)->handleDiag(diag);
+}
+
+SourceMgrAdapter::SourceMgrAdapter(SourceManager &srcMgr,
+                                   DiagnosticsEngine &diag,
+                                   unsigned errorDiagID,
+                                   unsigned warningDiagID,
+                                   unsigned noteDiagID,
+                                   const FileEntry *defaultFile)
+  : SrcMgr(srcMgr), Diag(diag), ErrorDiagID(errorDiagID),
+    WarningDiagID(warningDiagID), NoteDiagID(noteDiagID),
+    DefaultFile(defaultFile) { }
+
+SourceMgrAdapter::~SourceMgrAdapter() { }
+
+SourceLocation SourceMgrAdapter::mapLocation(const llvm::SourceMgr &llvmSrcMgr,
+                                             llvm::SMLoc loc) {
+  // Map invalid locations.
+  if (!loc.isValid())
+    return SourceLocation();
+
+  // Find the buffer containing the location.
+  unsigned bufferID = llvmSrcMgr.FindBufferContainingLoc(loc);
+  if (!bufferID)
+    return SourceLocation();
+
+
+  // If we haven't seen this buffer before, copy it over.
+  auto buffer = llvmSrcMgr.getMemoryBuffer(bufferID);
+  auto knownBuffer = FileIDMapping.find(std::make_pair(&llvmSrcMgr, bufferID));
+  if (knownBuffer == FileIDMapping.end()) {
+    FileID fileID;
+    if (DefaultFile) {
+      // Map to the default file.
+      fileID = SrcMgr.createFileID(DefaultFile, SourceLocation(),
+                                   SrcMgr::C_User);
+
+      // Only do this once.
+      DefaultFile = nullptr;
+    } else {
+      // Make a copy of the memory buffer.
+      StringRef bufferName = buffer->getBufferIdentifier();
+      auto bufferCopy
+        = std::unique_ptr<llvm::MemoryBuffer>(
+            llvm::MemoryBuffer::getMemBufferCopy(buffer->getBuffer(),
+                                                 bufferName));
+
+      // Add this memory buffer to the Clang source manager.
+      fileID = SrcMgr.createFileID(std::move(bufferCopy));
+    }
+
+    // Save the mapping.
+    knownBuffer = FileIDMapping.insert(
+                    std::make_pair(std::make_pair(&llvmSrcMgr, bufferID),
+                                   fileID)).first;
+  }
+
+  // Translate the offset into the file.
+  unsigned offset = loc.getPointer() - buffer->getBufferStart();
+  return SrcMgr.getLocForStartOfFile(knownBuffer->second)
+           .getLocWithOffset(offset);
+}
+
+SourceRange SourceMgrAdapter::mapRange(const llvm::SourceMgr &llvmSrcMgr,
+                                       llvm::SMRange range) {
+  if (!range.isValid())
+    return SourceRange();
+
+  SourceLocation start = mapLocation(llvmSrcMgr, range.Start);
+  SourceLocation end = mapLocation(llvmSrcMgr, range.End);
+  return SourceRange(start, end);
+}
+
+void SourceMgrAdapter::handleDiag(const llvm::SMDiagnostic &diag) {
+  // Map the location.
+  SourceLocation loc;
+  if (auto *llvmSrcMgr = diag.getSourceMgr())
+    loc = mapLocation(*llvmSrcMgr, diag.getLoc());
+
+  // Extract the message.
+  StringRef message = diag.getMessage();
+
+  // Map the diagnostic kind.
+  unsigned diagID;
+  switch (diag.getKind()) {
+  case llvm::SourceMgr::DK_Error:
+    diagID = ErrorDiagID;
+    break;
+
+  case llvm::SourceMgr::DK_Warning:
+    diagID = WarningDiagID;
+    break;
+
+  case llvm::SourceMgr::DK_Note:
+    diagID = NoteDiagID;
+    break;
+  }
+
+  // Report the diagnostic.
+  DiagnosticBuilder builder = Diag.Report(loc, diagID) << message;
+
+  if (auto *llvmSrcMgr = diag.getSourceMgr()) {
+    // Translate ranges.
+    SourceLocation startOfLine = loc.getLocWithOffset(-diag.getColumnNo());
+    for (auto range : diag.getRanges()) {
+      builder << SourceRange(startOfLine.getLocWithOffset(range.first),
+                             startOfLine.getLocWithOffset(range.second));
+    }
+
+    // Translate Fix-Its.
+    for (const llvm::SMFixIt &fixIt : diag.getFixIts()) {
+      CharSourceRange range(mapRange(*llvmSrcMgr, fixIt.getRange()), false);
+      builder << FixItHint::CreateReplacement(range, fixIt.getText());
+    }
+  }
+}
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 445b412..8f6be0a 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -117,6 +117,7 @@
                              VersionTuple &PlatformMinVersion) {
   Builder.defineMacro("__APPLE_CC__", "6000");
   Builder.defineMacro("__APPLE__");
+  Builder.defineMacro("__STDC_NO_THREADS__");
   Builder.defineMacro("OBJC_NEW_PROPERTIES");
   // AddressSanitizer doesn't play well with source fortification, which is on
   // by default on Darwin.
@@ -2250,6 +2251,32 @@
     return LangAS::opencl_constant;
   }
 
+  /// \returns Target specific vtbl ptr address space.
+  unsigned getVtblPtrAddressSpace() const override {
+    // \todo: We currently have address spaces defined in AMDGPU Backend. It
+    // would be nice if we could use it here instead of using bare numbers (same
+    // applies to getDWARFAddressSpace).
+    return 2; // constant.
+  }
+
+  /// \returns If a target requires an address within a target specific address
+  /// space \p AddressSpace to be converted in order to be used, then return the
+  /// corresponding target specific DWARF address space.
+  ///
+  /// \returns Otherwise return None and no conversion will be emitted in the
+  /// DWARF.
+  Optional<unsigned> getDWARFAddressSpace(
+      unsigned AddressSpace) const override {
+    switch (AddressSpace) {
+    case 0: // LLVM Private.
+      return 1; // DWARF Private.
+    case 3: // LLVM Local.
+      return 2; // DWARF Local.
+    default:
+      return None;
+    }
+  }
+
   CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
     switch (CC) {
       default:
@@ -8987,11 +9014,19 @@
     return new SPIR64TargetInfo(Triple, Opts);
   }
   case llvm::Triple::wasm32:
-    if (!(Triple == llvm::Triple("wasm32-unknown-unknown")))
+    if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
+        Triple.getVendor() != llvm::Triple::UnknownVendor ||
+        Triple.getOS() != llvm::Triple::UnknownOS ||
+        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment ||
+        !(Triple.isOSBinFormatELF() || Triple.isOSBinFormatWasm()))
       return nullptr;
     return new WebAssemblyOSTargetInfo<WebAssembly32TargetInfo>(Triple, Opts);
   case llvm::Triple::wasm64:
-    if (!(Triple == llvm::Triple("wasm64-unknown-unknown")))
+    if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
+        Triple.getVendor() != llvm::Triple::UnknownVendor ||
+        Triple.getOS() != llvm::Triple::UnknownOS ||
+        Triple.getEnvironment() != llvm::Triple::UnknownEnvironment ||
+        !(Triple.isOSBinFormatELF() || Triple.isOSBinFormatWasm()))
       return nullptr;
     return new WebAssemblyOSTargetInfo<WebAssembly64TargetInfo>(Triple, Opts);
 
diff --git a/lib/Basic/VirtualFileSystem.cpp b/lib/Basic/VirtualFileSystem.cpp
index 50fcb22..f346b01 100644
--- a/lib/Basic/VirtualFileSystem.cpp
+++ b/lib/Basic/VirtualFileSystem.cpp
@@ -257,8 +257,7 @@
     if (!EC && Iter != llvm::sys::fs::directory_iterator()) {
       llvm::sys::fs::file_status S;
       EC = Iter->status(S);
-      if (!EC)
-        CurrentEntry = Status::copyWithNewName(S, Iter->path());
+      CurrentEntry = Status::copyWithNewName(S, Iter->path());
     }
   }
 
@@ -1869,7 +1868,7 @@
                                                            std::error_code &EC)
     : FS(&FS_) {
   directory_iterator I = FS->dir_begin(Path, EC);
-  if (!EC && I != directory_iterator()) {
+  if (I != directory_iterator()) {
     State = std::make_shared<IterState>();
     State->push(I);
   }
@@ -1882,8 +1881,6 @@
   vfs::directory_iterator End;
   if (State->top()->isDirectory()) {
     vfs::directory_iterator I = FS->dir_begin(State->top()->getName(), EC);
-    if (EC)
-      return *this;
     if (I != End) {
       State->push(I);
       return *this;
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index dfd819a..574c511 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_subdirectory(Headers)
 add_subdirectory(Basic)
+add_subdirectory(APINotes)
 add_subdirectory(Lex)
 add_subdirectory(Parse)
 add_subdirectory(AST)
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index d2ce6ea..eb6a80a 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -557,14 +557,16 @@
           .Default(llvm::FloatABI::Default);
 
   // Set FP fusion mode.
-  switch (CodeGenOpts.getFPContractMode()) {
-  case CodeGenOptions::FPC_Off:
-    Options.AllowFPOpFusion = llvm::FPOpFusion::Strict;
-    break;
-  case CodeGenOptions::FPC_On:
+  switch (LangOpts.getDefaultFPContractMode()) {
+  case LangOptions::FPC_Off:
+    // Preserve any contraction performed by the front-end.  (Strict performs
+    // splitting of the muladd instrinsic in the backend.)
     Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
     break;
-  case CodeGenOptions::FPC_Fast:
+  case LangOptions::FPC_On:
+    Options.AllowFPOpFusion = llvm::FPOpFusion::Standard;
+    break;
+  case LangOptions::FPC_Fast:
     Options.AllowFPOpFusion = llvm::FPOpFusion::Fast;
     break;
   }
@@ -996,6 +998,7 @@
     return "__LLVM,__bitcode";
   case Triple::COFF:
   case Triple::ELF:
+  case Triple::Wasm:
   case Triple::UnknownObjectFormat:
     return ".llvmbc";
   }
@@ -1008,6 +1011,7 @@
     return "__LLVM,__cmdline";
   case Triple::COFF:
   case Triple::ELF:
+  case Triple::Wasm:
   case Triple::UnknownObjectFormat:
     return ".llvmcmd";
   }
diff --git a/lib/CodeGen/CGAtomic.cpp b/lib/CodeGen/CGAtomic.cpp
index 9287e46..28e20b5 100644
--- a/lib/CodeGen/CGAtomic.cpp
+++ b/lib/CodeGen/CGAtomic.cpp
@@ -1181,7 +1181,7 @@
   if (LVal.isBitField())
     return CGF.EmitLoadOfBitfieldLValue(
         LValue::MakeBitfield(addr, LVal.getBitFieldInfo(), LVal.getType(),
-                             LVal.getAlignmentSource()));
+                             LVal.getAlignmentSource()), loc);
   if (LVal.isVectorElt())
     return CGF.EmitLoadOfLValue(
         LValue::MakeVectorElt(addr, LVal.getVectorIdx(), LVal.getType(),
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index b250b9a..372d23c 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -16,7 +16,7 @@
 #include "CGObjCRuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/IR/CallSite.h"
@@ -318,6 +318,19 @@
   elementTypes.push_back(CGM.getBlockDescriptorType());
 }
 
+static QualType getCaptureFieldType(const CodeGenFunction &CGF,
+                                    const BlockDecl::Capture &CI) {
+  const VarDecl *VD = CI.getVariable();
+
+  // If the variable is captured by an enclosing block or lambda expression,
+  // use the type of the capture field.
+  if (CGF.BlockInfo && CI.isNested())
+    return CGF.BlockInfo->getCapture(VD).fieldType();
+  if (auto *FD = CGF.LambdaCaptureFields.lookup(VD))
+    return FD->getType();
+  return VD->getType();
+}
+
 /// Compute the layout of the given block.  Attempts to lay the block
 /// out with minimal space requirements.
 static void computeBlockInfo(CodeGenModule &CGM, CodeGenFunction *CGF,
@@ -432,15 +445,7 @@
       }
     }
 
-    QualType VT = variable->getType();
-
-    // If the variable is captured by an enclosing block or lambda expression,
-    // use the type of the capture field.
-    if (CGF->BlockInfo && CI.isNested())
-      VT = CGF->BlockInfo->getCapture(variable).fieldType();
-    else if (auto *FD = CGF->LambdaCaptureFields.lookup(variable))
-      VT = FD->getType();
-
+    QualType VT = getCaptureFieldType(*CGF, CI);
     CharUnits size = C.getTypeSizeInChars(VT);
     CharUnits align = C.getDeclAlign(variable);
     
@@ -606,8 +611,8 @@
     if (capture.isConstant()) continue;
 
     // Ignore objects that aren't destructed.
-    QualType::DestructionKind dtorKind =
-      variable->getType().isDestructedType();
+    QualType VT = getCaptureFieldType(CGF, CI);
+    QualType::DestructionKind dtorKind = VT.isDestructedType();
     if (dtorKind == QualType::DK_none) continue;
 
     CodeGenFunction::Destroyer *destroyer;
@@ -634,7 +639,7 @@
     if (useArrayEHCleanup) 
       cleanupKind = InactiveNormalAndEHCleanup;
 
-    CGF.pushDestroy(cleanupKind, addr, variable->getType(),
+    CGF.pushDestroy(cleanupKind, addr, VT,
                     destroyer, useArrayEHCleanup);
 
     // Remember where that cleanup was.
diff --git a/lib/CodeGen/CGCUDANV.cpp b/lib/CodeGen/CGCUDANV.cpp
index 83febcb..813cd74 100644
--- a/lib/CodeGen/CGCUDANV.cpp
+++ b/lib/CodeGen/CGCUDANV.cpp
@@ -15,7 +15,7 @@
 #include "CGCUDARuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/Decl.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/CallSite.h"
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index c7c61e0..a5e50b7 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -2858,19 +2858,7 @@
 
   llvm::Instruction *Ret;
   if (RV) {
-    if (CurCodeDecl && SanOpts.has(SanitizerKind::ReturnsNonnullAttribute)) {
-      if (auto RetNNAttr = CurCodeDecl->getAttr<ReturnsNonNullAttr>()) {
-        SanitizerScope SanScope(this);
-        llvm::Value *Cond = Builder.CreateICmpNE(
-            RV, llvm::Constant::getNullValue(RV->getType()));
-        llvm::Constant *StaticData[] = {
-            EmitCheckSourceLocation(EndLoc),
-            EmitCheckSourceLocation(RetNNAttr->getLocation()),
-        };
-        EmitCheck(std::make_pair(Cond, SanitizerKind::ReturnsNonnullAttribute),
-                  SanitizerHandler::NonnullReturn, StaticData, None);
-      }
-    }
+    EmitReturnValueCheck(RV, EndLoc);
     Ret = Builder.CreateRet(RV);
   } else {
     Ret = Builder.CreateRetVoid();
@@ -2880,6 +2868,63 @@
     Ret->setDebugLoc(std::move(RetDbgLoc));
 }
 
+void CodeGenFunction::EmitReturnValueCheck(llvm::Value *RV,
+                                           SourceLocation EndLoc) {
+  // A current decl may not be available when emitting vtable thunks.
+  if (!CurCodeDecl)
+    return;
+
+  ReturnsNonNullAttr *RetNNAttr = nullptr;
+  if (SanOpts.has(SanitizerKind::ReturnsNonnullAttribute))
+    RetNNAttr = CurCodeDecl->getAttr<ReturnsNonNullAttr>();
+
+  if (!RetNNAttr && !requiresReturnValueNullabilityCheck())
+    return;
+
+  // Prefer the returns_nonnull attribute if it's present.
+  SourceLocation AttrLoc;
+  SanitizerMask CheckKind;
+  SanitizerHandler Handler;
+  if (RetNNAttr) {
+    assert(!requiresReturnValueNullabilityCheck() &&
+           "Cannot check nullability and the nonnull attribute");
+    AttrLoc = RetNNAttr->getLocation();
+    CheckKind = SanitizerKind::ReturnsNonnullAttribute;
+    Handler = SanitizerHandler::NonnullReturn;
+  } else {
+    if (auto *DD = dyn_cast<DeclaratorDecl>(CurCodeDecl))
+      if (auto *TSI = DD->getTypeSourceInfo())
+        if (auto FTL = TSI->getTypeLoc().castAs<FunctionTypeLoc>())
+          AttrLoc = FTL.getReturnLoc().findNullabilityLoc();
+    CheckKind = SanitizerKind::NullabilityReturn;
+    Handler = SanitizerHandler::NullabilityReturn;
+  }
+
+  SanitizerScope SanScope(this);
+
+  llvm::BasicBlock *Check = nullptr;
+  llvm::BasicBlock *NoCheck = nullptr;
+  if (requiresReturnValueNullabilityCheck()) {
+    // Before doing the nullability check, make sure that the preconditions for
+    // the check are met.
+    Check = createBasicBlock("nullcheck");
+    NoCheck = createBasicBlock("no.nullcheck");
+    Builder.CreateCondBr(RetValNullabilityPrecondition, Check, NoCheck);
+    EmitBlock(Check);
+  }
+
+  // Now do the null check. If the returns_nonnull attribute is present, this
+  // is done unconditionally.
+  llvm::Value *Cond = Builder.CreateIsNotNull(RV);
+  llvm::Constant *StaticData[] = {
+      EmitCheckSourceLocation(EndLoc), EmitCheckSourceLocation(AttrLoc),
+  };
+  EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, None);
+
+  if (requiresReturnValueNullabilityCheck())
+    EmitBlock(NoCheck);
+}
+
 static bool isInAllocaArgument(CGCXXABI &ABI, QualType type) {
   const CXXRecordDecl *RD = type->getAsCXXRecordDecl();
   return RD && ABI.getRecordArgABI(RD) == CGCXXABI::RAA_DirectInMemory;
@@ -3188,40 +3233,67 @@
 
 void CodeGenFunction::EmitNonNullArgCheck(RValue RV, QualType ArgType,
                                           SourceLocation ArgLoc,
-                                          const FunctionDecl *FD,
+                                          AbstractCallee AC,
                                           unsigned ParmNum) {
-  if (!SanOpts.has(SanitizerKind::NonnullAttribute) || !FD)
+  if (!AC.getDecl() || !(SanOpts.has(SanitizerKind::NonnullAttribute) ||
+                         SanOpts.has(SanitizerKind::NullabilityArg)))
     return;
-  auto PVD = ParmNum < FD->getNumParams() ? FD->getParamDecl(ParmNum) : nullptr;
+
+  // The param decl may be missing in a variadic function.
+  auto PVD = ParmNum < AC.getNumParams() ? AC.getParamDecl(ParmNum) : nullptr;
   unsigned ArgNo = PVD ? PVD->getFunctionScopeIndex() : ParmNum;
-  auto NNAttr = getNonNullAttr(FD, PVD, ArgType, ArgNo);
-  if (!NNAttr)
+
+  // Prefer the nonnull attribute if it's present. 
+  const NonNullAttr *NNAttr = nullptr;
+  if (SanOpts.has(SanitizerKind::NonnullAttribute))
+    NNAttr = getNonNullAttr(AC.getDecl(), PVD, ArgType, ArgNo);
+
+  bool CanCheckNullability = false;
+  if (SanOpts.has(SanitizerKind::NullabilityArg) && !NNAttr && PVD) {
+    auto Nullability = PVD->getType()->getNullability(getContext());
+    CanCheckNullability = Nullability &&
+                          *Nullability == NullabilityKind::NonNull &&
+                          PVD->getTypeSourceInfo();
+  }
+
+  if (!NNAttr && !CanCheckNullability)
     return;
+
+  SourceLocation AttrLoc;
+  SanitizerMask CheckKind;
+  SanitizerHandler Handler;
+  if (NNAttr) {
+    AttrLoc = NNAttr->getLocation();
+    CheckKind = SanitizerKind::NonnullAttribute;
+    Handler = SanitizerHandler::NonnullArg;
+  } else {
+    AttrLoc = PVD->getTypeSourceInfo()->getTypeLoc().findNullabilityLoc();
+    CheckKind = SanitizerKind::NullabilityArg;
+    Handler = SanitizerHandler::NullabilityArg;
+  }
+
   SanitizerScope SanScope(this);
   assert(RV.isScalar());
   llvm::Value *V = RV.getScalarVal();
   llvm::Value *Cond =
       Builder.CreateICmpNE(V, llvm::Constant::getNullValue(V->getType()));
   llvm::Constant *StaticData[] = {
-      EmitCheckSourceLocation(ArgLoc),
-      EmitCheckSourceLocation(NNAttr->getLocation()),
+      EmitCheckSourceLocation(ArgLoc), EmitCheckSourceLocation(AttrLoc),
       llvm::ConstantInt::get(Int32Ty, ArgNo + 1),
   };
-  EmitCheck(std::make_pair(Cond, SanitizerKind::NonnullAttribute),
-            SanitizerHandler::NonnullArg, StaticData, None);
+  EmitCheck(std::make_pair(Cond, CheckKind), Handler, StaticData, None);
 }
 
 void CodeGenFunction::EmitCallArgs(
     CallArgList &Args, ArrayRef<QualType> ArgTypes,
     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
-    const FunctionDecl *CalleeDecl, unsigned ParamsToSkip,
-    EvaluationOrder Order) {
+    AbstractCallee AC, unsigned ParamsToSkip, EvaluationOrder Order) {
   assert((int)ArgTypes.size() == (ArgRange.end() - ArgRange.begin()));
 
   auto MaybeEmitImplicitObjectSize = [&](unsigned I, const Expr *Arg) {
-    if (CalleeDecl == nullptr || I >= CalleeDecl->getNumParams())
+    if (!AC.hasFunctionDecl() || I >= AC.getNumParams())
       return;
-    auto *PS = CalleeDecl->getParamDecl(I)->getAttr<PassObjectSizeAttr>();
+    auto *PS = AC.getParamDecl(I)->getAttr<PassObjectSizeAttr>();
     if (PS == nullptr)
       return;
 
@@ -3262,7 +3334,7 @@
     if (!LeftToRight) MaybeEmitImplicitObjectSize(Idx, *Arg);
     EmitCallArg(Args, *Arg, ArgTypes[Idx]);
     EmitNonNullArgCheck(Args.back().RV, ArgTypes[Idx], (*Arg)->getExprLoc(),
-                        CalleeDecl, ParamsToSkip + Idx);
+                        AC, ParamsToSkip + Idx);
     if (LeftToRight) MaybeEmitImplicitObjectSize(Idx, *Arg);
   }
 
diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 05d0567..c7e33f6 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -309,8 +309,10 @@
   // just do a bitcast; null checks are unnecessary.
   if (NonVirtualOffset.isZero() && !VBase) {
     if (sanitizePerformTypeCheck()) {
+      SanitizerSet SkippedChecks;
+      SkippedChecks.set(SanitizerKind::Null, !NullCheckValue);
       EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(),
-                    DerivedTy, DerivedAlign, !NullCheckValue);
+                    DerivedTy, DerivedAlign, SkippedChecks);
     }
     return Builder.CreateBitCast(Value, BasePtrTy);
   }
@@ -331,8 +333,10 @@
   }
 
   if (sanitizePerformTypeCheck()) {
+    SanitizerSet SkippedChecks;
+    SkippedChecks.set(SanitizerKind::Null, true);
     EmitTypeCheck(VBase ? TCK_UpcastToVirtualBase : TCK_Upcast, Loc,
-                  Value.getPointer(), DerivedTy, DerivedAlign, true);
+                  Value.getPointer(), DerivedTy, DerivedAlign, SkippedChecks);
   }
 
   // Compute the virtual offset.
@@ -685,7 +689,8 @@
 /// complete-to-base constructor delegation optimization, i.e.
 /// emitting the complete constructor as a simple call to the base
 /// constructor.
-static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor) {
+bool CodeGenFunction::IsConstructorDelegationValid(
+    const CXXConstructorDecl *Ctor) {
 
   // Currently we disable the optimization for classes with virtual
   // bases because (1) the addresses of parameter variables need to be
@@ -2102,7 +2107,9 @@
 void CodeGenFunction::EmitInlinedInheritingCXXConstructorCall(
     const CXXConstructorDecl *Ctor, CXXCtorType CtorType, bool ForVirtualBase,
     bool Delegating, CallArgList &Args) {
-  InlinedInheritingConstructorScope Scope(*this, GlobalDecl(Ctor, CtorType));
+  GlobalDecl GD(Ctor, CtorType);
+  InlinedInheritingConstructorScope Scope(*this, GD);
+  ApplyInlineDebugLocation DebugScope(*this, GD);
 
   // Save the arguments to be passed to the inherited constructor.
   CXXInheritedCtorInitExprArgs = Args;
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 12a6803..d58c3cc 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -107,8 +107,8 @@
 
   // Construct a location that has a valid scope, but no line info.
   assert(!DI->LexicalBlockStack.empty());
-  CGF->Builder.SetCurrentDebugLocation(
-      llvm::DebugLoc::get(0, 0, DI->LexicalBlockStack.back()));
+  CGF->Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
+      0, 0, DI->LexicalBlockStack.back(), DI->getInlinedAt()));
 }
 
 ApplyDebugLocation::ApplyDebugLocation(CodeGenFunction &CGF, const Expr *E)
@@ -134,6 +134,30 @@
     CGF->Builder.SetCurrentDebugLocation(std::move(OriginalLocation));
 }
 
+ApplyInlineDebugLocation::ApplyInlineDebugLocation(CodeGenFunction &CGF,
+                                                   GlobalDecl InlinedFn)
+    : CGF(&CGF) {
+  if (!CGF.getDebugInfo()) {
+    this->CGF = nullptr;
+    return;
+  }
+  auto &DI = *CGF.getDebugInfo();
+  SavedLocation = DI.getLocation();
+  assert((DI.getInlinedAt() ==
+          CGF.Builder.getCurrentDebugLocation()->getInlinedAt()) &&
+         "CGDebugInfo and IRBuilder are out of sync");
+
+  DI.EmitInlineFunctionStart(CGF.Builder, InlinedFn);
+}
+
+ApplyInlineDebugLocation::~ApplyInlineDebugLocation() {
+  if (!CGF)
+    return;
+  auto &DI = *CGF->getDebugInfo();
+  DI.EmitInlineFunctionEnd(CGF->Builder);
+  DI.EmitLocation(CGF->Builder, SavedLocation);
+}
+
 void CGDebugInfo::setLocation(SourceLocation Loc) {
   // If the new location isn't valid return.
   if (Loc.isInvalid())
@@ -185,7 +209,7 @@
 
   // Check namespace.
   if (const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
-    return getOrCreateNameSpace(NSDecl);
+    return getOrCreateNamespace(NSDecl);
 
   if (const auto *RDecl = dyn_cast<RecordDecl>(Context))
     if (!RDecl->isDependentType())
@@ -249,8 +273,8 @@
          << OC->getIdentifier()->getNameStart() << ')';
     }
   } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
-    OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '('
-       << OCD->getIdentifier()->getNameStart() << ')';
+    OS << OCD->getClassInterface()->getName() << '('
+       << OCD->getName() << ')';
   } else if (isa<ObjCProtocolDecl>(DC)) {
     // We can extract the type of the class from the self pointer.
     if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
@@ -793,17 +817,19 @@
   // Bit size, align and offset of the type.
   // Size is always the size of a pointer. We can't use getTypeSize here
   // because that does not return the correct value for references.
-  unsigned AS = CGM.getContext().getTargetAddressSpace(PointeeTy);
-  uint64_t Size = CGM.getTarget().getPointerWidth(AS);
+  unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(PointeeTy);
+  uint64_t Size = CGM.getTarget().getPointerWidth(AddressSpace);
   auto Align = getTypeAlignIfRequired(Ty, CGM.getContext());
+  Optional<unsigned> DWARFAddressSpace =
+      CGM.getTarget().getDWARFAddressSpace(AddressSpace);
 
   if (Tag == llvm::dwarf::DW_TAG_reference_type ||
       Tag == llvm::dwarf::DW_TAG_rvalue_reference_type)
     return DBuilder.createReferenceType(Tag, getOrCreateType(PointeeTy, Unit),
-                                        Size, Align);
+                                        Size, Align, DWARFAddressSpace);
   else
     return DBuilder.createPointerType(getOrCreateType(PointeeTy, Unit), Size,
-                                      Align);
+                                      Align, DWARFAddressSpace);
 }
 
 llvm::DIType *CGDebugInfo::getOrCreateStructPtrType(StringRef Name,
@@ -1608,8 +1634,13 @@
   llvm::DITypeRefArray SElements = DBuilder.getOrCreateTypeArray(STy);
   llvm::DIType *SubTy = DBuilder.createSubroutineType(SElements);
   unsigned Size = Context.getTypeSize(Context.VoidPtrTy);
+  unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
+  Optional<unsigned> DWARFAddressSpace =
+      CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
+
   llvm::DIType *vtbl_ptr_type =
-      DBuilder.createPointerType(SubTy, Size, 0, "__vtbl_ptr_type");
+      DBuilder.createPointerType(SubTy, Size, 0, DWARFAddressSpace,
+                                 "__vtbl_ptr_type");
   VTablePtrType = DBuilder.createPointerType(vtbl_ptr_type, Size);
   return VTablePtrType;
 }
@@ -1648,10 +1679,14 @@
     unsigned VSlotCount =
         VFTLayout.vtable_components().size() - CGM.getLangOpts().RTTIData;
     unsigned VTableWidth = PtrWidth * VSlotCount;
+    unsigned VtblPtrAddressSpace = CGM.getTarget().getVtblPtrAddressSpace();
+    Optional<unsigned> DWARFAddressSpace =
+        CGM.getTarget().getDWARFAddressSpace(VtblPtrAddressSpace);
 
     // Create a very wide void* type and insert it directly in the element list.
     llvm::DIType *VTableType =
-        DBuilder.createPointerType(nullptr, VTableWidth, 0, "__vtbl_ptr_type");
+        DBuilder.createPointerType(nullptr, VTableWidth, 0, DWARFAddressSpace,
+                                   "__vtbl_ptr_type");
     EltTys.push_back(VTableType);
 
     // The vptr is a pointer to this special vtable type.
@@ -2009,7 +2044,11 @@
   if (CreateSkeletonCU && IsRootModule) {
     // PCH files don't have a signature field in the control block,
     // but LLVM detects skeleton CUs by looking for a non-zero DWO id.
-    uint64_t Signature = Mod.getSignature() ? Mod.getSignature() : ~1ULL;
+    // We use the lower 64 bits for debug info.
+    uint64_t Signature =
+        Mod.getSignature()
+            ? (uint64_t)Mod.getSignature()[1] << 32 | Mod.getSignature()[0]
+            : ~1ULL;
     llvm::DIBuilder DIB(CGM.getModule());
     DIB.createCompileUnit(TheCU->getSourceLanguage(),
                           DIB.createFile(Mod.getModuleName(), Mod.getPath()),
@@ -2783,7 +2822,7 @@
   if (DebugKind >= codegenoptions::LimitedDebugInfo) {
     if (const NamespaceDecl *NSDecl =
         dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))
-      FDContext = getOrCreateNameSpace(NSDecl);
+      FDContext = getOrCreateNamespace(NSDecl);
     else if (const RecordDecl *RDecl =
              dyn_cast_or_null<RecordDecl>(FD->getDeclContext())) {
       llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
@@ -2844,28 +2883,40 @@
  VDContext = getContextDescriptor(cast<Decl>(DC), Mod ? Mod : TheCU);
 }
 
-llvm::DISubprogram *
-CGDebugInfo::getFunctionForwardDeclaration(const FunctionDecl *FD) {
+llvm::DISubprogram *CGDebugInfo::getFunctionFwdDeclOrStub(GlobalDecl GD,
+                                                          bool Stub) {
   llvm::DINodeArray TParamsArray;
   StringRef Name, LinkageName;
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
-  SourceLocation Loc = FD->getLocation();
+  SourceLocation Loc = GD.getDecl()->getLocation();
   llvm::DIFile *Unit = getOrCreateFile(Loc);
   llvm::DIScope *DContext = Unit;
   unsigned Line = getLineNumber(Loc);
-
-  collectFunctionDeclProps(FD, Unit, Name, LinkageName, DContext,
+  collectFunctionDeclProps(GD, Unit, Name, LinkageName, DContext,
                            TParamsArray, Flags);
+  auto *FD = dyn_cast<FunctionDecl>(GD.getDecl());
+
   // Build function type.
   SmallVector<QualType, 16> ArgTypes;
-  for (const ParmVarDecl *Parm: FD->parameters())
-    ArgTypes.push_back(Parm->getType());
+  if (FD)
+    for (const ParmVarDecl *Parm : FD->parameters())
+      ArgTypes.push_back(Parm->getType());
   CallingConv CC = FD->getType()->castAs<FunctionType>()->getCallConv();
   QualType FnType = CGM.getContext().getFunctionType(
       FD->getReturnType(), ArgTypes, FunctionProtoType::ExtProtoInfo(CC));
+  if (Stub) {
+    return DBuilder.createFunction(
+        DContext, Name, LinkageName, Unit, Line,
+        getOrCreateFunctionType(GD.getDecl(), FnType, Unit),
+        !FD->isExternallyVisible(),
+        /* isDefinition = */ true, 0, Flags, CGM.getLangOpts().Optimize,
+        TParamsArray.get(), getFunctionDeclaration(FD));
+  }
+
   llvm::DISubprogram *SP = DBuilder.createTempFunctionFwdDecl(
       DContext, Name, LinkageName, Unit, Line,
-      getOrCreateFunctionType(FD, FnType, Unit), !FD->isExternallyVisible(),
+      getOrCreateFunctionType(GD.getDecl(), FnType, Unit),
+      !FD->isExternallyVisible(),
       /* isDefinition = */ false, 0, Flags, CGM.getLangOpts().Optimize,
       TParamsArray.get(), getFunctionDeclaration(FD));
   const auto *CanonDecl = cast<FunctionDecl>(FD->getCanonicalDecl());
@@ -2875,6 +2926,16 @@
   return SP;
 }
 
+llvm::DISubprogram *
+CGDebugInfo::getFunctionForwardDeclaration(GlobalDecl GD) {
+  return getFunctionFwdDeclOrStub(GD, /* Stub = */ false);
+}
+
+llvm::DISubprogram *
+CGDebugInfo::getFunctionStub(GlobalDecl GD) {
+  return getFunctionFwdDeclOrStub(GD, /* Stub = */ true);
+}
+
 llvm::DIGlobalVariable *
 CGDebugInfo::getGlobalVariableForwardDeclaration(const VarDecl *VD) {
   QualType T;
@@ -3146,6 +3207,27 @@
       TParamsArray.get(), getFunctionDeclaration(D)));
 }
 
+void CGDebugInfo::EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD) {
+  const auto *FD = cast<FunctionDecl>(GD.getDecl());
+  // If there is a subprogram for this function available then use it.
+  auto FI = SPCache.find(FD->getCanonicalDecl());
+  llvm::DISubprogram *SP = nullptr;
+  if (FI != SPCache.end())
+    SP = dyn_cast_or_null<llvm::DISubprogram>(FI->second);
+  if (!SP)
+    SP = getFunctionStub(GD);
+  FnBeginRegionCount.push_back(LexicalBlockStack.size());
+  LexicalBlockStack.emplace_back(SP);
+  setInlinedAt(Builder.getCurrentDebugLocation());
+  EmitLocation(Builder, FD->getLocation());
+}
+
+void CGDebugInfo::EmitInlineFunctionEnd(CGBuilderTy &Builder) {
+  assert(CurInlinedAt && "unbalanced inline scope stack");
+  EmitFunctionEnd(Builder);
+  setInlinedAt(llvm::DebugLoc(CurInlinedAt).getInlinedAt());
+}
+
 void CGDebugInfo::EmitLocation(CGBuilderTy &Builder, SourceLocation Loc) {
   // Update our current location
   setLocation(Loc);
@@ -3155,7 +3237,7 @@
 
   llvm::MDNode *Scope = LexicalBlockStack.back();
   Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
-      getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope));
+      getLineNumber(CurLoc), getColumnNumber(CurLoc), Scope, CurInlinedAt));
 }
 
 void CGDebugInfo::CreateLexicalBlock(SourceLocation Loc) {
@@ -3167,14 +3249,29 @@
       getColumnNumber(CurLoc)));
 }
 
+void CGDebugInfo::AppendAddressSpaceXDeref(
+    unsigned AddressSpace,
+    SmallVectorImpl<int64_t> &Expr) const {
+  Optional<unsigned> DWARFAddressSpace =
+      CGM.getTarget().getDWARFAddressSpace(AddressSpace);
+  if (!DWARFAddressSpace)
+    return;
+
+  Expr.push_back(llvm::dwarf::DW_OP_constu);
+  Expr.push_back(DWARFAddressSpace.getValue());
+  Expr.push_back(llvm::dwarf::DW_OP_swap);
+  Expr.push_back(llvm::dwarf::DW_OP_xderef);
+}
+
 void CGDebugInfo::EmitLexicalBlockStart(CGBuilderTy &Builder,
                                         SourceLocation Loc) {
   // Set our current location.
   setLocation(Loc);
 
   // Emit a line table change for the current location inside the new scope.
-  Builder.SetCurrentDebugLocation(llvm::DebugLoc::get(
-      getLineNumber(Loc), getColumnNumber(Loc), LexicalBlockStack.back()));
+  Builder.SetCurrentDebugLocation(
+      llvm::DebugLoc::get(getLineNumber(Loc), getColumnNumber(Loc),
+                          LexicalBlockStack.back(), CurInlinedAt));
 
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
     return;
@@ -3316,30 +3413,33 @@
     Line = getLineNumber(VD->getLocation());
     Column = getColumnNumber(VD->getLocation());
   }
-  SmallVector<int64_t, 9> Expr;
+  SmallVector<int64_t, 13> Expr;
   llvm::DINode::DIFlags Flags = llvm::DINode::FlagZero;
   if (VD->isImplicit())
     Flags |= llvm::DINode::FlagArtificial;
 
   auto Align = getDeclAlignIfRequired(VD, CGM.getContext());
 
+  unsigned AddressSpace = CGM.getContext().getTargetAddressSpace(VD->getType());
+  AppendAddressSpaceXDeref(AddressSpace, Expr);
+
   // If this is the first argument and it is implicit then
   // give it an object pointer flag.
   // FIXME: There has to be a better way to do this, but for static
   // functions there won't be an implicit param at arg1 and
   // otherwise it is 'self' or 'this'.
   if (isa<ImplicitParamDecl>(VD) && ArgNo && *ArgNo == 1)
-    Flags |= llvm::DINode::FlagObjectPointer;
-  if (auto *Arg = dyn_cast<llvm::Argument>(Storage))
-    if (Arg->getType()->isPointerTy() && !Arg->hasByValAttr() &&
-        !VD->getType()->isPointerType())
-      Expr.push_back(llvm::dwarf::DW_OP_deref);
+  Flags |= llvm::DINode::FlagObjectPointer;
 
+  // Note: Older versions of clang used to emit byval references with an extra
+  // DW_OP_deref, because they referenced the IR arg directly instead of
+  // referencing an alloca. Newer versions of LLVM don't treat allocas
+  // differently from other function arguments when used in a dbg.declare.
   auto *Scope = cast<llvm::DIScope>(LexicalBlockStack.back());
-
   StringRef Name = VD->getName();
   if (!Name.empty()) {
     if (VD->hasAttr<BlocksAttr>()) {
+      // Here, we need an offset *into* the alloca.
       CharUnits offset = CharUnits::fromQuantity(32);
       Expr.push_back(llvm::dwarf::DW_OP_plus);
       // offset of __forwarding field
@@ -3351,21 +3451,7 @@
       // offset of x field
       offset = CGM.getContext().toCharUnitsFromBits(XOffset);
       Expr.push_back(offset.getQuantity());
-
-      // Create the descriptor for the variable.
-      auto *D = ArgNo
-                    ? DBuilder.createParameterVariable(Scope, VD->getName(),
-                                                       *ArgNo, Unit, Line, Ty)
-                    : DBuilder.createAutoVariable(Scope, VD->getName(), Unit,
-                                                  Line, Ty, Align);
-
-      // Insert an llvm.dbg.declare into the current block.
-      DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
-                             llvm::DebugLoc::get(Line, Column, Scope),
-                             Builder.GetInsertBlock());
-      return;
-    } else if (isa<VariableArrayType>(VD->getType()))
-      Expr.push_back(llvm::dwarf::DW_OP_deref);
+    }
   } else if (const auto *RT = dyn_cast<RecordType>(VD->getType())) {
     // If VD is an anonymous union then Storage represents value for
     // all union fields.
@@ -3393,9 +3479,10 @@
             Flags | llvm::DINode::FlagArtificial, FieldAlign);
 
         // Insert an llvm.dbg.declare into the current block.
-        DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
-                               llvm::DebugLoc::get(Line, Column, Scope),
-                               Builder.GetInsertBlock());
+        DBuilder.insertDeclare(
+            Storage, D, DBuilder.createExpression(Expr),
+            llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
+            Builder.GetInsertBlock());
       }
     }
   }
@@ -3411,7 +3498,7 @@
 
   // Insert an llvm.dbg.declare into the current block.
   DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(Expr),
-                         llvm::DebugLoc::get(Line, Column, Scope),
+                         llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
                          Builder.GetInsertBlock());
 }
 
@@ -3467,8 +3554,7 @@
           ->getElementOffset(blockInfo.getCapture(VD).getIndex()));
 
   SmallVector<int64_t, 9> addr;
-  if (isa<llvm::AllocaInst>(Storage))
-    addr.push_back(llvm::dwarf::DW_OP_deref);
+  addr.push_back(llvm::dwarf::DW_OP_deref);
   addr.push_back(llvm::dwarf::DW_OP_plus);
   addr.push_back(offset.getQuantity());
   if (isByRef) {
@@ -3492,13 +3578,13 @@
       Line, Ty, false, llvm::DINode::FlagZero, Align);
 
   // Insert an llvm.dbg.declare into the current block.
-  auto DL = llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back());
+  auto DL =
+      llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back(), CurInlinedAt);
+  auto *Expr = DBuilder.createExpression(addr);
   if (InsertPoint)
-    DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(addr), DL,
-                           InsertPoint);
+    DBuilder.insertDeclare(Storage, D, Expr, DL, InsertPoint);
   else
-    DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(addr), DL,
-                           Builder.GetInsertBlock());
+    DBuilder.insertDeclare(Storage, D, Expr, DL, Builder.GetInsertBlock());
 }
 
 void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,
@@ -3660,12 +3746,13 @@
     // Insert an llvm.dbg.value into the current block.
     DBuilder.insertDbgValueIntrinsic(
         LocalAddr, 0, debugVar, DBuilder.createExpression(),
-        llvm::DebugLoc::get(line, column, scope), Builder.GetInsertBlock());
+        llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
+        Builder.GetInsertBlock());
   }
 
   // Insert an llvm.dbg.declare into the current block.
   DBuilder.insertDeclare(Arg, debugVar, DBuilder.createExpression(),
-                         llvm::DebugLoc::get(line, column, scope),
+                         llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
                          Builder.GetInsertBlock());
 }
 
@@ -3747,9 +3834,16 @@
     GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
   } else {
     auto Align = getDeclAlignIfRequired(D, CGM.getContext());
+
+    SmallVector<int64_t, 4> Expr;
+    unsigned AddressSpace =
+        CGM.getContext().getTargetAddressSpace(D->getType());
+    AppendAddressSpaceXDeref(AddressSpace, Expr);
+
     GVE = DBuilder.createGlobalVariableExpression(
         DContext, DeclName, LinkageName, Unit, LineNo, getOrCreateType(T, Unit),
-        Var->hasLocalLinkage(), /*Expr=*/nullptr,
+        Var->hasLocalLinkage(),
+        Expr.empty() ? nullptr : DBuilder.createExpression(Expr),
         getOrCreateStaticDataMemberDeclarationOrNull(D), Align);
     Var->addDebugInfo(GVE);
   }
@@ -3828,7 +3922,7 @@
       CGM.getCodeGenOpts().DebugExplicitImport) {
     DBuilder.createImportedModule(
         getCurrentContextDescriptor(cast<Decl>(UD.getDeclContext())),
-        getOrCreateNameSpace(NSDecl),
+        getOrCreateNamespace(NSDecl),
         getLineNumber(UD.getLocation()));
   }
 }
@@ -3888,25 +3982,26 @@
   else
     R = DBuilder.createImportedDeclaration(
         getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
-        getOrCreateNameSpace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
+        getOrCreateNamespace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
         getLineNumber(NA.getLocation()), NA.getName());
   VH.reset(R);
   return R;
 }
 
 llvm::DINamespace *
-CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) {
-  NSDecl = NSDecl->getCanonicalDecl();
-  auto I = NameSpaceCache.find(NSDecl);
-  if (I != NameSpaceCache.end())
+CGDebugInfo::getOrCreateNamespace(const NamespaceDecl *NSDecl) {
+  // Don't canonicalize the NamespaceDecl here: The DINamespace will be uniqued
+  // if necessary, and this way multiple declarations of the same namespace in
+  // different parent modules stay distinct.
+  auto I = NamespaceCache.find(NSDecl);
+  if (I != NamespaceCache.end())
     return cast<llvm::DINamespace>(I->second);
 
-  unsigned LineNo = getLineNumber(NSDecl->getLocation());
-  llvm::DIFile *FileD = getOrCreateFile(NSDecl->getLocation());
   llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
-  llvm::DINamespace *NS = DBuilder.createNameSpace(
-      Context, NSDecl->getName(), FileD, LineNo, NSDecl->isInline());
-  NameSpaceCache[NSDecl].reset(NS);
+  // Don't trust the context if it is a DIModule (see comment above).
+  llvm::DINamespace *NS =
+      DBuilder.createNameSpace(Context, NSDecl->getName(), NSDecl->isInline());
+  NamespaceCache[NSDecl].reset(NS);
   return NS;
 }
 
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index ac2e8dd..2c70732 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -61,6 +61,7 @@
   ModuleMap *ClangModuleMap = nullptr;
   ExternalASTSource::ASTSourceDescriptor PCHDescriptor;
   SourceLocation CurLoc;
+  llvm::MDNode *CurInlinedAt = nullptr;
   llvm::DIType *VTablePtrType = nullptr;
   llvm::DIType *ClassTy = nullptr;
   llvm::DICompositeType *ObjTy = nullptr;
@@ -124,7 +125,7 @@
   /// Cache declarations relevant to DW_TAG_imported_declarations (C++
   /// using declarations) that aren't covered by other more specific caches.
   llvm::DenseMap<const Decl *, llvm::TrackingMDRef> DeclCache;
-  llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NameSpaceCache;
+  llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NamespaceCache;
   llvm::DenseMap<const NamespaceAliasDecl *, llvm::TrackingMDRef>
       NamespaceAliasCache;
   llvm::DenseMap<const Decl *, llvm::TypedTrackingMDRef<llvm::DIDerivedType>>
@@ -193,8 +194,9 @@
   getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile *F);
   /// \return debug info descriptor for vtable.
   llvm::DIType *getOrCreateVTablePtrType(llvm::DIFile *F);
+
   /// \return namespace descriptor for the given namespace decl.
-  llvm::DINamespace *getOrCreateNameSpace(const NamespaceDecl *N);
+  llvm::DINamespace *getOrCreateNamespace(const NamespaceDecl *N);
   llvm::DIType *CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty,
                                       QualType PointeeTy, llvm::DIFile *F);
   llvm::DIType *getOrCreateStructPtrType(StringRef Name, llvm::DIType *&Cache);
@@ -292,6 +294,15 @@
   /// Create a new lexical block node and push it on the stack.
   void CreateLexicalBlock(SourceLocation Loc);
 
+  /// If target-specific LLVM \p AddressSpace directly maps to target-specific
+  /// DWARF address space, appends extended dereferencing mechanism to complex
+  /// expression \p Expr. Otherwise, does nothing.
+  ///
+  /// Extended dereferencing mechanism is has the following format:
+  ///     DW_OP_constu <DWARF Address Space> DW_OP_swap DW_OP_xderef
+  void AppendAddressSpaceXDeref(unsigned AddressSpace,
+                                SmallVectorImpl<int64_t> &Expr) const;
+
 public:
   CGDebugInfo(CodeGenModule &CGM);
   ~CGDebugInfo();
@@ -320,6 +331,17 @@
   /// ignored.
   void setLocation(SourceLocation Loc);
 
+  /// Return the current source location. This does not necessarily correspond
+  /// to the IRBuilder's current DebugLoc.
+  SourceLocation getLocation() const { return CurLoc; }
+
+  /// Update the current inline scope. All subsequent calls to \p EmitLocation
+  /// will create a location with this inlinedAt field.
+  void setInlinedAt(llvm::MDNode *InlinedAt) { CurInlinedAt = InlinedAt; }
+
+  /// \return the current inline scope.
+  llvm::MDNode *getInlinedAt() const { return CurInlinedAt; }
+
   // Converts a SourceLocation to a DebugLoc
   llvm::DebugLoc SourceLocToDebugLoc(SourceLocation Loc);
 
@@ -336,6 +358,11 @@
                          SourceLocation ScopeLoc, QualType FnType,
                          llvm::Function *Fn, CGBuilderTy &Builder);
 
+  /// Start a new scope for an inlined function.
+  void EmitInlineFunctionStart(CGBuilderTy &Builder, GlobalDecl GD);
+  /// End an inlined function scope.
+  void EmitInlineFunctionEnd(CGBuilderTy &Builder);
+
   /// Emit debug info for a function declaration.
   void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType);
 
@@ -491,11 +518,18 @@
   llvm::DIDerivedType *
   getOrCreateStaticDataMemberDeclarationOrNull(const VarDecl *D);
 
-  /// Create a subprogram describing the forward declaration
-  /// represented in the given FunctionDecl.
-  llvm::DISubprogram *getFunctionForwardDeclaration(const FunctionDecl *FD);
+  /// Helper that either creates a forward declaration or a stub.
+  llvm::DISubprogram *getFunctionFwdDeclOrStub(GlobalDecl GD, bool Stub);
 
-  /// Create a global variable describing the forward decalration
+  /// Create a subprogram describing the forward declaration
+  /// represented in the given FunctionDecl wrapped in a GlobalDecl.
+  llvm::DISubprogram *getFunctionForwardDeclaration(GlobalDecl GD);
+
+  /// Create a DISubprogram describing the function
+  /// represented in the given FunctionDecl wrapped in a GlobalDecl.
+  llvm::DISubprogram *getFunctionStub(GlobalDecl GD);
+
+  /// Create a global variable describing the forward declaration
   /// represented in the given VarDecl.
   llvm::DIGlobalVariable *
   getGlobalVariableForwardDeclaration(const VarDecl *VD);
@@ -622,6 +656,20 @@
 
 };
 
+/// A scoped helper to set the current debug location to an inlined location.
+class ApplyInlineDebugLocation {
+  SourceLocation SavedLocation;
+  CodeGenFunction *CGF;
+
+public:
+  /// Set up the CodeGenFunction's DebugInfo to produce inline locations for the
+  /// function \p InlinedFn. The current debug location becomes the inlined call
+  /// site of the inlined function.
+  ApplyInlineDebugLocation(CodeGenFunction &CGF, GlobalDecl InlinedFn);
+  /// Restore everything back to the orginial state.
+  ~ApplyInlineDebugLocation();
+};
+
 } // namespace CodeGen
 } // namespace clang
 
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 0a88b23..b3529f7 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -671,6 +671,27 @@
   lvalue.setAddress(CGF.emitBlockByrefAddress(lvalue.getAddress(), var));
 }
 
+void CodeGenFunction::EmitNullabilityCheck(LValue LHS, llvm::Value *RHS,
+                                           SourceLocation Loc) {
+  if (!SanOpts.has(SanitizerKind::NullabilityAssign))
+    return;
+
+  auto Nullability = LHS.getType()->getNullability(getContext());
+  if (!Nullability || *Nullability != NullabilityKind::NonNull)
+    return;
+
+  // Check if the right hand side of the assignment is nonnull, if the left
+  // hand side must be nonnull.
+  SanitizerScope SanScope(this);
+  llvm::Value *IsNotNull = Builder.CreateIsNotNull(RHS);
+  llvm::Constant *StaticData[] = {
+      EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(LHS.getType()),
+      llvm::ConstantInt::get(Int8Ty, 0), //< The LogAlignment info is unused.
+      llvm::ConstantInt::get(Int8Ty, TCK_NonnullAssign)};
+  EmitCheck({{IsNotNull, SanitizerKind::NullabilityAssign}},
+            SanitizerHandler::TypeMismatch, StaticData, RHS);
+}
+
 void CodeGenFunction::EmitScalarInit(const Expr *init, const ValueDecl *D,
                                      LValue lvalue, bool capturedByInit) {
   Qualifiers::ObjCLifetime lifetime = lvalue.getObjCLifetime();
@@ -678,6 +699,7 @@
     llvm::Value *value = EmitScalarExpr(init);
     if (capturedByInit)
       drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
+    EmitNullabilityCheck(lvalue, value, init->getExprLoc());
     EmitStoreThroughLValue(RValue::get(value), lvalue, true);
     return;
   }
@@ -766,6 +788,8 @@
 
   if (capturedByInit) drillIntoBlockVariable(*this, lvalue, cast<VarDecl>(D));
 
+  EmitNullabilityCheck(lvalue, value, init->getExprLoc());
+
   // If the variable might have been accessed by its initializer, we
   // might have to initialize with a barrier.  We have to do this for
   // both __weak and __strong, but __weak got filtered out above.
@@ -1022,11 +1046,21 @@
       // Emit a lifetime intrinsic if meaningful. There's no point in doing this
       // if we don't have a valid insertion point (?).
       if (HaveInsertPoint() && !IsMSCatchParam) {
-        // goto or switch-case statements can break lifetime into several
-        // regions which need more efforts to handle them correctly. PR28267
-        // This is rare case, but it's better just omit intrinsics than have
-        // them incorrectly placed.
-        if (!Bypasses.IsBypassed(&D)) {
+        // If there's a jump into the lifetime of this variable, its lifetime
+        // gets broken up into several regions in IR, which requires more work
+        // to handle correctly. For now, just omit the intrinsics; this is a
+        // rare case, and it's better to just be conservatively correct.
+        // PR28267.
+        //
+        // We have to do this in all language modes if there's a jump past the
+        // declaration. We also have to do it in C if there's a jump to an
+        // earlier point in the current block because non-VLA lifetimes begin as
+        // soon as the containing block is entered, not when its variables
+        // actually come into scope; suppressing the lifetime annotations
+        // completely in this case is unnecessarily pessimistic, but again, this
+        // is rare.
+        if (!Bypasses.IsBypassed(&D) &&
+            !(!getLangOpts().CPlusPlus && hasLabelBeenSeenInCurrentScope())) {
           uint64_t size = CGM.getDataLayout().getTypeAllocSize(allocaTy);
           emission.SizeForLifetimeMarkers =
               EmitLifetimeStart(size, address.getPointer());
@@ -1083,6 +1117,12 @@
   if (D.hasAttr<AnnotateAttr>())
     EmitVarAnnotations(&D, address.getPointer());
 
+  // Make sure we call @llvm.lifetime.end.
+  if (emission.useLifetimeMarkers())
+    EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker,
+                                         emission.getAllocatedAddress(),
+                                         emission.getSizeForLifetimeMarkers());
+
   return emission;
 }
 
@@ -1373,13 +1413,6 @@
 
   const VarDecl &D = *emission.Variable;
 
-  // Make sure we call @llvm.lifetime.end.  This needs to happen
-  // *last*, so the cleanup needs to be pushed *first*.
-  if (emission.useLifetimeMarkers())
-    EHStack.pushCleanup<CallLifetimeEnd>(NormalEHLifetimeMarker,
-                                         emission.getAllocatedAddress(),
-                                         emission.getSizeForLifetimeMarkers());
-
   // Check the type for a cleanup.
   if (QualType::DestructionKind dtorKind = D.getType().isDestructedType())
     emitAutoVarTypeCleanup(emission, dtorKind);
@@ -1869,6 +1902,19 @@
 
   if (D.hasAttr<AnnotateAttr>())
     EmitVarAnnotations(&D, DeclPtr.getPointer());
+
+  // We can only check return value nullability if all arguments to the
+  // function satisfy their nullability preconditions. This makes it necessary
+  // to emit null checks for args in the function body itself.
+  if (requiresReturnValueNullabilityCheck()) {
+    auto Nullability = Ty->getNullability(getContext());
+    if (Nullability && *Nullability == NullabilityKind::NonNull) {
+      SanitizerScope SanScope(this);
+      RetValNullabilityPrecondition =
+          Builder.CreateAnd(RetValNullabilityPrecondition,
+                            Builder.CreateIsNotNull(Arg.getAnyValue()));
+    }
+  }
 }
 
 void CodeGenModule::EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index e5e34a5..e46fe21 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -534,7 +534,8 @@
 
 void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
                                     llvm::Value *Ptr, QualType Ty,
-                                    CharUnits Alignment, bool SkipNullCheck) {
+                                    CharUnits Alignment,
+                                    SanitizerSet SkippedChecks) {
   if (!sanitizePerformTypeCheck())
     return;
 
@@ -549,26 +550,42 @@
   SmallVector<std::pair<llvm::Value *, SanitizerMask>, 3> Checks;
   llvm::BasicBlock *Done = nullptr;
 
+  // Quickly determine whether we have a pointer to an alloca. It's possible
+  // to skip null checks, and some alignment checks, for these pointers. This
+  // can reduce compile-time significantly.
+  auto PtrToAlloca =
+      dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases());
+
   bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
                            TCK == TCK_UpcastToVirtualBase;
   if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
-      !SkipNullCheck) {
+      !SkippedChecks.has(SanitizerKind::Null) && !PtrToAlloca) {
     // The glvalue must not be an empty glvalue.
     llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);
 
-    if (AllowNullPointers) {
-      // When performing pointer casts, it's OK if the value is null.
-      // Skip the remaining checks in that case.
-      Done = createBasicBlock("null");
-      llvm::BasicBlock *Rest = createBasicBlock("not.null");
-      Builder.CreateCondBr(IsNonNull, Rest, Done);
-      EmitBlock(Rest);
-    } else {
-      Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
+    // The IR builder can constant-fold the null check if the pointer points to
+    // a constant.
+    bool PtrIsNonNull =
+        IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext());
+
+    // Skip the null check if the pointer is known to be non-null.
+    if (!PtrIsNonNull) {
+      if (AllowNullPointers) {
+        // When performing pointer casts, it's OK if the value is null.
+        // Skip the remaining checks in that case.
+        Done = createBasicBlock("null");
+        llvm::BasicBlock *Rest = createBasicBlock("not.null");
+        Builder.CreateCondBr(IsNonNull, Rest, Done);
+        EmitBlock(Rest);
+      } else {
+        Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
+      }
     }
   }
 
-  if (SanOpts.has(SanitizerKind::ObjectSize) && !Ty->isIncompleteType()) {
+  if (SanOpts.has(SanitizerKind::ObjectSize) &&
+      !SkippedChecks.has(SanitizerKind::ObjectSize) &&
+      !Ty->isIncompleteType()) {
     uint64_t Size = getContext().getTypeSizeInChars(Ty).getQuantity();
 
     // The glvalue must refer to a large enough storage region.
@@ -587,13 +604,15 @@
 
   uint64_t AlignVal = 0;
 
-  if (SanOpts.has(SanitizerKind::Alignment)) {
+  if (SanOpts.has(SanitizerKind::Alignment) &&
+      !SkippedChecks.has(SanitizerKind::Alignment)) {
     AlignVal = Alignment.getQuantity();
     if (!Ty->isIncompleteType() && !AlignVal)
       AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity();
 
     // The glvalue must be suitably aligned.
-    if (AlignVal) {
+    if (AlignVal > 1 &&
+        (!PtrToAlloca || PtrToAlloca->getAlignment() < AlignVal)) {
       llvm::Value *Align =
           Builder.CreateAnd(Builder.CreatePtrToInt(Ptr, IntPtrTy),
                             llvm::ConstantInt::get(IntPtrTy, AlignVal - 1));
@@ -624,6 +643,7 @@
   //       or call a non-static member function
   CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
   if (SanOpts.has(SanitizerKind::Vptr) &&
+      !SkippedChecks.has(SanitizerKind::Vptr) &&
       (TCK == TCK_MemberAccess || TCK == TCK_MemberCall ||
        TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||
        TCK == TCK_UpcastToVirtualBase) &&
@@ -947,15 +967,47 @@
                         E->getType());
 }
 
+bool CodeGenFunction::IsWrappedCXXThis(const Expr *Obj) {
+  const Expr *Base = Obj;
+  while (!isa<CXXThisExpr>(Base)) {
+    // The result of a dynamic_cast can be null.
+    if (isa<CXXDynamicCastExpr>(Base))
+      return false;
+
+    if (const auto *CE = dyn_cast<CastExpr>(Base)) {
+      Base = CE->getSubExpr();
+    } else if (const auto *PE = dyn_cast<ParenExpr>(Base)) {
+      Base = PE->getSubExpr();
+    } else if (const auto *UO = dyn_cast<UnaryOperator>(Base)) {
+      if (UO->getOpcode() == UO_Extension)
+        Base = UO->getSubExpr();
+      else
+        return false;
+    } else {
+      return false;
+    }
+  }
+  return true;
+}
+
 LValue CodeGenFunction::EmitCheckedLValue(const Expr *E, TypeCheckKind TCK) {
   LValue LV;
   if (SanOpts.has(SanitizerKind::ArrayBounds) && isa<ArraySubscriptExpr>(E))
     LV = EmitArraySubscriptExpr(cast<ArraySubscriptExpr>(E), /*Accessed*/true);
   else
     LV = EmitLValue(E);
-  if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple())
+  if (!isa<DeclRefExpr>(E) && !LV.isBitField() && LV.isSimple()) {
+    SanitizerSet SkippedChecks;
+    if (const auto *ME = dyn_cast<MemberExpr>(E)) {
+      bool IsBaseCXXThis = IsWrappedCXXThis(ME->getBase());
+      if (IsBaseCXXThis)
+        SkippedChecks.set(SanitizerKind::Alignment, true);
+      if (IsBaseCXXThis || isa<DeclRefExpr>(ME->getBase()))
+        SkippedChecks.set(SanitizerKind::Null, true);
+    }
     EmitTypeCheck(TCK, E->getExprLoc(), LV.getPointer(),
-                  E->getType(), LV.getAlignment());
+                  E->getType(), LV.getAlignment(), SkippedChecks);
+  }
   return LV;
 }
 
@@ -1265,6 +1317,53 @@
   return MDHelper.createRange(Min, End);
 }
 
+bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
+                                           SourceLocation Loc) {
+  bool HasBoolCheck = SanOpts.has(SanitizerKind::Bool);
+  bool HasEnumCheck = SanOpts.has(SanitizerKind::Enum);
+  if (!HasBoolCheck && !HasEnumCheck)
+    return false;
+
+  bool IsBool = hasBooleanRepresentation(Ty) ||
+                NSAPI(CGM.getContext()).isObjCBOOLType(Ty);
+  bool NeedsBoolCheck = HasBoolCheck && IsBool;
+  bool NeedsEnumCheck = HasEnumCheck && Ty->getAs<EnumType>();
+  if (!NeedsBoolCheck && !NeedsEnumCheck)
+    return false;
+
+  // Single-bit booleans don't need to be checked. Special-case this to avoid
+  // a bit width mismatch when handling bitfield values. This is handled by
+  // EmitFromMemory for the non-bitfield case.
+  if (IsBool &&
+      cast<llvm::IntegerType>(Value->getType())->getBitWidth() == 1)
+    return false;
+
+  llvm::APInt Min, End;
+  if (!getRangeForType(*this, Ty, Min, End, /*StrictEnums=*/true, IsBool))
+    return true;
+
+  SanitizerScope SanScope(this);
+  llvm::Value *Check;
+  --End;
+  if (!Min) {
+    Check = Builder.CreateICmpULE(
+        Value, llvm::ConstantInt::get(getLLVMContext(), End));
+  } else {
+    llvm::Value *Upper = Builder.CreateICmpSLE(
+        Value, llvm::ConstantInt::get(getLLVMContext(), End));
+    llvm::Value *Lower = Builder.CreateICmpSGE(
+        Value, llvm::ConstantInt::get(getLLVMContext(), Min));
+    Check = Builder.CreateAnd(Upper, Lower);
+  }
+  llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc),
+                                  EmitCheckTypeDescriptor(Ty)};
+  SanitizerMask Kind =
+      NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool;
+  EmitCheck(std::make_pair(Check, Kind), SanitizerHandler::LoadInvalidValue,
+            StaticArgs, EmitCheckValue(Value));
+  return true;
+}
+
 llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
                                                QualType Ty,
                                                SourceLocation Loc,
@@ -1317,35 +1416,9 @@
                                       false /*ConvertTypeToTag*/);
   }
 
-  bool IsBool = hasBooleanRepresentation(Ty) ||
-                NSAPI(CGM.getContext()).isObjCBOOLType(Ty);
-  bool NeedsBoolCheck = SanOpts.has(SanitizerKind::Bool) && IsBool;
-  bool NeedsEnumCheck =
-      SanOpts.has(SanitizerKind::Enum) && Ty->getAs<EnumType>();
-  if (NeedsBoolCheck || NeedsEnumCheck) {
-    SanitizerScope SanScope(this);
-    llvm::APInt Min, End;
-    if (getRangeForType(*this, Ty, Min, End, /*StrictEnums=*/true, IsBool)) {
-      --End;
-      llvm::Value *Check;
-      if (!Min)
-        Check = Builder.CreateICmpULE(
-          Load, llvm::ConstantInt::get(getLLVMContext(), End));
-      else {
-        llvm::Value *Upper = Builder.CreateICmpSLE(
-          Load, llvm::ConstantInt::get(getLLVMContext(), End));
-        llvm::Value *Lower = Builder.CreateICmpSGE(
-          Load, llvm::ConstantInt::get(getLLVMContext(), Min));
-        Check = Builder.CreateAnd(Upper, Lower);
-      }
-      llvm::Constant *StaticArgs[] = {
-        EmitCheckSourceLocation(Loc),
-        EmitCheckTypeDescriptor(Ty)
-      };
-      SanitizerMask Kind = NeedsEnumCheck ? SanitizerKind::Enum : SanitizerKind::Bool;
-      EmitCheck(std::make_pair(Check, Kind), SanitizerHandler::LoadInvalidValue,
-                StaticArgs, EmitCheckValue(Load));
-    }
+  if (EmitScalarRangeCheck(Load, Ty, Loc)) {
+    // In order to prevent the optimizer from throwing away the check, don't
+    // attach range metadata to the load.
   } else if (CGM.getCodeGenOpts().OptimizationLevel > 0)
     if (llvm::MDNode *RangeInfo = getRangeForLoadFromType(Ty))
       Load->setMetadata(llvm::LLVMContext::MD_range, RangeInfo);
@@ -1487,10 +1560,11 @@
     return EmitLoadOfGlobalRegLValue(LV);
 
   assert(LV.isBitField() && "Unknown LValue type!");
-  return EmitLoadOfBitfieldLValue(LV);
+  return EmitLoadOfBitfieldLValue(LV, Loc);
 }
 
-RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV) {
+RValue CodeGenFunction::EmitLoadOfBitfieldLValue(LValue LV,
+                                                 SourceLocation Loc) {
   const CGBitFieldInfo &Info = LV.getBitFieldInfo();
 
   // Get the output type.
@@ -1515,7 +1589,7 @@
                               "bf.clear");
   }
   Val = Builder.CreateIntCast(Val, ResLTy, Info.IsSigned, "bf.cast");
-
+  EmitScalarRangeCheck(Val, LV.getType(), Loc);
   return RValue::get(Val);
 }
 
@@ -3335,7 +3409,15 @@
     AlignmentSource AlignSource;
     Address Addr = EmitPointerWithAlignment(BaseExpr, &AlignSource);
     QualType PtrTy = BaseExpr->getType()->getPointeeType();
-    EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy);
+    SanitizerSet SkippedChecks;
+    bool IsBaseCXXThis = IsWrappedCXXThis(BaseExpr);
+    if (IsBaseCXXThis)
+      SkippedChecks.set(SanitizerKind::Alignment, true);
+    if (IsBaseCXXThis || isa<DeclRefExpr>(BaseExpr) ||
+        isa<llvm::ConstantPointerNull>(Addr.getPointer()))
+      SkippedChecks.set(SanitizerKind::Null, true);
+    EmitTypeCheck(TCK_MemberAccess, E->getExprLoc(), Addr.getPointer(), PtrTy,
+                  /*Alignment=*/CharUnits::Zero(), SkippedChecks);
     BaseLV = MakeAddrLValue(Addr, PtrTy, AlignSource);
   } else
     BaseLV = EmitCheckedLValue(BaseExpr, TCK_MemberAccess);
@@ -3949,6 +4031,8 @@
 
     RValue RV = EmitAnyExpr(E->getRHS());
     LValue LV = EmitCheckedLValue(E->getLHS(), TCK_Store);
+    if (RV.isScalar())
+      EmitNullabilityCheck(LV, RV.getScalarVal(), E->getExprLoc());
     EmitStoreThroughLValue(RV, LV);
     return LV;
   }
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index 71c8fb8..95cf19f 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -290,10 +290,20 @@
   if (CE)
     CallLoc = CE->getExprLoc();
 
-  EmitTypeCheck(isa<CXXConstructorDecl>(CalleeDecl)
-                ? CodeGenFunction::TCK_ConstructorCall
-                : CodeGenFunction::TCK_MemberCall,
-                CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()));
+  SanitizerSet SkippedChecks;
+  if (const auto *CMCE = dyn_cast<CXXMemberCallExpr>(CE)) {
+    auto *IOA = CMCE->getImplicitObjectArgument();
+    bool IsImplicitObjectCXXThis = IsWrappedCXXThis(IOA);
+    if (IsImplicitObjectCXXThis)
+      SkippedChecks.set(SanitizerKind::Alignment, true);
+    if (IsImplicitObjectCXXThis || isa<DeclRefExpr>(IOA))
+      SkippedChecks.set(SanitizerKind::Null, true);
+  }
+  EmitTypeCheck(
+      isa<CXXConstructorDecl>(CalleeDecl) ? CodeGenFunction::TCK_ConstructorCall
+                                          : CodeGenFunction::TCK_MemberCall,
+      CallLoc, This.getPointer(), C.getRecordType(CalleeDecl->getParent()),
+      /*Alignment=*/CharUnits::Zero(), SkippedChecks);
 
   // FIXME: Uses of 'MD' past this point need to be audited. We may need to use
   // 'CalleeDecl' instead.
@@ -1560,7 +1570,7 @@
 
     // FIXME: Why do we not pass a CalleeDecl here?
     EmitCallArgs(allocatorArgs, allocatorType, E->placement_arguments(),
-                 /*CalleeDecl*/nullptr, /*ParamsToSkip*/ParamsToSkip);
+                 /*AC*/AbstractCallee(), /*ParamsToSkip*/ParamsToSkip);
 
     RValue RV =
       EmitNewDeleteCall(*this, allocator, allocatorType, allocatorArgs);
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 1b85c45..17944a8 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -24,6 +24,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DataLayout.h"
@@ -47,8 +48,66 @@
   Value *RHS;
   QualType Ty;  // Computation Type.
   BinaryOperator::Opcode Opcode; // Opcode of BinOp to perform
-  bool FPContractable;
+  FPOptions FPFeatures;
   const Expr *E;      // Entire expr, for error unsupported.  May not be binop.
+
+  /// Check if the binop can result in integer overflow.
+  bool mayHaveIntegerOverflow() const {
+    // Without constant input, we can't rule out overflow.
+    const auto *LHSCI = dyn_cast<llvm::ConstantInt>(LHS);
+    const auto *RHSCI = dyn_cast<llvm::ConstantInt>(RHS);
+    if (!LHSCI || !RHSCI)
+      return true;
+
+    // Assume overflow is possible, unless we can prove otherwise.
+    bool Overflow = true;
+    const auto &LHSAP = LHSCI->getValue();
+    const auto &RHSAP = RHSCI->getValue();
+    if (Opcode == BO_Add) {
+      if (Ty->hasSignedIntegerRepresentation())
+        (void)LHSAP.sadd_ov(RHSAP, Overflow);
+      else
+        (void)LHSAP.uadd_ov(RHSAP, Overflow);
+    } else if (Opcode == BO_Sub) {
+      if (Ty->hasSignedIntegerRepresentation())
+        (void)LHSAP.ssub_ov(RHSAP, Overflow);
+      else
+        (void)LHSAP.usub_ov(RHSAP, Overflow);
+    } else if (Opcode == BO_Mul) {
+      if (Ty->hasSignedIntegerRepresentation())
+        (void)LHSAP.smul_ov(RHSAP, Overflow);
+      else
+        (void)LHSAP.umul_ov(RHSAP, Overflow);
+    } else if (Opcode == BO_Div || Opcode == BO_Rem) {
+      if (Ty->hasSignedIntegerRepresentation() && !RHSCI->isZero())
+        (void)LHSAP.sdiv_ov(RHSAP, Overflow);
+      else
+        return false;
+    }
+    return Overflow;
+  }
+
+  /// Check if the binop computes a division or a remainder.
+  bool isDivisionLikeOperation() const {
+    return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
+           Opcode == BO_RemAssign;
+  }
+
+  /// Check if the binop can result in an integer division by zero.
+  bool mayHaveIntegerDivisionByZero() const {
+    if (isDivisionLikeOperation())
+      if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
+        return CI->isZero();
+    return true;
+  }
+
+  /// Check if the binop can result in a float division by zero.
+  bool mayHaveFloatDivisionByZero() const {
+    if (isDivisionLikeOperation())
+      if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
+        return CFP->isZero();
+    return true;
+  }
 };
 
 static bool MustVisitNullValue(const Expr *E) {
@@ -58,6 +117,83 @@
   return E->getType()->isNullPtrType();
 }
 
+/// If \p E is a widened promoted integer, get its base (unpromoted) type.
+static llvm::Optional<QualType> getUnwidenedIntegerType(const ASTContext &Ctx,
+                                                        const Expr *E) {
+  const Expr *Base = E->IgnoreImpCasts();
+  if (E == Base)
+    return llvm::None;
+
+  QualType BaseTy = Base->getType();
+  if (!BaseTy->isPromotableIntegerType() ||
+      Ctx.getTypeSize(BaseTy) >= Ctx.getTypeSize(E->getType()))
+    return llvm::None;
+
+  return BaseTy;
+}
+
+/// Check if \p E is a widened promoted integer.
+static bool IsWidenedIntegerOp(const ASTContext &Ctx, const Expr *E) {
+  return getUnwidenedIntegerType(Ctx, E).hasValue();
+}
+
+/// Check if we can skip the overflow check for \p Op.
+static bool CanElideOverflowCheck(const ASTContext &Ctx, const BinOpInfo &Op) {
+  assert((isa<UnaryOperator>(Op.E) || isa<BinaryOperator>(Op.E)) &&
+         "Expected a unary or binary operator");
+
+  // If the binop has constant inputs and we can prove there is no overflow,
+  // we can elide the overflow check.
+  if (!Op.mayHaveIntegerOverflow())
+    return true;
+
+  // If a unary op has a widened operand, the op cannot overflow.
+  if (const auto *UO = dyn_cast<UnaryOperator>(Op.E))
+    return IsWidenedIntegerOp(Ctx, UO->getSubExpr());
+
+  // We usually don't need overflow checks for binops with widened operands.
+  // Multiplication with promoted unsigned operands is a special case.
+  const auto *BO = cast<BinaryOperator>(Op.E);
+  auto OptionalLHSTy = getUnwidenedIntegerType(Ctx, BO->getLHS());
+  if (!OptionalLHSTy)
+    return false;
+
+  auto OptionalRHSTy = getUnwidenedIntegerType(Ctx, BO->getRHS());
+  if (!OptionalRHSTy)
+    return false;
+
+  QualType LHSTy = *OptionalLHSTy;
+  QualType RHSTy = *OptionalRHSTy;
+
+  // This is the simple case: binops without unsigned multiplication, and with
+  // widened operands. No overflow check is needed here.
+  if ((Op.Opcode != BO_Mul && Op.Opcode != BO_MulAssign) ||
+      !LHSTy->isUnsignedIntegerType() || !RHSTy->isUnsignedIntegerType())
+    return true;
+
+  // For unsigned multiplication the overflow check can be elided if either one
+  // of the unpromoted types are less than half the size of the promoted type.
+  unsigned PromotedSize = Ctx.getTypeSize(Op.E->getType());
+  return (2 * Ctx.getTypeSize(LHSTy)) < PromotedSize ||
+         (2 * Ctx.getTypeSize(RHSTy)) < PromotedSize;
+}
+
+/// Update the FastMathFlags of LLVM IR from the FPOptions in LangOptions.
+static void updateFastMathFlags(llvm::FastMathFlags &FMF,
+                                FPOptions FPFeatures) {
+  FMF.setAllowContract(FPFeatures.allowFPContractAcrossStatement());
+}
+
+/// Propagate fast-math flags from \p Op to the instruction in \p V.
+static Value *propagateFMFlags(Value *V, const BinOpInfo &Op) {
+  if (auto *I = dyn_cast<llvm::Instruction>(V)) {
+    llvm::FastMathFlags FMF = I->getFastMathFlags();
+    updateFastMathFlags(FMF, Op.FPFeatures);
+    I->setFastMathFlags(FMF);
+  }
+  return V;
+}
+
 class ScalarExprEmitter
   : public StmtVisitor<ScalarExprEmitter, Value*> {
   CodeGenFunction &CGF;
@@ -300,6 +436,24 @@
     return V;
   }
 
+  Value *VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
+    VersionTuple Version = E->getVersion();
+
+    // If we're checking for a platform older than our minimum deployment
+    // target, we can fold the check away.
+    if (Version <= CGF.CGM.getTarget().getPlatformMinVersion())
+      return llvm::ConstantInt::get(Builder.getInt1Ty(), 1);
+
+    Optional<unsigned> Min = Version.getMinor(), SMin = Version.getSubminor();
+    llvm::Value *Args[] = {
+        llvm::ConstantInt::get(CGF.CGM.Int32Ty, Version.getMajor()),
+        llvm::ConstantInt::get(CGF.CGM.Int32Ty, Min ? *Min : 0),
+        llvm::ConstantInt::get(CGF.CGM.Int32Ty, SMin ? *SMin : 0),
+    };
+
+    return CGF.EmitBuiltinAvailable(Args);
+  }
+
   Value *VisitArraySubscriptExpr(ArraySubscriptExpr *E);
   Value *VisitShuffleVectorExpr(ShuffleVectorExpr *E);
   Value *VisitConvertVectorExpr(ConvertVectorExpr *E);
@@ -464,16 +618,21 @@
           return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
         // Fall through.
       case LangOptions::SOB_Trapping:
+        if (CanElideOverflowCheck(CGF.getContext(), Ops))
+          return Builder.CreateNSWMul(Ops.LHS, Ops.RHS, "mul");
         return EmitOverflowCheckedBinOp(Ops);
       }
     }
 
     if (Ops.Ty->isUnsignedIntegerType() &&
-        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow))
+        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
+        !CanElideOverflowCheck(CGF.getContext(), Ops))
       return EmitOverflowCheckedBinOp(Ops);
 
-    if (Ops.LHS->getType()->isFPOrFPVectorTy())
-      return Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
+    if (Ops.LHS->getType()->isFPOrFPVectorTy()) {
+      Value *V = Builder.CreateFMul(Ops.LHS, Ops.RHS, "mul");
+      return propagateFMFlags(V, Ops);
+    }
     return Builder.CreateMul(Ops.LHS, Ops.RHS, "mul");
   }
   /// Create a binary op that checks for overflow.
@@ -1627,7 +1786,7 @@
   BinOp.RHS = llvm::ConstantInt::get(InVal->getType(), 1, false);
   BinOp.Ty = E->getType();
   BinOp.Opcode = IsInc ? BO_Add : BO_Sub;
-  BinOp.FPContractable = false;
+  // FIXME: once UnaryOperator carries FPFeatures, copy it here.
   BinOp.E = E;
   return BinOp;
 }
@@ -1645,6 +1804,8 @@
       return Builder.CreateNSWAdd(InVal, Amount, Name);
     // Fall through.
   case LangOptions::SOB_Trapping:
+    if (IsWidenedIntegerOp(CGF.getContext(), E->getSubExpr()))
+      return Builder.CreateNSWAdd(InVal, Amount, Name);
     return EmitOverflowCheckedBinOp(createBinOpInfoFromIncDec(E, InVal, IsInc));
   }
   llvm_unreachable("Unknown SignedOverflowBehaviorTy");
@@ -1891,7 +2052,7 @@
     BinOp.LHS = llvm::Constant::getNullValue(BinOp.RHS->getType());
   BinOp.Ty = E->getType();
   BinOp.Opcode = BO_Sub;
-  BinOp.FPContractable = false;
+  // FIXME: once UnaryOperator carries FPFeatures, copy it here.
   BinOp.E = E;
   return EmitSub(BinOp);
 }
@@ -2112,7 +2273,7 @@
   Result.RHS = Visit(E->getRHS());
   Result.Ty  = E->getType();
   Result.Opcode = E->getOpcode();
-  Result.FPContractable = E->isFPContractable();
+  Result.FPFeatures = E->getFPFeatures();
   Result.E = E;
   return Result;
 }
@@ -2132,7 +2293,7 @@
   OpInfo.RHS = Visit(E->getRHS());
   OpInfo.Ty = E->getComputationResultType();
   OpInfo.Opcode = E->getOpcode();
-  OpInfo.FPContractable = E->isFPContractable();
+  OpInfo.FPFeatures = E->getFPFeatures();
   OpInfo.E = E;
   // Load/convert the LHS.
   LValue LHSLV = EmitCheckedLValue(E->getLHS(), CodeGenFunction::TCK_Store);
@@ -2263,8 +2424,11 @@
                                     SanitizerKind::IntegerDivideByZero));
   }
 
+  const auto *BO = cast<BinaryOperator>(Ops.E);
   if (CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow) &&
-      Ops.Ty->hasSignedIntegerRepresentation()) {
+      Ops.Ty->hasSignedIntegerRepresentation() &&
+      !IsWidenedIntegerOp(CGF.getContext(), BO->getLHS()) &&
+      Ops.mayHaveIntegerOverflow()) {
     llvm::IntegerType *Ty = cast<llvm::IntegerType>(Zero->getType());
 
     llvm::Value *IntMin =
@@ -2287,11 +2451,13 @@
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
          CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
-        Ops.Ty->isIntegerType()) {
+        Ops.Ty->isIntegerType() &&
+        (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
       llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
       EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, true);
     } else if (CGF.SanOpts.has(SanitizerKind::FloatDivideByZero) &&
-               Ops.Ty->isRealFloatingType()) {
+               Ops.Ty->isRealFloatingType() &&
+               Ops.mayHaveFloatDivisionByZero()) {
       llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
       llvm::Value *NonZero = Builder.CreateFCmpUNE(Ops.RHS, Zero);
       EmitBinOpCheck(std::make_pair(NonZero, SanitizerKind::FloatDivideByZero),
@@ -2324,12 +2490,13 @@
 
 Value *ScalarExprEmitter::EmitRem(const BinOpInfo &Ops) {
   // Rem in C can't be a floating point type: C99 6.5.5p2.
-  if (CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero)) {
+  if ((CGF.SanOpts.has(SanitizerKind::IntegerDivideByZero) ||
+       CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) &&
+      Ops.Ty->isIntegerType() &&
+      (Ops.mayHaveIntegerDivisionByZero() || Ops.mayHaveIntegerOverflow())) {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     llvm::Value *Zero = llvm::Constant::getNullValue(ConvertType(Ops.Ty));
-
-    if (Ops.Ty->isIntegerType())
-      EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
+    EmitUndefinedBehaviorIntegerDivAndRemCheck(Ops, Zero, false);
   }
 
   if (Ops.Ty->hasUnsignedIntegerRepresentation())
@@ -2369,6 +2536,7 @@
   if (isSigned)
     OpID |= 1;
 
+  CodeGenFunction::SanitizerScope SanScope(&CGF);
   llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
 
   llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
@@ -2384,7 +2552,6 @@
     // If the signed-integer-overflow sanitizer is enabled, emit a call to its
     // runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
     if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
-      CodeGenFunction::SanitizerScope SanScope(&CGF);
       llvm::Value *NotOverflow = Builder.CreateNot(overflow);
       SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow
                               : SanitizerKind::UnsignedIntegerOverflow;
@@ -2577,12 +2744,7 @@
          "Only fadd/fsub can be the root of an fmuladd.");
 
   // Check whether this op is marked as fusable.
-  if (!op.FPContractable)
-    return nullptr;
-
-  // Check whether -ffp-contract=on. (If -ffp-contract=off/fast, fusing is
-  // either disabled, or handled entirely by the LLVM backend).
-  if (CGF.CGM.getCodeGenOpts().getFPContractMode() != CodeGenOptions::FPC_On)
+  if (!op.FPFeatures.allowFPContractWithinStatement())
     return nullptr;
 
   // We have a potentially fusable op. Look for a mul on one of the operands.
@@ -2616,12 +2778,15 @@
         return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
       // Fall through.
     case LangOptions::SOB_Trapping:
+      if (CanElideOverflowCheck(CGF.getContext(), op))
+        return Builder.CreateNSWAdd(op.LHS, op.RHS, "add");
       return EmitOverflowCheckedBinOp(op);
     }
   }
 
   if (op.Ty->isUnsignedIntegerType() &&
-      CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow))
+      CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
+      !CanElideOverflowCheck(CGF.getContext(), op))
     return EmitOverflowCheckedBinOp(op);
 
   if (op.LHS->getType()->isFPOrFPVectorTy()) {
@@ -2629,7 +2794,8 @@
     if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder))
       return FMulAdd;
 
-    return Builder.CreateFAdd(op.LHS, op.RHS, "add");
+    Value *V = Builder.CreateFAdd(op.LHS, op.RHS, "add");
+    return propagateFMFlags(V, op);
   }
 
   return Builder.CreateAdd(op.LHS, op.RHS, "add");
@@ -2647,19 +2813,23 @@
           return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
         // Fall through.
       case LangOptions::SOB_Trapping:
+        if (CanElideOverflowCheck(CGF.getContext(), op))
+          return Builder.CreateNSWSub(op.LHS, op.RHS, "sub");
         return EmitOverflowCheckedBinOp(op);
       }
     }
 
     if (op.Ty->isUnsignedIntegerType() &&
-        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow))
+        CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) &&
+        !CanElideOverflowCheck(CGF.getContext(), op))
       return EmitOverflowCheckedBinOp(op);
 
     if (op.LHS->getType()->isFPOrFPVectorTy()) {
       // Try to form an fmuladd.
       if (Value *FMulAdd = tryEmitFMulAdd(op, CGF, Builder, true))
         return FMulAdd;
-      return Builder.CreateFSub(op.LHS, op.RHS, "sub");
+      Value *V = Builder.CreateFSub(op.LHS, op.RHS, "sub");
+      return propagateFMFlags(V, op);
     }
 
     return Builder.CreateSub(op.LHS, op.RHS, "sub");
@@ -2751,8 +2921,8 @@
            isa<llvm::IntegerType>(Ops.LHS->getType())) {
     CodeGenFunction::SanitizerScope SanScope(&CGF);
     SmallVector<std::pair<Value *, SanitizerMask>, 2> Checks;
-    llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, RHS);
-    llvm::Value *ValidExponent = Builder.CreateICmpULE(RHS, WidthMinusOne);
+    llvm::Value *WidthMinusOne = GetWidthMinusOneValue(Ops.LHS, Ops.RHS);
+    llvm::Value *ValidExponent = Builder.CreateICmpULE(Ops.RHS, WidthMinusOne);
 
     if (SanitizeExponent) {
       Checks.push_back(
@@ -2767,12 +2937,14 @@
       llvm::BasicBlock *Cont = CGF.createBasicBlock("cont");
       llvm::BasicBlock *CheckShiftBase = CGF.createBasicBlock("check");
       Builder.CreateCondBr(ValidExponent, CheckShiftBase, Cont);
+      llvm::Value *PromotedWidthMinusOne =
+          (RHS == Ops.RHS) ? WidthMinusOne
+                           : GetWidthMinusOneValue(Ops.LHS, RHS);
       CGF.EmitBlock(CheckShiftBase);
-      llvm::Value *BitsShiftedOff =
-        Builder.CreateLShr(Ops.LHS,
-                           Builder.CreateSub(WidthMinusOne, RHS, "shl.zeros",
-                                             /*NUW*/true, /*NSW*/true),
-                           "shl.check");
+      llvm::Value *BitsShiftedOff = Builder.CreateLShr(
+          Ops.LHS, Builder.CreateSub(PromotedWidthMinusOne, RHS, "shl.zeros",
+                                     /*NUW*/ true, /*NSW*/ true),
+          "shl.check");
       if (CGF.getLangOpts().CPlusPlus) {
         // In C99, we are not permitted to shift a 1 bit into the sign bit.
         // Under C++11's rules, shifting a 1 bit into the sign bit is
@@ -3038,10 +3210,12 @@
     // because the result is altered by the store, i.e., [C99 6.5.16p1]
     // 'An assignment expression has the value of the left operand after
     // the assignment...'.
-    if (LHS.isBitField())
+    if (LHS.isBitField()) {
       CGF.EmitStoreThroughBitfieldLValue(RValue::get(RHS), LHS, &RHS);
-    else
+    } else {
+      CGF.EmitNullabilityCheck(LHS, RHS, E->getExprLoc());
       CGF.EmitStoreThroughLValue(RValue::get(RHS), LHS);
+    }
   }
 
   // If the result is clearly ignored, return now.
@@ -3327,9 +3501,11 @@
   // safe to evaluate the LHS and RHS unconditionally.
   if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) &&
       isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) {
-    CGF.incrementProfileCounter(E);
-
     llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
+    llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
+
+    CGF.incrementProfileCounter(E, StepV);
+
     llvm::Value *LHS = Visit(lhsExpr);
     llvm::Value *RHS = Visit(rhsExpr);
     if (!LHS) {
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 932b8a1..4a6a458 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -117,10 +117,24 @@
   const ObjCArrayLiteral *ALE = dyn_cast<ObjCArrayLiteral>(E);
   if (!ALE)
     DLE = cast<ObjCDictionaryLiteral>(E);
-  
-  // Compute the type of the array we're initializing.
+
+  // Optimize empty collections by referencing constants, when available.
   uint64_t NumElements = 
     ALE ? ALE->getNumElements() : DLE->getNumElements();
+  if (NumElements == 0 && CGM.getLangOpts().ObjCRuntime.hasEmptyCollections()) {
+    StringRef ConstantName = ALE ? "__NSArray0__" : "__NSDictionary0__";
+    QualType IdTy(CGM.getContext().getObjCIdType());
+    llvm::Constant *Constant =
+        CGM.CreateRuntimeVariable(ConvertType(IdTy), ConstantName);
+    LValue LV = MakeNaturalAlignAddrLValue(Constant, IdTy);
+    llvm::Value *Ptr = EmitLoadOfScalar(LV, E->getLocStart());
+    cast<llvm::LoadInst>(Ptr)->setMetadata(
+        CGM.getModule().getMDKindID("invariant.load"),
+        llvm::MDNode::get(getLLVMContext(), None));
+    return Builder.CreateBitCast(Ptr, ConvertType(E->getType()));
+  }
+
+  // Compute the type of the array we're initializing.
   llvm::APInt APNumElements(Context.getTypeSize(Context.getSizeType()),
                             NumElements);
   QualType ElementType = Context.getObjCIdType().withConst();
@@ -427,7 +441,7 @@
   QualType ResultType = method ? method->getReturnType() : E->getType();
 
   CallArgList Args;
-  EmitCallArgs(Args, method, E->arguments());
+  EmitCallArgs(Args, method, E->arguments(), /*AC*/AbstractCallee(method));
 
   // For delegate init calls in ARC, do an unsafe store of null into
   // self.  This represents the call taking direct ownership of that
@@ -1316,7 +1330,7 @@
 
   BinaryOperator assign(&ivarRef, finalArg, BO_Assign,
                         ivarRef.getType(), VK_RValue, OK_Ordinary,
-                        SourceLocation(), false);
+                        SourceLocation(), FPOptions());
   EmitStmt(&assign);
 }
 
@@ -1469,6 +1483,8 @@
   if (DI)
     DI->EmitLexicalBlockStart(Builder, S.getSourceRange().getBegin());
 
+  RunCleanupsScope ForScope(*this);
+
   // The local variable comes into scope immediately.
   AutoVarEmission variable = AutoVarEmission::invalid();
   if (const DeclStmt *SD = dyn_cast<DeclStmt>(S.getElement()))
@@ -1499,8 +1515,6 @@
                                       ArrayType::Normal, 0);
   Address ItemsPtr = CreateMemTemp(ItemsTy, "items.ptr");
 
-  RunCleanupsScope ForScope(*this);
-
   // Emit the collection pointer.  In ARC, we do a retain.
   llvm::Value *Collection;
   if (getLangOpts().ObjCAutoRefCount) {
@@ -3239,7 +3253,7 @@
   CallExpr *CalleeExp = cast<CallExpr>(PID->getSetterCXXAssignment());
   CXXOperatorCallExpr TheCall(C, OO_Equal, CalleeExp->getCallee(),
                               Args, DestTy->getPointeeType(),
-                              VK_LValue, SourceLocation(), false);
+                              VK_LValue, SourceLocation(), FPOptions());
   
   EmitStmt(&TheCall);
 
@@ -3375,5 +3389,54 @@
   return Val;
 }
 
+llvm::Value *
+CodeGenFunction::EmitBuiltinAvailable(ArrayRef<llvm::Value *> Args) {
+  assert(Args.size() == 3 && "Expected 3 argument here!");
+
+  if (!CGM.IsOSVersionAtLeastFn) {
+    llvm::FunctionType *FTy =
+        llvm::FunctionType::get(Int32Ty, {Int32Ty, Int32Ty, Int32Ty}, false);
+    CGM.IsOSVersionAtLeastFn =
+        CGM.CreateRuntimeFunction(FTy, "__isOSVersionAtLeast");
+  }
+
+  llvm::Value *CallRes =
+      EmitNounwindRuntimeCall(CGM.IsOSVersionAtLeastFn, Args);
+
+  return Builder.CreateICmpNE(CallRes, llvm::Constant::getNullValue(Int32Ty));
+}
+
+void CodeGenModule::emitAtAvailableLinkGuard() {
+  if (!IsOSVersionAtLeastFn)
+    return;
+  // @available requires CoreFoundation only on Darwin.
+  if (!Target.getTriple().isOSDarwin())
+    return;
+  // Add -framework CoreFoundation to the linker commands. We still want to
+  // emit the core foundation reference down below because otherwise if
+  // CoreFoundation is not used in the code, the linker won't link the
+  // framework.
+  auto &Context = getLLVMContext();
+  llvm::Metadata *Args[2] = {llvm::MDString::get(Context, "-framework"),
+                             llvm::MDString::get(Context, "CoreFoundation")};
+  LinkerOptionsMetadata.push_back(llvm::MDNode::get(Context, Args));
+  // Emit a reference to a symbol from CoreFoundation to ensure that
+  // CoreFoundation is linked into the final binary.
+  llvm::FunctionType *FTy =
+      llvm::FunctionType::get(Int32Ty, {VoidPtrTy}, false);
+  llvm::Constant *CFFunc =
+      CreateRuntimeFunction(FTy, "CFBundleGetVersionNumber");
+
+  llvm::FunctionType *CheckFTy = llvm::FunctionType::get(VoidTy, {}, false);
+  llvm::Function *CFLinkCheckFunc = cast<llvm::Function>(CreateBuiltinFunction(
+      CheckFTy, "__clang_at_available_requires_core_foundation_framework"));
+  CFLinkCheckFunc->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage);
+  CFLinkCheckFunc->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  CodeGenFunction CGF(*this);
+  CGF.Builder.SetInsertPoint(CGF.createBasicBlock("", CFLinkCheckFunc));
+  CGF.EmitNounwindRuntimeCall(CFFunc, llvm::Constant::getNullValue(VoidPtrTy));
+  CGF.Builder.CreateUnreachable();
+  addCompilerUsedGlobal(CFLinkCheckFunc);
+}
 
 CGObjCRuntime::~CGObjCRuntime() {}
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index fa2b3d8..ce39bd1 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -18,7 +18,7 @@
 #include "CGCleanup.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 7219592..2880733 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -17,7 +17,7 @@
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
@@ -7147,7 +7147,12 @@
   }
 
   assert(GV->getLinkage() == L);
-  return GV;
+
+  if (IsForDefinition ||
+      GV->getValueType() == ObjCTypes.ClassnfABITy)
+    return GV;
+
+  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ClassnfABIPtrTy);
 }
 
 llvm::Value *
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index 4025217..e54cf7b 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -15,7 +15,7 @@
 #include "CGCleanup.h"
 #include "CGOpenMPRuntime.h"
 #include "CodeGenFunction.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/StmtOpenMP.h"
 #include "llvm/ADT/ArrayRef.h"
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 39e1cdf..6da9e7a 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -2320,8 +2320,7 @@
     CodeGenFunction::OpaqueValueMapping OpaqueUB(CGF, &UBRefExpr, UB);
     // Generate condition for loop.
     BinaryOperator Cond(&IVRefExpr, &UBRefExpr, BO_LE, C.BoolTy, VK_RValue,
-                        OK_Ordinary, S.getLocStart(),
-                        /*fpContractable=*/false);
+                        OK_Ordinary, S.getLocStart(), FPOptions());
     // Increment for loop counter.
     UnaryOperator Inc(&IVRefExpr, UO_PreInc, KmpInt32Ty, VK_RValue, OK_Ordinary,
                       S.getLocStart());
diff --git a/lib/CodeGen/CGVTables.cpp b/lib/CodeGen/CGVTables.cpp
index 1a09830..64a3d2d 100644
--- a/lib/CodeGen/CGVTables.cpp
+++ b/lib/CodeGen/CGVTables.cpp
@@ -14,7 +14,7 @@
 #include "CGCXXABI.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 4fbf9f2..921e3b8 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -75,6 +75,7 @@
   CodeGenPGO.cpp
   CodeGenTBAA.cpp
   CodeGenTypes.cpp
+  ConstantInitBuilder.cpp
   CoverageMappingGen.cpp
   ItaniumCXXABI.cpp
   MicrosoftCXXABI.cpp
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp
index 5f74141..6206882 100644
--- a/lib/CodeGen/CodeGenAction.cpp
+++ b/lib/CodeGen/CodeGenAction.cpp
@@ -275,7 +275,7 @@
     /// Get the best possible source location to represent a diagnostic that
     /// may have associated debug info.
     const FullSourceLoc
-    getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithDebugLocBase &D,
+    getBestLocationFromDebugLoc(const llvm::DiagnosticInfoWithLocationBase &D,
                                 bool &BadDebugInfo, StringRef &Filename,
                                 unsigned &Line, unsigned &Column) const;
 
@@ -477,8 +477,8 @@
 }
 
 const FullSourceLoc BackendConsumer::getBestLocationFromDebugLoc(
-    const llvm::DiagnosticInfoWithDebugLocBase &D, bool &BadDebugInfo, StringRef &Filename,
-                                unsigned &Line, unsigned &Column) const {
+    const llvm::DiagnosticInfoWithLocationBase &D, bool &BadDebugInfo,
+    StringRef &Filename, unsigned &Line, unsigned &Column) const {
   SourceManager &SourceMgr = Context->getSourceManager();
   FileManager &FileMgr = SourceMgr.getFileManager();
   SourceLocation DILoc;
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index e142a21..07cc100 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -707,6 +707,11 @@
   return false;
 }
 
+static void markAsIgnoreThreadCheckingAtRuntime(llvm::Function *Fn) {
+  Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
+  Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
+}
+
 void CodeGenFunction::StartFunction(GlobalDecl GD,
                                     QualType RetTy,
                                     llvm::Function *Fn,
@@ -750,16 +755,19 @@
     Fn->addFnAttr(llvm::Attribute::SafeStack);
 
   // Ignore TSan memory acesses from within ObjC/ObjC++ dealloc, initialize,
-  // .cxx_destruct and all of their calees at run time.
+  // .cxx_destruct, __destroy_helper_block_ and all of their calees at run time.
   if (SanOpts.has(SanitizerKind::Thread)) {
     if (const auto *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
       IdentifierInfo *II = OMD->getSelector().getIdentifierInfoForSlot(0);
       if (OMD->getMethodFamily() == OMF_dealloc ||
           OMD->getMethodFamily() == OMF_initialize ||
           (OMD->getSelector().isUnarySelector() && II->isStr(".cxx_destruct"))) {
-        Fn->addFnAttr("sanitize_thread_no_checking_at_run_time");
-        Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
+        markAsIgnoreThreadCheckingAtRuntime(Fn);
       }
+    } else if (const auto *FD = dyn_cast_or_null<FunctionDecl>(D)) {
+      IdentifierInfo *II = FD->getIdentifier();
+      if (II && II->isStr("__destroy_helper_block_"))
+        markAsIgnoreThreadCheckingAtRuntime(Fn);
     }
   }
 
@@ -807,6 +815,18 @@
     }
   }
 
+  // If we're checking nullability, we need to know whether we can check the
+  // return value. Initialize the flag to 'true' and refine it in EmitParmDecl.
+  if (SanOpts.has(SanitizerKind::NullabilityReturn)) {
+    auto Nullability = FnRetTy->getNullability(getContext());
+    if (Nullability && *Nullability == NullabilityKind::NonNull) {
+      if (!(SanOpts.has(SanitizerKind::ReturnsNonnullAttribute) &&
+            CurCodeDecl && CurCodeDecl->getAttr<ReturnsNonNullAttr>()))
+        RetValNullabilityPrecondition =
+            llvm::ConstantInt::getTrue(getLLVMContext());
+    }
+  }
+
   // If we're in C++ mode and the function name is "main", it is guaranteed
   // to be norecurse by the standard (3.6.1.3 "The function main shall not be
   // used within a program").
@@ -935,6 +955,16 @@
       // fast register allocator would be happier...
       CXXThisValue = CXXABIThisValue;
     }
+
+    // Check the 'this' pointer once per function, if it's available.
+    if (CXXThisValue) {
+      SanitizerSet SkippedChecks;
+      SkippedChecks.set(SanitizerKind::ObjectSize, true);
+      QualType ThisTy = MD->getThisType(getContext());
+      EmitTypeCheck(TCK_Load, Loc, CXXThisValue, ThisTy,
+                    getContext().getTypeAlignInChars(ThisTy->getPointeeType()),
+                    SkippedChecks);
+    }
   }
 
   // If any of the arguments have a variably modified type, make sure to
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 5861340..cd23db9 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -115,6 +115,8 @@
   SANITIZER_CHECK(MissingReturn, missing_return, 0)                            \
   SANITIZER_CHECK(MulOverflow, mul_overflow, 0)                                \
   SANITIZER_CHECK(NegateOverflow, negate_overflow, 0)                          \
+  SANITIZER_CHECK(NullabilityArg, nullability_arg, 0)                          \
+  SANITIZER_CHECK(NullabilityReturn, nullability_return, 0)                    \
   SANITIZER_CHECK(NonnullArg, nonnull_arg, 0)                                  \
   SANITIZER_CHECK(NonnullReturn, nonnull_return, 0)                            \
   SANITIZER_CHECK(OutOfBounds, out_of_bounds, 0)                               \
@@ -212,6 +214,13 @@
   /// value. This is invalid iff the function has no return value.
   Address ReturnValue;
 
+  /// Return true if a label was seen in the current scope.
+  bool hasLabelBeenSeenInCurrentScope() const {
+    if (CurLexicalScope)
+      return CurLexicalScope->hasLabels();
+    return !LabelMap.empty();
+  }
+
   /// AllocaInsertPoint - This is an instruction in the entry block before which
   /// we prefer to insert allocas.
   llvm::AssertingVH<llvm::Instruction> AllocaInsertPt;
@@ -298,6 +307,31 @@
     ~CGCapturedStmtRAII() { CGF.CapturedStmtInfo = PrevCapturedStmtInfo; }
   };
 
+  /// An abstract representation of regular/ObjC call/message targets.
+  class AbstractCallee {
+    /// The function declaration of the callee.
+    const Decl *CalleeDecl;
+
+  public:
+    AbstractCallee() : CalleeDecl(nullptr) {}
+    AbstractCallee(const FunctionDecl *FD) : CalleeDecl(FD) {}
+    AbstractCallee(const ObjCMethodDecl *OMD) : CalleeDecl(OMD) {}
+    bool hasFunctionDecl() const {
+      return dyn_cast_or_null<FunctionDecl>(CalleeDecl);
+    }
+    const Decl *getDecl() const { return CalleeDecl; }
+    unsigned getNumParams() const {
+      if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
+        return FD->getNumParams();
+      return cast<ObjCMethodDecl>(CalleeDecl)->param_size();
+    }
+    const ParmVarDecl *getParamDecl(unsigned I) const {
+      if (const auto *FD = dyn_cast<FunctionDecl>(CalleeDecl))
+        return FD->getParamDecl(I);
+      return *(cast<ObjCMethodDecl>(CalleeDecl)->param_begin() + I);
+    }
+  };
+
   /// \brief Sanitizers enabled for this function.
   SanitizerSet SanOpts;
 
@@ -620,6 +654,10 @@
         rescopeLabels();
     }
 
+    bool hasLabels() const {
+      return !Labels.empty();
+    }
+
     void rescopeLabels();
   };
 
@@ -1116,10 +1154,11 @@
                                             uint64_t LoopCount);
 
 public:
-  /// Increment the profiler's counter for the given statement.
-  void incrementProfileCounter(const Stmt *S) {
+  /// Increment the profiler's counter for the given statement by \p StepV.
+  /// If \p StepV is null, the default increment is 1.
+  void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) {
     if (CGM.getCodeGenOpts().hasProfileClangInstr())
-      PGO.emitCounterIncrement(Builder, S);
+      PGO.emitCounterIncrement(Builder, S, StepV);
     PGO.setCurrentStmt(S);
   }
 
@@ -1334,6 +1373,16 @@
   /// information about the layout of the variable.
   llvm::DenseMap<const ValueDecl *, BlockByrefInfo> BlockByrefInfos;
 
+  /// Used by -fsanitize=nullability-return to determine whether the return
+  /// value can be checked.
+  llvm::Value *RetValNullabilityPrecondition = nullptr;
+
+  /// Check if -fsanitize=nullability-return instrumentation is required for
+  /// this function.
+  bool requiresReturnValueNullabilityCheck() const {
+    return RetValNullabilityPrecondition;
+  }
+
   llvm::BasicBlock *TerminateLandingPad;
   llvm::BasicBlock *TerminateHandler;
   llvm::BasicBlock *TrapBB;
@@ -1553,6 +1602,8 @@
                      SourceLocation Loc = SourceLocation(),
                      SourceLocation StartLoc = SourceLocation());
 
+  static bool IsConstructorDelegationValid(const CXXConstructorDecl *Ctor);
+
   void EmitConstructorBody(FunctionArgList &Args);
   void EmitDestructorBody(FunctionArgList &Args);
   void emitImplicitAssignmentOperatorBody(FunctionArgList &Args);
@@ -1710,6 +1761,9 @@
   void EmitFunctionEpilog(const CGFunctionInfo &FI, bool EmitRetDbgLoc,
                           SourceLocation EndLoc);
 
+  /// Emit a test that checks if the return value \p RV is nonnull.
+  void EmitReturnValueCheck(llvm::Value *RV, SourceLocation EndLoc);
+
   /// EmitStartEHSpec - Emit the start of the exception spec.
   void EmitStartEHSpec(const Decl *D);
 
@@ -2019,6 +2073,9 @@
   llvm::BlockAddress *GetAddrOfLabel(const LabelDecl *L);
   llvm::BasicBlock *GetIndirectGotoBlock();
 
+  /// Check if \p E is a C++ "this" pointer wrapped in value-preserving casts.
+  static bool IsWrappedCXXThis(const Expr *E);
+
   /// EmitNullInitialization - Generate code to set a value of the given type to
   /// null, If the type contains data member pointers, they will be initialized
   /// to -1 in accordance with the Itanium C++ ABI.
@@ -2230,7 +2287,9 @@
     TCK_Upcast,
     /// Checking the operand of a cast to a virtual base object. Must be an
     /// object within its lifetime.
-    TCK_UpcastToVirtualBase
+    TCK_UpcastToVirtualBase,
+    /// Checking the value assigned to a _Nonnull pointer. Must not be null.
+    TCK_NonnullAssign
   };
 
   /// \brief Whether any type-checking sanitizers are enabled. If \c false,
@@ -2241,7 +2300,7 @@
   /// appropriate size and alignment for an object of type \p Type.
   void EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *V,
                      QualType Type, CharUnits Alignment = CharUnits::Zero(),
-                     bool SkipNullCheck = false);
+                     SanitizerSet SkippedChecks = SanitizerSet());
 
   /// \brief Emit a check that \p Base points into an array object, which
   /// we can access at index \p Index. \p Accessed should be \c false if we
@@ -2843,6 +2902,13 @@
   /// representation to its value representation.
   llvm::Value *EmitFromMemory(llvm::Value *Value, QualType Ty);
 
+  /// Check if the scalar \p Value is within the valid range for the given
+  /// type \p Ty.
+  ///
+  /// Returns true if a check is needed (even if the range is unknown).
+  bool EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
+                            SourceLocation Loc);
+
   /// EmitLoadOfScalar - Load a scalar value from an address, taking
   /// care to appropriately convert from the memory representation to
   /// the LLVM value representation.
@@ -2883,7 +2949,7 @@
   /// rvalue, returning the rvalue.
   RValue EmitLoadOfLValue(LValue V, SourceLocation Loc);
   RValue EmitLoadOfExtVectorElementLValue(LValue V);
-  RValue EmitLoadOfBitfieldLValue(LValue LV);
+  RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc);
   RValue EmitLoadOfGlobalRegLValue(LValue LV);
 
   /// EmitStoreThroughLValue - Store the specified rvalue into the specified
@@ -3149,6 +3215,8 @@
 public:
   llvm::Value *EmitMSVCBuiltinExpr(MSVCIntrin BuiltinID, const CallExpr *E);
 
+  llvm::Value *EmitBuiltinAvailable(ArrayRef<llvm::Value *> Args);
+
   llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
   llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E);
@@ -3396,6 +3464,10 @@
   void EmitBranchOnBoolExpr(const Expr *Cond, llvm::BasicBlock *TrueBlock,
                             llvm::BasicBlock *FalseBlock, uint64_t TrueCount);
 
+  /// Given an assignment `*LHS = RHS`, emit a test that checks if \p RHS is
+  /// nonnull, if \p LHS is marked _Nonnull.
+  void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc);
+
   /// \brief Emit a description of a type in a format suitable for passing to
   /// a runtime sanitizer handler.
   llvm::Constant *EmitCheckTypeDescriptor(QualType T);
@@ -3435,7 +3507,7 @@
   /// \brief Create a check for a function parameter that may potentially be
   /// declared as non-null.
   void EmitNonNullArgCheck(RValue RV, QualType ArgType, SourceLocation ArgLoc,
-                           const FunctionDecl *FD, unsigned ParmNum);
+                           AbstractCallee AC, unsigned ParmNum);
 
   /// EmitCallArg - Emit a single call argument.
   void EmitCallArg(CallArgList &args, const Expr *E, QualType ArgType);
@@ -3533,7 +3605,7 @@
   template <typename T>
   void EmitCallArgs(CallArgList &Args, const T *CallArgTypeInfo,
                     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
-                    const FunctionDecl *CalleeDecl = nullptr,
+                    AbstractCallee AC = AbstractCallee(),
                     unsigned ParamsToSkip = 0,
                     EvaluationOrder Order = EvaluationOrder::Default) {
     SmallVector<QualType, 16> ArgTypes;
@@ -3575,12 +3647,12 @@
     for (auto *A : llvm::make_range(Arg, ArgRange.end()))
       ArgTypes.push_back(CallArgTypeInfo ? getVarArgType(A) : A->getType());
 
-    EmitCallArgs(Args, ArgTypes, ArgRange, CalleeDecl, ParamsToSkip, Order);
+    EmitCallArgs(Args, ArgTypes, ArgRange, AC, ParamsToSkip, Order);
   }
 
   void EmitCallArgs(CallArgList &Args, ArrayRef<QualType> ArgTypes,
                     llvm::iterator_range<CallExpr::const_arg_iterator> ArgRange,
-                    const FunctionDecl *CalleeDecl = nullptr,
+                    AbstractCallee AC = AbstractCallee(),
                     unsigned ParamsToSkip = 0,
                     EvaluationOrder Order = EvaluationOrder::Default);
 
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index f14354a..b2a96f7 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -24,7 +24,6 @@
 #include "CodeGenFunction.h"
 #include "CodeGenPGO.h"
 #include "CodeGenTBAA.h"
-#include "ConstantBuilder.h"
 #include "CoverageMappingGen.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
@@ -42,6 +41,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Version.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "clang/Sema/SemaDiagnostic.h"
 #include "llvm/ADT/Triple.h"
@@ -373,9 +373,13 @@
     if (MainFile.empty())
       MainFile = "<stdin>";
     Diags.Report(diag::warn_profile_data_unprofiled) << MainFile;
-  } else
-    Diags.Report(diag::warn_profile_data_out_of_date) << Visited << Missing
-                                                      << Mismatched;
+  } else {
+    if (Mismatched > 0)
+      Diags.Report(diag::warn_profile_data_out_of_date) << Visited << Mismatched;
+
+    if (Missing > 0)
+      Diags.Report(diag::warn_profile_data_missing) << Visited << Missing;
+  }
 }
 
 void CodeGenModule::Release() {
@@ -414,6 +418,7 @@
     CoverageMapping->emit();
   if (CodeGenOpts.SanitizeCfiCrossDso)
     CodeGenFunction(*this).EmitCfiCheckFail();
+  emitAtAvailableLinkGuard();
   emitLLVMUsed();
   if (SanStats)
     SanStats->finish();
@@ -3348,6 +3353,7 @@
     llvm_unreachable("unknown file format");
   case llvm::Triple::COFF:
   case llvm::Triple::ELF:
+  case llvm::Triple::Wasm:
     GV->setSection("cfstring");
     break;
   case llvm::Triple::MachO:
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 36f6785..1ed4df1 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -546,6 +546,10 @@
     return *ObjCData;
   }
 
+  // Version checking function, used to implement ObjC's @available:
+  // i32 @__isOSVersionAtLeast(i32, i32, i32)
+  llvm::Constant *IsOSVersionAtLeastFn = nullptr;
+
   InstrProfStats &getPGOStats() { return PGOStats; }
   llvm::IndexedInstrProfReader *getPGOReader() const { return PGOReader.get(); }
 
@@ -1266,6 +1270,10 @@
   /// Emit any vtables which we deferred and still have a use for.
   void EmitDeferredVTables();
 
+  /// Emit a dummy function that reference a CoreFoundation symbol when
+  /// @available is used on Darwin.
+  void emitAtAvailableLinkGuard();
+
   /// Emit the llvm.used and llvm.compiler.used metadata.
   void emitLLVMUsed();
 
diff --git a/lib/CodeGen/CodeGenPGO.cpp b/lib/CodeGen/CodeGenPGO.cpp
index c6c3fa4..9e8d0d7 100644
--- a/lib/CodeGen/CodeGenPGO.cpp
+++ b/lib/CodeGen/CodeGenPGO.cpp
@@ -626,12 +626,14 @@
   // Constructors and destructors may be represented by several functions in IR.
   // If so, instrument only base variant, others are implemented by delegation
   // to the base one, it would be counted twice otherwise.
-  if (CGM.getTarget().getCXXABI().hasConstructorVariants() &&
-      ((isa<CXXConstructorDecl>(GD.getDecl()) &&
-        GD.getCtorType() != Ctor_Base) ||
-       (isa<CXXDestructorDecl>(GD.getDecl()) &&
-        GD.getDtorType() != Dtor_Base))) {
+  if (CGM.getTarget().getCXXABI().hasConstructorVariants()) {
+    if (isa<CXXDestructorDecl>(D) && GD.getDtorType() != Dtor_Base)
       return;
+
+    if (const auto *CCD = dyn_cast<CXXConstructorDecl>(D))
+      if (GD.getCtorType() != Ctor_Base &&
+          CodeGenFunction::IsConstructorDelegationValid(CCD))
+        return;
   }
   CGM.ClearUnusedCoverageMapping(D);
   setFuncName(Fn);
@@ -664,7 +666,7 @@
 }
 
 bool CodeGenPGO::skipRegionMappingForDecl(const Decl *D) {
-  if (SkipCoverageMapping)
+  if (!D->getBody())
     return true;
 
   // Don't map the functions in system headers.
@@ -737,7 +739,8 @@
   Fn->setEntryCount(FunctionCount);
 }
 
-void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S) {
+void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
+                                      llvm::Value *StepV) {
   if (!CGM.getCodeGenOpts().hasProfileClangInstr() || !RegionCounterMap)
     return;
   if (!Builder.GetInsertBlock())
@@ -745,11 +748,18 @@
 
   unsigned Counter = (*RegionCounterMap)[S];
   auto *I8PtrTy = llvm::Type::getInt8PtrTy(CGM.getLLVMContext());
-  Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
-                     {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
-                      Builder.getInt64(FunctionHash),
-                      Builder.getInt32(NumRegionCounters),
-                      Builder.getInt32(Counter)});
+
+  llvm::Value *Args[] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
+                         Builder.getInt64(FunctionHash),
+                         Builder.getInt32(NumRegionCounters),
+                         Builder.getInt32(Counter), StepV};
+  if (!StepV)
+    Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
+                       makeArrayRef(Args, 4));
+  else
+    Builder.CreateCall(
+        CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
+        makeArrayRef(Args));
 }
 
 // This method either inserts a call to the profile run-time during
diff --git a/lib/CodeGen/CodeGenPGO.h b/lib/CodeGen/CodeGenPGO.h
index 4f229cd..0759e65 100644
--- a/lib/CodeGen/CodeGenPGO.h
+++ b/lib/CodeGen/CodeGenPGO.h
@@ -40,14 +40,11 @@
   std::unique_ptr<llvm::InstrProfRecord> ProfRecord;
   std::vector<uint64_t> RegionCounts;
   uint64_t CurrentRegionCount;
-  /// \brief A flag that is set to true when this function doesn't need
-  /// to have coverage mapping data.
-  bool SkipCoverageMapping;
 
 public:
   CodeGenPGO(CodeGenModule &CGM)
-      : CGM(CGM), NumValueSites({{0}}), NumRegionCounters(0),
-        FunctionHash(0), CurrentRegionCount(0), SkipCoverageMapping(false) {}
+      : CGM(CGM), NumValueSites({{0}}), NumRegionCounters(0), FunctionHash(0),
+        CurrentRegionCount(0) {}
 
   /// Whether or not we have PGO region data for the current function. This is
   /// false both when we have no data at all and when our data has been
@@ -105,7 +102,8 @@
   void emitCounterRegionMapping(const Decl *D);
 
 public:
-  void emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S);
+  void emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
+                            llvm::Value *StepV);
 
   /// Return the region count for the counter at the given index.
   uint64_t getRegionCount(const Stmt *S) {
diff --git a/lib/CodeGen/ConstantBuilder.h b/lib/CodeGen/ConstantBuilder.h
deleted file mode 100644
index 40b34a9..0000000
--- a/lib/CodeGen/ConstantBuilder.h
+++ /dev/null
@@ -1,444 +0,0 @@
-//===----- ConstantBuilder.h - Builder for LLVM IR constants ----*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class provides a convenient interface for building complex
-// global initializers.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H
-#define LLVM_CLANG_LIB_CODEGEN_CONSTANTBUILDER_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/IR/Constants.h"
-
-#include "CodeGenModule.h"
-
-#include <vector>
-
-namespace clang {
-namespace CodeGen {
-
-class ConstantStructBuilder;
-class ConstantArrayBuilder;
-
-/// A convenience builder class for complex constant initializers,
-/// especially for anonymous global structures used by various language
-/// runtimes.
-///
-/// The basic usage pattern is expected to be something like:
-///    ConstantInitBuilder builder(CGM);
-///    auto toplevel = builder.beginStruct();
-///    toplevel.addInt(CGM.SizeTy, widgets.size());
-///    auto widgetArray = builder.beginArray();
-///    for (auto &widget : widgets) {
-///      auto widgetDesc = widgetArray.beginStruct();
-///      widgetDesc.addInt(CGM.SizeTy, widget.getPower());
-///      widgetDesc.add(CGM.GetAddrOfConstantString(widget.getName()));
-///      widgetDesc.add(CGM.GetAddrOfGlobal(widget.getInitializerDecl()));
-///      widgetArray.add(widgetDesc.finish());
-///    }
-///    toplevel.add(widgetArray.finish());
-///    auto global = toplevel.finishAndCreateGlobal("WIDGET_LIST", Align,
-///                                                 /*constant*/ true);
-class ConstantInitBuilder {
-  struct SelfReference {
-    llvm::GlobalVariable *Dummy;
-    llvm::SmallVector<llvm::Constant*, 4> Indices;
-
-    SelfReference(llvm::GlobalVariable *dummy) : Dummy(dummy) {}
-  };
-  CodeGenModule &CGM;
-  llvm::SmallVector<llvm::Constant*, 16> Buffer;
-  std::vector<SelfReference> SelfReferences;
-  bool Frozen = false;
-
-public:
-  explicit ConstantInitBuilder(CodeGenModule &CGM) : CGM(CGM) {}
-
-  ~ConstantInitBuilder() {
-    assert(Buffer.empty() && "didn't claim all values out of buffer");
-  }
-
-  class AggregateBuilderBase {
-  protected:
-    ConstantInitBuilder &Builder;
-    AggregateBuilderBase *Parent;
-    size_t Begin;
-    bool Finished = false;
-    bool Frozen = false;
-
-    llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() {
-      return Builder.Buffer;
-    }
-
-    const llvm::SmallVectorImpl<llvm::Constant*> &getBuffer() const {
-      return Builder.Buffer;
-    }
-
-    AggregateBuilderBase(ConstantInitBuilder &builder,
-                         AggregateBuilderBase *parent)
-        : Builder(builder), Parent(parent), Begin(builder.Buffer.size()) {
-      if (parent) {
-        assert(!parent->Frozen && "parent already has child builder active");
-        parent->Frozen = true;
-      } else {
-        assert(!builder.Frozen && "builder already has child builder active");
-        builder.Frozen = true;
-      }
-    }
-
-    ~AggregateBuilderBase() {
-      assert(Finished && "didn't finish aggregate builder");
-    }
-
-    void markFinished() {
-      assert(!Frozen && "child builder still active");
-      assert(!Finished && "builder already finished");
-      Finished = true;
-      if (Parent) {
-        assert(Parent->Frozen &&
-               "parent not frozen while child builder active");
-        Parent->Frozen = false;
-      } else {
-        assert(Builder.Frozen &&
-               "builder not frozen while child builder active");
-        Builder.Frozen = false;
-      }
-    }
-
-  public:
-    // Not copyable.
-    AggregateBuilderBase(const AggregateBuilderBase &) = delete;
-    AggregateBuilderBase &operator=(const AggregateBuilderBase &) = delete;
-
-    // Movable, mostly to allow returning.  But we have to write this out
-    // properly to satisfy the assert in the destructor.
-    AggregateBuilderBase(AggregateBuilderBase &&other)
-      : Builder(other.Builder), Parent(other.Parent), Begin(other.Begin),
-        Finished(other.Finished), Frozen(other.Frozen) {
-      other.Finished = false;
-    }
-    AggregateBuilderBase &operator=(AggregateBuilderBase &&other) = delete;
-
-    /// Abandon this builder completely.
-    void abandon() {
-      markFinished();
-      auto &buffer = Builder.Buffer;
-      buffer.erase(buffer.begin() + Begin, buffer.end());
-    }
-
-    /// Add a new value to this initializer.
-    void add(llvm::Constant *value) {
-      assert(value && "adding null value to constant initializer");
-      assert(!Finished && "cannot add more values after finishing builder");
-      assert(!Frozen && "cannot add values while subbuilder is active");
-      Builder.Buffer.push_back(value);
-    }
-
-    /// Add an integer value of type size_t.
-    void addSize(CharUnits size) {
-      add(Builder.CGM.getSize(size));
-    }
-
-    /// Add an integer value of a specific type.
-    void addInt(llvm::IntegerType *intTy, uint64_t value,
-                bool isSigned = false) {
-      add(llvm::ConstantInt::get(intTy, value, isSigned));
-    }
-
-    /// Add a null pointer of a specific type.
-    void addNullPointer(llvm::PointerType *ptrTy) {
-      add(llvm::ConstantPointerNull::get(ptrTy));
-    }
-
-    /// Add a bitcast of a value to a specific type.
-    void addBitCast(llvm::Constant *value, llvm::Type *type) {
-      add(llvm::ConstantExpr::getBitCast(value, type));
-    }
-
-    /// Add a bunch of new values to this initializer.
-    void addAll(ArrayRef<llvm::Constant *> values) {
-      assert(!Finished && "cannot add more values after finishing builder");
-      assert(!Frozen && "cannot add values while subbuilder is active");
-      Builder.Buffer.append(values.begin(), values.end());
-    }
-
-    /// An opaque class to hold the abstract position of a placeholder.
-    class PlaceholderPosition {
-      size_t Index;
-      friend class AggregateBuilderBase;
-      PlaceholderPosition(size_t index) : Index(index) {}
-    };
-
-    /// Add a placeholder value to the structure.  The returned position
-    /// can be used to set the value later; it will not be invalidated by
-    /// any intermediate operations except (1) filling the same position or
-    /// (2) finishing the entire builder.
-    ///
-    /// This is useful for emitting certain kinds of structure which
-    /// contain some sort of summary field, generaly a count, before any
-    /// of the data.  By emitting a placeholder first, the structure can
-    /// be emitted eagerly.
-    PlaceholderPosition addPlaceholder() {
-      assert(!Finished && "cannot add more values after finishing builder");
-      assert(!Frozen && "cannot add values while subbuilder is active");
-      Builder.Buffer.push_back(nullptr);
-      return Builder.Buffer.size() - 1;
-    }
-
-    /// Fill a previously-added placeholder.
-    void fillPlaceholderWithInt(PlaceholderPosition position,
-                                llvm::IntegerType *type, uint64_t value,
-                                bool isSigned = false) {
-      fillPlaceholder(position, llvm::ConstantInt::get(type, value, isSigned));
-    }
-
-    /// Fill a previously-added placeholder.
-    void fillPlaceholder(PlaceholderPosition position, llvm::Constant *value) {
-      assert(!Finished && "cannot change values after finishing builder");
-      assert(!Frozen && "cannot add values while subbuilder is active");
-      llvm::Constant *&slot = Builder.Buffer[position.Index];
-      assert(slot == nullptr && "placeholder already filled");
-      slot = value;
-    }
-
-    /// Produce an address which will eventually point to the the next
-    /// position to be filled.  This is computed with an indexed
-    /// getelementptr rather than by computing offsets.
-    ///
-    /// The returned pointer will have type T*, where T is the given
-    /// position.
-    llvm::Constant *getAddrOfCurrentPosition(llvm::Type *type) {
-      // Make a global variable.  We will replace this with a GEP to this
-      // position after installing the initializer.
-      auto dummy =
-        new llvm::GlobalVariable(Builder.CGM.getModule(), type, true,
-                                 llvm::GlobalVariable::PrivateLinkage,
-                                 nullptr, "");
-      Builder.SelfReferences.emplace_back(dummy);
-      auto &entry = Builder.SelfReferences.back();
-      (void) getGEPIndicesToCurrentPosition(entry.Indices);
-      return dummy;
-    }
-
-    ArrayRef<llvm::Constant*> getGEPIndicesToCurrentPosition(
-                             llvm::SmallVectorImpl<llvm::Constant*> &indices) {
-      getGEPIndicesTo(indices, Builder.Buffer.size());
-      return indices;
-    }
-
-    ConstantArrayBuilder beginArray(llvm::Type *eltTy = nullptr);
-    ConstantStructBuilder beginStruct(llvm::StructType *structTy = nullptr);
-
-  private:
-    void getGEPIndicesTo(llvm::SmallVectorImpl<llvm::Constant*> &indices,
-                         size_t position) const {
-      // Recurse on the parent builder if present.
-      if (Parent) {
-        Parent->getGEPIndicesTo(indices, Begin);
-
-      // Otherwise, add an index to drill into the first level of pointer. 
-      } else {
-        assert(indices.empty());
-        indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, 0));
-      }
-
-      assert(position >= Begin);
-      // We have to use i32 here because struct GEPs demand i32 indices.
-      // It's rather unlikely to matter in practice.
-      indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty,
-                                               position - Begin));
-    }
-  };
-
-  template <class Impl>
-  class AggregateBuilder : public AggregateBuilderBase {
-  protected:
-    AggregateBuilder(ConstantInitBuilder &builder,
-                     AggregateBuilderBase *parent)
-      : AggregateBuilderBase(builder, parent) {}
-
-    Impl &asImpl() { return *static_cast<Impl*>(this); }
-
-  public:
-    /// Given that this builder was created by beginning an array or struct
-    /// component on the given parent builder, finish the array/struct
-    /// component and add it to the parent.
-    ///
-    /// It is an intentional choice that the parent is passed in explicitly
-    /// despite it being redundant with information already kept in the
-    /// builder.  This aids in readability by making it easier to find the
-    /// places that add components to a builder, as well as "bookending"
-    /// the sub-builder more explicitly.
-    void finishAndAddTo(AggregateBuilderBase &parent) {
-      assert(Parent == &parent && "adding to non-parent builder");
-      parent.add(asImpl().finishImpl());
-    }
-
-    /// Given that this builder was created by beginning an array or struct
-    /// directly on a ConstantInitBuilder, finish the array/struct and
-    /// create a global variable with it as the initializer.
-    template <class... As>
-    llvm::GlobalVariable *finishAndCreateGlobal(As &&...args) {
-      assert(!Parent && "finishing non-root builder");
-      return Builder.createGlobal(asImpl().finishImpl(),
-                                  std::forward<As>(args)...);
-    }
-
-    /// Given that this builder was created by beginning an array or struct
-    /// directly on a ConstantInitBuilder, finish the array/struct and
-    /// set it as the initializer of the given global variable.
-    void finishAndSetAsInitializer(llvm::GlobalVariable *global) {
-      assert(!Parent && "finishing non-root builder");
-      return Builder.setGlobalInitializer(global, asImpl().finishImpl());
-    }
-  };
-
-  ConstantArrayBuilder beginArray(llvm::Type *eltTy = nullptr);
-
-  ConstantStructBuilder beginStruct(llvm::StructType *structTy = nullptr);
-
-private:
-  llvm::GlobalVariable *createGlobal(llvm::Constant *initializer,
-                                     const llvm::Twine &name,
-                                     CharUnits alignment,
-                                     bool constant = false,
-                                     llvm::GlobalValue::LinkageTypes linkage
-                                       = llvm::GlobalValue::InternalLinkage,
-                                     unsigned addressSpace = 0) {
-    auto GV = new llvm::GlobalVariable(CGM.getModule(),
-                                       initializer->getType(),
-                                       constant,
-                                       linkage,
-                                       initializer,
-                                       name,
-                                       /*insert before*/ nullptr,
-                                       llvm::GlobalValue::NotThreadLocal,
-                                       addressSpace);
-    GV->setAlignment(alignment.getQuantity());
-    resolveSelfReferences(GV);
-    return GV;
-  }
-
-  void setGlobalInitializer(llvm::GlobalVariable *GV,
-                            llvm::Constant *initializer) {
-    GV->setInitializer(initializer);
-    resolveSelfReferences(GV);
-  }
-
-  void resolveSelfReferences(llvm::GlobalVariable *GV) {
-    for (auto &entry : SelfReferences) {
-      llvm::Constant *resolvedReference =
-        llvm::ConstantExpr::getInBoundsGetElementPtr(
-          GV->getValueType(), GV, entry.Indices);
-      entry.Dummy->replaceAllUsesWith(resolvedReference);
-      entry.Dummy->eraseFromParent();
-    }
-  }
-};
-
-/// A helper class of ConstantInitBuilder, used for building constant
-/// array initializers.
-class ConstantArrayBuilder
-    : public ConstantInitBuilder::AggregateBuilder<ConstantArrayBuilder> {
-  llvm::Type *EltTy;
-  friend class ConstantInitBuilder;
-  template <class Impl> friend class ConstantInitBuilder::AggregateBuilder;
-  ConstantArrayBuilder(ConstantInitBuilder &builder,
-                       AggregateBuilderBase *parent, llvm::Type *eltTy)
-    : AggregateBuilder(builder, parent), EltTy(eltTy) {}
-public:
-  size_t size() const {
-    assert(!Finished);
-    assert(!Frozen);
-    assert(Begin <= getBuffer().size());
-    return getBuffer().size() - Begin;
-  }
-
-  bool empty() const {
-    return size() == 0;
-  }
-
-private:
-  /// Form an array constant from the values that have been added to this
-  /// builder.
-  llvm::Constant *finishImpl() {
-    markFinished();
-
-    auto &buffer = getBuffer();
-    assert((Begin < buffer.size() ||
-            (Begin == buffer.size() && EltTy))
-           && "didn't add any array elements without element type");
-    auto elts = llvm::makeArrayRef(buffer).slice(Begin);
-    auto eltTy = EltTy ? EltTy : elts[0]->getType();
-    auto type = llvm::ArrayType::get(eltTy, elts.size());
-    auto constant = llvm::ConstantArray::get(type, elts);
-    buffer.erase(buffer.begin() + Begin, buffer.end());
-    return constant;
-  }
-};
-
-inline ConstantArrayBuilder
-ConstantInitBuilder::beginArray(llvm::Type *eltTy) {
-  return ConstantArrayBuilder(*this, nullptr, eltTy);
-}
-
-inline ConstantArrayBuilder
-ConstantInitBuilder::AggregateBuilderBase::beginArray(llvm::Type *eltTy) {
-  return ConstantArrayBuilder(Builder, this, eltTy);
-}
-
-/// A helper class of ConstantInitBuilder, used for building constant
-/// struct initializers.
-class ConstantStructBuilder
-    : public ConstantInitBuilder::AggregateBuilder<ConstantStructBuilder> {
-  llvm::StructType *Ty;
-  friend class ConstantInitBuilder;
-  template <class Impl> friend class ConstantInitBuilder::AggregateBuilder;
-  ConstantStructBuilder(ConstantInitBuilder &builder,
-                        AggregateBuilderBase *parent, llvm::StructType *ty)
-    : AggregateBuilder(builder, parent), Ty(ty) {}
-
-  /// Finish the struct.
-  llvm::Constant *finishImpl() {
-    markFinished();
-
-    auto &buffer = getBuffer();
-    assert(Begin < buffer.size() && "didn't add any struct elements?");
-    auto elts = llvm::makeArrayRef(buffer).slice(Begin);
-
-    llvm::Constant *constant;
-    if (Ty) {
-      constant = llvm::ConstantStruct::get(Ty, elts);
-    } else {
-      constant = llvm::ConstantStruct::getAnon(elts, /*packed*/ false);
-    }
-
-    buffer.erase(buffer.begin() + Begin, buffer.end());
-    return constant;
-  }
-};
-
-inline ConstantStructBuilder
-ConstantInitBuilder::beginStruct(llvm::StructType *structTy) {
-  return ConstantStructBuilder(*this, nullptr, structTy);
-}
-
-inline ConstantStructBuilder
-ConstantInitBuilder::AggregateBuilderBase::beginStruct(
-                                                  llvm::StructType *structTy) {
-  return ConstantStructBuilder(Builder, this, structTy);
-}
-
-}  // end namespace CodeGen
-}  // end namespace clang
-
-#endif
diff --git a/lib/CodeGen/ConstantInitBuilder.cpp b/lib/CodeGen/ConstantInitBuilder.cpp
new file mode 100644
index 0000000..7f8d809
--- /dev/null
+++ b/lib/CodeGen/ConstantInitBuilder.cpp
@@ -0,0 +1,280 @@
+//===--- ConstantInitBuilder.cpp - Global initializer builder -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines out-of-line routines for building initializers for
+// global variables, in particular the kind of globals that are implicitly
+// introduced by various language ABIs.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/CodeGen/ConstantInitBuilder.h"
+#include "CodeGenModule.h"
+
+using namespace clang;
+using namespace CodeGen;
+
+llvm::Type *ConstantInitFuture::getType() const {
+  assert(Data && "dereferencing null future");
+  if (Data.is<llvm::Constant*>()) {
+    return Data.get<llvm::Constant*>()->getType();
+  } else {
+    return Data.get<ConstantInitBuilderBase*>()->Buffer[0]->getType();
+  }
+}
+
+void ConstantInitFuture::abandon() {
+  assert(Data && "abandoning null future");
+  if (auto builder = Data.dyn_cast<ConstantInitBuilderBase*>()) {
+    builder->abandon(0);
+  }
+  Data = nullptr;
+}
+
+void ConstantInitFuture::installInGlobal(llvm::GlobalVariable *GV) {
+  assert(Data && "installing null future");
+  if (Data.is<llvm::Constant*>()) {
+    GV->setInitializer(Data.get<llvm::Constant*>());
+  } else {
+    auto &builder = *Data.get<ConstantInitBuilderBase*>();
+    assert(builder.Buffer.size() == 1);
+    builder.setGlobalInitializer(GV, builder.Buffer[0]);
+    builder.Buffer.clear();
+    Data = nullptr;
+  }
+}
+
+ConstantInitFuture
+ConstantInitBuilderBase::createFuture(llvm::Constant *initializer) {
+  assert(Buffer.empty() && "buffer not current empty");
+  Buffer.push_back(initializer);
+  return ConstantInitFuture(this);
+}
+
+// Only used in this file.
+inline ConstantInitFuture::ConstantInitFuture(ConstantInitBuilderBase *builder)
+    : Data(builder) {
+  assert(!builder->Frozen);
+  assert(builder->Buffer.size() == 1);
+  assert(builder->Buffer[0] != nullptr);
+}
+
+llvm::GlobalVariable *
+ConstantInitBuilderBase::createGlobal(llvm::Constant *initializer,
+                                      const llvm::Twine &name,
+                                      CharUnits alignment,
+                                      bool constant,
+                                      llvm::GlobalValue::LinkageTypes linkage,
+                                      unsigned addressSpace) {
+  auto GV = new llvm::GlobalVariable(CGM.getModule(),
+                                     initializer->getType(),
+                                     constant,
+                                     linkage,
+                                     initializer,
+                                     name,
+                                     /*insert before*/ nullptr,
+                                     llvm::GlobalValue::NotThreadLocal,
+                                     addressSpace);
+  GV->setAlignment(alignment.getQuantity());
+  resolveSelfReferences(GV);
+  return GV;
+}
+
+void ConstantInitBuilderBase::setGlobalInitializer(llvm::GlobalVariable *GV,
+                                                   llvm::Constant *initializer){
+  GV->setInitializer(initializer);
+
+  if (!SelfReferences.empty())
+    resolveSelfReferences(GV);
+}
+
+void ConstantInitBuilderBase::resolveSelfReferences(llvm::GlobalVariable *GV) {
+  for (auto &entry : SelfReferences) {
+    llvm::Constant *resolvedReference =
+      llvm::ConstantExpr::getInBoundsGetElementPtr(
+        GV->getValueType(), GV, entry.Indices);
+    auto dummy = entry.Dummy;
+    dummy->replaceAllUsesWith(resolvedReference);
+    dummy->eraseFromParent();
+  }
+  SelfReferences.clear();
+}
+
+void ConstantInitBuilderBase::abandon(size_t newEnd) {
+  // Remove all the entries we've added.
+  Buffer.erase(Buffer.begin() + newEnd, Buffer.end());
+
+  // If we're abandoning all the way to the beginning, destroy
+  // all the self-references, because we might not get another
+  // opportunity.
+  if (newEnd == 0) {
+    for (auto &entry : SelfReferences) {
+      auto dummy = entry.Dummy;
+      dummy->replaceAllUsesWith(llvm::UndefValue::get(dummy->getType()));
+      dummy->eraseFromParent();
+    }
+    SelfReferences.clear();
+  }
+}
+
+void ConstantAggregateBuilderBase::addSize(CharUnits size) {
+  add(Builder.CGM.getSize(size));
+}
+
+llvm::Constant *
+ConstantAggregateBuilderBase::getRelativeOffset(llvm::IntegerType *offsetType,
+                                                llvm::Constant *target) {
+  // Compute the address of the relative-address slot.
+  auto base = getAddrOfCurrentPosition(offsetType);
+
+  // Subtract.
+  base = llvm::ConstantExpr::getPtrToInt(base, Builder.CGM.IntPtrTy);
+  target = llvm::ConstantExpr::getPtrToInt(target, Builder.CGM.IntPtrTy);
+  llvm::Constant *offset = llvm::ConstantExpr::getSub(target, base);
+
+  // Truncate to the relative-address type if necessary.
+  if (Builder.CGM.IntPtrTy != offsetType) {
+    offset = llvm::ConstantExpr::getTrunc(offset, offsetType);
+  }
+
+  return offset;
+}
+
+llvm::Constant *
+ConstantAggregateBuilderBase::getAddrOfCurrentPosition(llvm::Type *type) {
+  // Make a global variable.  We will replace this with a GEP to this
+  // position after installing the initializer.
+  auto dummy =
+    new llvm::GlobalVariable(Builder.CGM.getModule(), type, true,
+                             llvm::GlobalVariable::PrivateLinkage,
+                             nullptr, "");
+  Builder.SelfReferences.emplace_back(dummy);
+  auto &entry = Builder.SelfReferences.back();
+  (void) getGEPIndicesToCurrentPosition(entry.Indices);
+  return dummy;
+}
+
+void ConstantAggregateBuilderBase::getGEPIndicesTo(
+                               llvm::SmallVectorImpl<llvm::Constant*> &indices,
+                               size_t position) const {
+  // Recurse on the parent builder if present.
+  if (Parent) {
+    Parent->getGEPIndicesTo(indices, Begin);
+
+  // Otherwise, add an index to drill into the first level of pointer. 
+  } else {
+    assert(indices.empty());
+    indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty, 0));
+  }
+
+  assert(position >= Begin);
+  // We have to use i32 here because struct GEPs demand i32 indices.
+  // It's rather unlikely to matter in practice.
+  indices.push_back(llvm::ConstantInt::get(Builder.CGM.Int32Ty,
+                                           position - Begin));
+}
+
+ConstantAggregateBuilderBase::PlaceholderPosition
+ConstantAggregateBuilderBase::addPlaceholderWithSize(llvm::Type *type) {
+  // Bring the offset up to the last field.
+  CharUnits offset = getNextOffsetFromGlobal();
+
+  // Create the placeholder.
+  auto position = addPlaceholder();
+
+  // Advance the offset past that field.
+  auto &layout = Builder.CGM.getDataLayout();
+  if (!Packed)
+    offset = offset.alignTo(CharUnits::fromQuantity(
+                                layout.getABITypeAlignment(type)));
+  offset += CharUnits::fromQuantity(layout.getTypeStoreSize(type));
+
+  CachedOffsetEnd = Builder.Buffer.size();
+  CachedOffsetFromGlobal = offset;
+
+  return position;
+}
+
+CharUnits ConstantAggregateBuilderBase::getOffsetFromGlobalTo(size_t end) const{
+  size_t cacheEnd = CachedOffsetEnd;
+  assert(cacheEnd <= end);
+
+  // Fast path: if the cache is valid, just use it.
+  if (cacheEnd == end) {
+    return CachedOffsetFromGlobal;
+  }
+
+  // If the cached range ends before the index at which the current
+  // aggregate starts, recurse for the parent.
+  CharUnits offset;
+  if (cacheEnd < Begin) {
+    assert(cacheEnd == 0);
+    assert(Parent && "Begin != 0 for root builder");
+    cacheEnd = Begin;
+    offset = Parent->getOffsetFromGlobalTo(Begin);
+  } else {
+    offset = CachedOffsetFromGlobal;
+  }
+
+  // Perform simple layout on the elements in cacheEnd..<end.
+  if (cacheEnd != end) {
+    auto &layout = Builder.CGM.getDataLayout();
+    do {
+      llvm::Constant *element = Builder.Buffer[cacheEnd];
+      assert(element != nullptr &&
+             "cannot compute offset when a placeholder is present");
+      llvm::Type *elementType = element->getType();
+      if (!Packed)
+        offset = offset.alignTo(CharUnits::fromQuantity(
+                                  layout.getABITypeAlignment(elementType)));
+      offset += CharUnits::fromQuantity(layout.getTypeStoreSize(elementType));
+    } while (++cacheEnd != end);
+  }
+
+  // Cache and return.
+  CachedOffsetEnd = cacheEnd;
+  CachedOffsetFromGlobal = offset;
+  return offset;
+}
+
+llvm::Constant *ConstantAggregateBuilderBase::finishArray(llvm::Type *eltTy) {
+  markFinished();
+
+  auto &buffer = getBuffer();
+  assert((Begin < buffer.size() ||
+          (Begin == buffer.size() && eltTy))
+         && "didn't add any array elements without element type");
+  auto elts = llvm::makeArrayRef(buffer).slice(Begin);
+  if (!eltTy) eltTy = elts[0]->getType();
+  auto type = llvm::ArrayType::get(eltTy, elts.size());
+  auto constant = llvm::ConstantArray::get(type, elts);
+  buffer.erase(buffer.begin() + Begin, buffer.end());
+  return constant;
+}
+
+llvm::Constant *
+ConstantAggregateBuilderBase::finishStruct(llvm::StructType *ty) {
+  markFinished();
+
+  auto &buffer = getBuffer();
+  auto elts = llvm::makeArrayRef(buffer).slice(Begin);
+
+  if (ty == nullptr && elts.empty())
+    ty = llvm::StructType::get(Builder.CGM.getLLVMContext(), {}, Packed);
+
+  llvm::Constant *constant;
+  if (ty) {
+    assert(ty->isPacked() == Packed);
+    constant = llvm::ConstantStruct::get(ty, elts);
+  } else {
+    constant = llvm::ConstantStruct::getAnon(elts, Packed);
+  }
+
+  buffer.erase(buffer.begin() + Begin, buffer.end());
+  return constant;
+}
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index f7a8dd6..fe1fbd1 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -24,8 +24,8 @@
 #include "CGVTables.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
-#include "ConstantBuilder.h"
 #include "TargetInfo.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/StmtCXX.h"
@@ -2015,10 +2015,11 @@
 
     // The ABI says: "It is suggested that it be emitted in the same COMDAT
     // group as the associated data object." In practice, this doesn't work for
-    // non-ELF object formats, so only do it for ELF.
+    // non-ELF and non-Wasm object formats, so only do it for ELF and Wasm.
     llvm::Comdat *C = var->getComdat();
     if (!D.isLocalVarDecl() && C &&
-        CGM.getTarget().getTriple().isOSBinFormatELF()) {
+        (CGM.getTarget().getTriple().isOSBinFormatELF() ||
+         CGM.getTarget().getTriple().isOSBinFormatWasm())) {
       guard->setComdat(C);
       // An inline variable's guard function is run from the per-TU
       // initialization function, not via a dedicated global ctor function, so
@@ -3534,8 +3535,9 @@
     return StructorCodegen::RAUW;
 
   if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
-    // Only ELF supports COMDATs with arbitrary names (C5/D5).
-    if (CGM.getTarget().getTriple().isOSBinFormatELF())
+    // Only ELF and wasm support COMDATs with arbitrary names (C5/D5).
+    if (CGM.getTarget().getTriple().isOSBinFormatELF() ||
+        CGM.getTarget().getTriple().isOSBinFormatWasm())
       return StructorCodegen::COMDAT;
     return StructorCodegen::Emit;
   }
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 38df455..ac9f8d3 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -19,8 +19,8 @@
 #include "CGVTables.h"
 #include "CodeGenModule.h"
 #include "CodeGenTypes.h"
-#include "ConstantBuilder.h"
 #include "TargetInfo.h"
+#include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/StmtCXX.h"
diff --git a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
index 754f996..37ecc05a 100644
--- a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -171,7 +171,8 @@
     // Prepare CGDebugInfo to emit debug info for a clang module.
     auto *DI = Builder->getModuleDebugInfo();
     StringRef ModuleName = llvm::sys::path::filename(MainFileName);
-    DI->setPCHDescriptor({ModuleName, "", OutputFileName, ~1ULL});
+    DI->setPCHDescriptor({ModuleName, "", OutputFileName,
+                          ASTFileSignature{{{~0U, ~0U, ~0U, ~0U, ~1U}}}});
     DI->setModuleMap(MMap);
   }
 
@@ -241,7 +242,11 @@
 
     // PCH files don't have a signature field in the control block,
     // but LLVM detects DWO CUs by looking for a non-zero DWO id.
-    uint64_t Signature = Buffer->Signature ? Buffer->Signature : ~1ULL;
+    // We use the lower 64 bits for debug info.
+    uint64_t Signature =
+        Buffer->Signature
+            ? (uint64_t)Buffer->Signature[1] << 32 | Buffer->Signature[0]
+            : ~1ULL;
     Builder->getModuleDebugInfo()->setDwoId(Signature);
 
     // Finalize the Builder.
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index d2fc388..e843270 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -4811,6 +4811,9 @@
   bool isSwiftErrorInRegister() const override {
     return true;
   }
+
+  bool isLegalVectorTypeForSwift(CharUnits totalSize, llvm::Type *eltTy,
+                                 unsigned elts) const override;
 };
 
 class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
@@ -4877,10 +4880,16 @@
 
   // Empty records are always ignored on Darwin, but actually passed in C++ mode
   // elsewhere for GNU compatibility.
-  if (isEmptyRecord(getContext(), Ty, true)) {
+  uint64_t Size = getContext().getTypeSize(Ty);
+  bool IsEmpty = isEmptyRecord(getContext(), Ty, true);
+  if (IsEmpty || Size == 0) {
     if (!getContext().getLangOpts().CPlusPlus || isDarwinPCS())
       return ABIArgInfo::getIgnore();
 
+    // GNU C mode. The only argument that gets ignored is an empty one with size
+    // 0.
+    if (IsEmpty && Size == 0)
+      return ABIArgInfo::getIgnore();
     return ABIArgInfo::getDirect(llvm::Type::getInt8Ty(getVMContext()));
   }
 
@@ -4893,7 +4902,6 @@
   }
 
   // Aggregates <= 16 bytes are passed directly in registers or on the stack.
-  uint64_t Size = getContext().getTypeSize(Ty);
   if (Size <= 128) {
     // On RenderScript, coerce Aggregates <= 16 bytes to an integer array of
     // same size and alignment.
@@ -4933,7 +4941,8 @@
                 : ABIArgInfo::getDirect());
   }
 
-  if (isEmptyRecord(getContext(), RetTy, true))
+  uint64_t Size = getContext().getTypeSize(RetTy);
+  if (isEmptyRecord(getContext(), RetTy, true) || Size == 0)
     return ABIArgInfo::getIgnore();
 
   const Type *Base = nullptr;
@@ -4943,7 +4952,6 @@
     return ABIArgInfo::getDirect();
 
   // Aggregates <= 16 bytes are returned directly in registers or on the stack.
-  uint64_t Size = getContext().getTypeSize(RetTy);
   if (Size <= 128) {
     // On RenderScript, coerce Aggregates <= 16 bytes to an integer array of
     // same size and alignment.
@@ -4979,6 +4987,17 @@
   return false;
 }
 
+bool AArch64ABIInfo::isLegalVectorTypeForSwift(CharUnits totalSize,
+                                               llvm::Type *eltTy,
+                                               unsigned elts) const {
+  if (!llvm::isPowerOf2_32(elts))
+    return false;
+  if (totalSize.getQuantity() != 8 &&
+      (totalSize.getQuantity() != 16 || elts == 1))
+    return false;
+  return true;
+}
+
 bool AArch64ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
   // Homogeneous aggregates for AAPCS64 must have base types of a floating
   // point type or a short-vector type. This is the same as the 32-bit ABI,
@@ -5367,6 +5386,8 @@
   bool isSwiftErrorInRegister() const override {
     return true;
   }
+  bool isLegalVectorTypeForSwift(CharUnits totalSize, llvm::Type *eltTy,
+                                 unsigned elts) const override;
 };
 
 class ARMTargetCodeGenInfo : public TargetCodeGenInfo {
@@ -5882,6 +5903,20 @@
   return false;
 }
 
+bool ARMABIInfo::isLegalVectorTypeForSwift(CharUnits vectorSize,
+                                           llvm::Type *eltTy,
+                                           unsigned numElts) const {
+  if (!llvm::isPowerOf2_32(numElts))
+    return false;
+  unsigned size = getDataLayout().getTypeStoreSizeInBits(eltTy);
+  if (size > 64)
+    return false;
+  if (vectorSize.getQuantity() != 8 &&
+      (vectorSize.getQuantity() != 16 || numElts == 1))
+    return false;
+  return true;
+}
+
 bool ARMABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
   // Homogeneous aggregates for AAPCS-VFP must have base types of float,
   // double, or 64-bit or 128-bit vectors.
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 15f830d..c32f8a4 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -62,7 +62,7 @@
       CCCPrintBindings(false), CCPrintHeaders(false), CCLogDiagnostics(false),
       CCGenDiagnostics(false), DefaultTargetTriple(DefaultTargetTriple),
       CCCGenericGCCName(""), CheckInputsExist(true), CCCUsePCH(true),
-      SuppressMissingInputWarning(false) {
+      GenReproducer(false), SuppressMissingInputWarning(false) {
 
   // Provide a sane fallback if no VFS is specified.
   if (!this->VFS)
@@ -79,7 +79,8 @@
     llvm::sys::path::append(P, ClangResourceDir);
   } else {
     StringRef ClangLibdirSuffix(CLANG_LIBDIR_SUFFIX);
-    llvm::sys::path::append(P, "..", Twine("lib") + ClangLibdirSuffix, "clang",
+    P = llvm::sys::path::parent_path(Dir);
+    llvm::sys::path::append(P, Twine("lib") + ClangLibdirSuffix, "clang",
                             CLANG_VERSION_STRING);
   }
   ResourceDir = P.str();
@@ -596,6 +597,9 @@
     CCCGenericGCCName = A->getValue();
   CCCUsePCH =
       Args.hasFlag(options::OPT_ccc_pch_is_pch, options::OPT_ccc_pch_is_pth);
+  GenReproducer = Args.hasFlag(options::OPT_gen_reproducer,
+                               options::OPT_fno_crash_diagnostics,
+                               !!::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH"));
   // FIXME: DefaultTargetTriple is used by the target-prefixed calls to as/ld
   // and getToolChain is const.
   if (IsCLMode()) {
@@ -3186,7 +3190,8 @@
   const JobAction *JA = cast<JobAction>(A);
   ActionList CollapsedOffloadActions;
 
-  ToolSelector TS(JA, *TC, C, isSaveTempsEnabled(), embedBitcodeInObject());
+  ToolSelector TS(JA, *TC, C, isSaveTempsEnabled(),
+                  embedBitcodeInObject() && !isUsingLTO());
   const Tool *T = TS.getTool(Inputs, CollapsedOffloadActions);
 
   if (!T)
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 9fd8808..595d6e6 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -88,6 +88,8 @@
     return HaveCrashVFS ? false : true;
   if (FlagRef.startswith("-fmodules-cache-path="))
     return true;
+  if (FlagRef.startswith("-fapinotes-cache-path="))
+    return true;
 
   SkipNum = 0;
   return false;
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index f4f6dad..de06000 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -26,18 +26,19 @@
 using namespace llvm::opt;
 
 enum : SanitizerMask {
-  NeedsUbsanRt = Undefined | Integer | CFI,
+  NeedsUbsanRt = Undefined | Integer | Nullability | CFI,
   NeedsUbsanCxxRt = Vptr | CFI,
   NotAllowedWithTrap = Vptr,
   RequiresPIE = DataFlow,
   NeedsUnwindTables = Address | Thread | Memory | DataFlow,
-  SupportsCoverage = Address | Memory | Leak | Undefined | Integer | DataFlow,
-  RecoverableByDefault = Undefined | Integer,
+  SupportsCoverage =
+      Address | Memory | Leak | Undefined | Integer | Nullability | DataFlow,
+  RecoverableByDefault = Undefined | Integer | Nullability,
   Unrecoverable = Unreachable | Return,
   LegacyFsanitizeRecoverMask = Undefined | Integer,
   NeedsLTO = CFI,
-  TrappingSupported =
-      (Undefined & ~Vptr) | UnsignedIntegerOverflow | LocalBounds | CFI,
+  TrappingSupported = (Undefined & ~Vptr) | UnsignedIntegerOverflow |
+                      Nullability | LocalBounds | CFI,
   TrappingDefault = CFI,
   CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
 };
@@ -573,12 +574,11 @@
       }
     }
 
-    if (Arg *A = Args.getLastArg(
-            options::OPT_fsanitize_address_use_after_scope,
-            options::OPT_fno_sanitize_address_use_after_scope)) {
-      AsanUseAfterScope = A->getOption().getID() ==
-                          options::OPT_fsanitize_address_use_after_scope;
-    }
+    AsanUseAfterScope = Args.hasFlag(
+        options::OPT_fsanitize_address_use_after_scope,
+        options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
+  } else {
+    AsanUseAfterScope = false;
   }
 
   // Parse -link-cxx-sanitizer flag.
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index 6adc038..b385868 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -682,7 +682,8 @@
   // platform dependent.
   using namespace SanitizerKind;
   SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) |
-                      CFICastStrict | UnsignedIntegerOverflow | LocalBounds;
+                      CFICastStrict | UnsignedIntegerOverflow | Nullability |
+                      LocalBounds;
   if (getTriple().getArch() == llvm::Triple::x86 ||
       getTriple().getArch() == llvm::Triple::x86_64 ||
       getTriple().getArch() == llvm::Triple::arm ||
diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp
index 9bc9ae4..d01e31f 100644
--- a/lib/Driver/ToolChains.cpp
+++ b/lib/Driver/ToolChains.cpp
@@ -533,9 +533,22 @@
   }
 
   Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
-  Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ);
-  Arg *TvOSVersion = Args.getLastArg(options::OPT_mtvos_version_min_EQ);
-  Arg *WatchOSVersion = Args.getLastArg(options::OPT_mwatchos_version_min_EQ);
+  Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ,
+                                    options::OPT_mios_simulator_version_min_EQ);
+  Arg *TvOSVersion =
+      Args.getLastArg(options::OPT_mtvos_version_min_EQ,
+                      options::OPT_mtvos_simulator_version_min_EQ);
+  Arg *WatchOSVersion =
+      Args.getLastArg(options::OPT_mwatchos_version_min_EQ,
+                      options::OPT_mwatchos_simulator_version_min_EQ);
+
+  // Add a macro to differentiate between m(iphone|tv|watch)os-version-min=X.Y and
+  // -m(iphone|tv|watch)simulator-version-min=X.Y.
+  if (Args.hasArg(options::OPT_mios_simulator_version_min_EQ) ||
+      Args.hasArg(options::OPT_mtvos_simulator_version_min_EQ) ||
+      Args.hasArg(options::OPT_mwatchos_simulator_version_min_EQ))
+    Args.append(Args.MakeSeparateArg(nullptr, Opts.getOption(options::OPT_D),
+                                     " __APPLE_EMBEDDED_SIMULATOR__=1"));
 
   if (OSXVersion && (iOSVersion || TvOSVersion || WatchOSVersion)) {
     getDriver().Diag(diag::err_drv_argument_not_allowed_with)
@@ -1109,10 +1122,6 @@
                      options::OPT_fno_omit_frame_pointer, false))
       getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
           << "-fomit-frame-pointer" << BoundArch;
-    if (Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
-                     options::OPT_mno_omit_leaf_frame_pointer, false))
-      getDriver().Diag(clang::diag::warn_drv_unsupported_opt_for_target)
-          << "-momit-leaf-frame-pointer" << BoundArch;
   }
 
   return DAL;
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 4d4a8c2..fd294c2 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -1369,9 +1369,9 @@
                                options::OPT_mno_global_merge)) {
     CmdArgs.push_back("-backend-option");
     if (A->getOption().matches(options::OPT_mno_global_merge))
-      CmdArgs.push_back("-aarch64-global-merge=false");
+      CmdArgs.push_back("-aarch64-enable-global-merge=false");
     else
-      CmdArgs.push_back("-aarch64-global-merge=true");
+      CmdArgs.push_back("-aarch64-enable-global-merge=true");
   }
 }
 
@@ -3415,7 +3415,7 @@
   return false;
 }
 
-static bool mustUseFramePointerForTarget(const llvm::Triple &Triple) {
+static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
   switch (Triple.getArch()){
   default:
     return false;
@@ -3481,7 +3481,7 @@
   if (Arg *A = Args.getLastArg(options::OPT_fno_omit_frame_pointer,
                                options::OPT_fomit_frame_pointer))
     return A->getOption().matches(options::OPT_fno_omit_frame_pointer) ||
-           mustUseFramePointerForTarget(Triple);
+           mustUseNonLeafFramePointerForTarget(Triple);
 
   if (Args.hasArg(options::OPT_pg))
     return true;
@@ -3493,8 +3493,7 @@
                                       const llvm::Triple &Triple) {
   if (Arg *A = Args.getLastArg(options::OPT_mno_omit_leaf_frame_pointer,
                                options::OPT_momit_leaf_frame_pointer))
-    return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer) ||
-           mustUseFramePointerForTarget(Triple);
+    return A->getOption().matches(options::OPT_mno_omit_leaf_frame_pointer);
 
   if (Args.hasArg(options::OPT_pg))
     return true;
@@ -4258,14 +4257,14 @@
   }
 
   // Embed-bitcode option.
-  if (C.getDriver().embedBitcodeInObject() &&
+  if (C.getDriver().embedBitcodeInObject() && !C.getDriver().isUsingLTO() &&
       (isa<BackendJobAction>(JA) || isa<AssembleJobAction>(JA))) {
     // Add flags implied by -fembed-bitcode.
     Args.AddLastArg(CmdArgs, options::OPT_fembed_bitcode_EQ);
     // Disable all llvm IR level optimizations.
     CmdArgs.push_back("-disable-llvm-passes");
   }
-  if (C.getDriver().embedBitcodeMarkerOnly())
+  if (C.getDriver().embedBitcodeMarkerOnly() && !C.getDriver().isUsingLTO())
     CmdArgs.push_back("-fembed-bitcode=marker");
 
   // We normally speed up the clang process a bit by skipping destructors at
@@ -4487,6 +4486,9 @@
   if (!Args.hasFlag(options::OPT_fstrict_return, options::OPT_fno_strict_return,
                     true))
     CmdArgs.push_back("-fno-strict-return");
+  if (Args.hasFlag(options::OPT_fallow_editor_placeholders,
+                   options::OPT_fno_allow_editor_placeholders, false))
+    CmdArgs.push_back("-fallow-editor-placeholders");
   if (Args.hasFlag(options::OPT_fstrict_vtable_pointers,
                    options::OPT_fno_strict_vtable_pointers,
                    false))
@@ -5646,6 +5648,42 @@
                     options::OPT_fno_assume_sane_operator_new))
     CmdArgs.push_back("-fno-assume-sane-operator-new");
 
+  if (Args.hasFlag(options::OPT_fapinotes, options::OPT_fno_apinotes,
+                   false) ||
+      Args.hasFlag(options::OPT_fapinotes_modules,
+                     options::OPT_fno_apinotes_modules, false) ||
+      Args.hasArg(options::OPT_iapinotes_modules)) {
+    if (Args.hasFlag(options::OPT_fapinotes, options::OPT_fno_apinotes, false))
+      CmdArgs.push_back("-fapinotes");
+    if (Args.hasFlag(options::OPT_fapinotes_modules,
+                     options::OPT_fno_apinotes_modules, false))
+      CmdArgs.push_back("-fapinotes-modules");
+
+    SmallString<128> APINotesCachePath;
+    if (Arg *A = Args.getLastArg(options::OPT_fapinotes_cache_path)) {
+      APINotesCachePath = A->getValue();
+    }
+
+    if (C.isForDiagnostics()) {
+      // When generating crash reports, we want to emit the API notes along with
+      // the reproduction sources, so we ignore any provided API notes path.
+      APINotesCachePath = Output.getFilename();
+      llvm::sys::path::replace_extension(APINotesCachePath, ".cache");
+      llvm::sys::path::append(APINotesCachePath, "apinotes");
+    } else if (APINotesCachePath.empty()) {
+      // No API notes path was provided: use the default.
+      llvm::sys::path::system_temp_directory(/*erasedOnReboot=*/false,
+                                             APINotesCachePath);
+      llvm::sys::path::append(APINotesCachePath, "org.llvm.clang");
+      llvm::sys::path::append(APINotesCachePath, "APINotesCache");
+    }
+    const char Arg[] = "-fapinotes-cache-path=";
+    APINotesCachePath.insert(APINotesCachePath.begin(), Arg, Arg + strlen(Arg));
+    CmdArgs.push_back(Args.MakeArgString(APINotesCachePath));
+
+    Args.AddLastArg(CmdArgs, options::OPT_fapinotes_swift_version);
+  }
+
   // -fblocks=0 is default.
   if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
                    getToolChain().IsBlocksDefault()) ||
@@ -6457,7 +6495,8 @@
   // pristine IR generated by the frontend. Ideally, a new compile action should
   // be added so both IR can be captured.
   if (C.getDriver().isSaveTempsEnabled() &&
-      !C.getDriver().embedBitcodeInObject() && isa<CompileJobAction>(JA))
+      !C.getDriver().embedBitcodeInObject() && !C.getDriver().isUsingLTO() &&
+      isa<CompileJobAction>(JA))
     CmdArgs.push_back("-disable-llvm-passes");
 
   if (Output.getType() == types::TY_Dependencies) {
@@ -8430,9 +8469,13 @@
   // for embed-bitcode, use -bitcode_bundle in linker command
   if (C.getDriver().embedBitcodeEnabled()) {
     // Check if the toolchain supports bitcode build flow.
-    if (MachOTC.SupportsEmbeddedBitcode())
+    if (MachOTC.SupportsEmbeddedBitcode()) {
       CmdArgs.push_back("-bitcode_bundle");
-    else
+      if (C.getDriver().embedBitcodeMarkerOnly() && Version[0] >= 278) {
+        CmdArgs.push_back("-bitcode_process_mode");
+        CmdArgs.push_back("marker");
+      }
+    } else
       D.Diag(diag::err_drv_bitcode_unsupported_on_toolchain);
   }
 
diff --git a/lib/Edit/EditedSource.cpp b/lib/Edit/EditedSource.cpp
index 5292a58..1a7a68c 100644
--- a/lib/Edit/EditedSource.cpp
+++ b/lib/Edit/EditedSource.cpp
@@ -363,13 +363,14 @@
 
 static void applyRewrite(EditsReceiver &receiver,
                          StringRef text, FileOffset offs, unsigned len,
-                         const SourceManager &SM, const LangOptions &LangOpts) {
+                         const SourceManager &SM, const LangOptions &LangOpts,
+                         bool shouldAdjustRemovals) {
   assert(offs.getFID().isValid());
   SourceLocation Loc = SM.getLocForStartOfFile(offs.getFID());
   Loc = Loc.getLocWithOffset(offs.getOffset());
   assert(Loc.isFileID());
 
-  if (text.empty())
+  if (text.empty() && shouldAdjustRemovals)
     adjustRemoval(SM, LangOpts, Loc, offs, len, text);
 
   CharSourceRange range = CharSourceRange::getCharRange(Loc,
@@ -387,7 +388,8 @@
     receiver.insert(Loc, text);
 }
 
-void EditedSource::applyRewrites(EditsReceiver &receiver) {
+void EditedSource::applyRewrites(EditsReceiver &receiver,
+                                 bool shouldAdjustRemovals) {
   SmallString<128> StrVec;
   FileOffset CurOffs, CurEnd;
   unsigned CurLen;
@@ -414,14 +416,16 @@
       continue;
     }
 
-    applyRewrite(receiver, StrVec, CurOffs, CurLen, SourceMgr, LangOpts);
+    applyRewrite(receiver, StrVec, CurOffs, CurLen, SourceMgr, LangOpts,
+                 shouldAdjustRemovals);
     CurOffs = offs;
     StrVec = act.Text;
     CurLen = act.RemoveLen;
     CurEnd = CurOffs.getWithOffset(CurLen);
   }
 
-  applyRewrite(receiver, StrVec, CurOffs, CurLen, SourceMgr, LangOpts);
+  applyRewrite(receiver, StrVec, CurOffs, CurLen, SourceMgr, LangOpts,
+               shouldAdjustRemovals);
 }
 
 void EditedSource::clearRewrites() {
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index 6bb6fb3..2f8446e 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -560,7 +560,6 @@
   // and we need to avoid bin packing there.
   bool NestedBlockSpecialCase =
       Style.Language != FormatStyle::LK_Cpp &&
-      Style.Language != FormatStyle::LK_ObjC &&
       Current.is(tok::r_brace) && State.Stack.size() > 1 &&
       State.Stack[State.Stack.size() - 2].NestedBlockInlined;
   if (!NestedBlockSpecialCase)
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 12cb555..1aa7a0a 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -52,7 +52,6 @@
     IO.enumCase(Value, "Cpp", FormatStyle::LK_Cpp);
     IO.enumCase(Value, "Java", FormatStyle::LK_Java);
     IO.enumCase(Value, "JavaScript", FormatStyle::LK_JavaScript);
-    IO.enumCase(Value, "ObjC", FormatStyle::LK_ObjC);
     IO.enumCase(Value, "Proto", FormatStyle::LK_Proto);
     IO.enumCase(Value, "TableGen", FormatStyle::LK_TableGen);
   }
@@ -624,8 +623,6 @@
   } else if (Language == FormatStyle::LK_Proto) {
     GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_None;
     GoogleStyle.SpacesInContainerLiterals = false;
-  } else if (Language == FormatStyle::LK_ObjC) {
-    GoogleStyle.ColumnLimit = 100;
   }
 
   return GoogleStyle;
@@ -1873,8 +1870,6 @@
     return FormatStyle::LK_Java;
   if (FileName.endswith_lower(".js") || FileName.endswith_lower(".ts"))
     return FormatStyle::LK_JavaScript; // JavaScript or TypeScript.
-  if (FileName.endswith(".m") || FileName.endswith(".mm"))
-    return FormatStyle::LK_ObjC;
   if (FileName.endswith_lower(".proto") ||
       FileName.endswith_lower(".protodevel"))
     return FormatStyle::LK_Proto;
@@ -1884,21 +1879,12 @@
 }
 
 FormatStyle getStyle(StringRef StyleName, StringRef FileName,
-                     StringRef FallbackStyle, StringRef Code,
-                     vfs::FileSystem *FS) {
+                     StringRef FallbackStyle, vfs::FileSystem *FS) {
   if (!FS) {
     FS = vfs::getRealFileSystem().get();
   }
   FormatStyle Style = getLLVMStyle();
   Style.Language = getLanguageByFileName(FileName);
-
-  // This is a very crude detection of whether a header contains ObjC code that
-  // should be improved over time and probably be done on tokens, not one the
-  // bare content of the file.
-  if (Style.Language == FormatStyle::LK_Cpp && FileName.endswith(".h") &&
-      (Code.contains("\n- (") || Code.contains("\n+ (")))
-    Style.Language = FormatStyle::LK_ObjC;
-
   if (!getPredefinedStyle(FallbackStyle, Style.Language, &Style)) {
     llvm::errs() << "Invalid fallback style \"" << FallbackStyle
                  << "\" using LLVM style\n";
diff --git a/lib/Format/FormatTokenLexer.cpp b/lib/Format/FormatTokenLexer.cpp
index 46a32a9..2aa48e3 100644
--- a/lib/Format/FormatTokenLexer.cpp
+++ b/lib/Format/FormatTokenLexer.cpp
@@ -558,8 +558,7 @@
     Column = FormatTok->LastLineColumnWidth;
   }
 
-  if (Style.Language == FormatStyle::LK_Cpp ||
-      Style.Language == FormatStyle::LK_ObjC) {
+  if (Style.Language == FormatStyle::LK_Cpp) {
     if (!(Tokens.size() > 0 && Tokens.back()->Tok.getIdentifierInfo() &&
           Tokens.back()->Tok.getIdentifierInfo()->getPPKeywordID() ==
               tok::pp_define) &&
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index b5f7de2..d1a3952 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -317,8 +317,7 @@
          Contexts.back().InTemplateArgument);
 
     bool StartsObjCMethodExpr =
-        !CppArrayTemplates && (Style.Language == FormatStyle::LK_Cpp ||
-                               Style.Language == FormatStyle::LK_ObjC) &&
+        !CppArrayTemplates && Style.Language == FormatStyle::LK_Cpp &&
         Contexts.back().CanBeExpression && Left->isNot(TT_LambdaLSquare) &&
         CurrentToken->isNot(tok::l_brace) &&
         (!Parent ||
@@ -434,8 +433,7 @@
           FormatToken *Previous = CurrentToken->getPreviousNonComment();
           if (((CurrentToken->is(tok::colon) &&
                 (!Contexts.back().ColonIsDictLiteral ||
-                 (Style.Language != FormatStyle::LK_Cpp &&
-                  Style.Language != FormatStyle::LK_ObjC))) ||
+                 Style.Language != FormatStyle::LK_Cpp)) ||
                Style.Language == FormatStyle::LK_Proto) &&
               (Previous->Tok.getIdentifierInfo() ||
                Previous->is(tok::string_literal)))
@@ -1176,7 +1174,6 @@
   bool rParenEndsCast(const FormatToken &Tok) {
     // C-style casts are only used in C++ and Java.
     if (Style.Language != FormatStyle::LK_Cpp &&
-        Style.Language != FormatStyle::LK_ObjC &&
         Style.Language != FormatStyle::LK_Java)
       return false;
 
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index d892996..aba662b 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -18,6 +18,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Basic/VirtualFileSystem.h"
@@ -185,7 +186,8 @@
   llvm::BitstreamWriter Stream;
   ASTWriter Writer;
 
-  ASTWriterData() : Stream(Buffer), Writer(Stream, { }) { }
+  ASTWriterData(MemoryBufferCache &PCMCache)
+      : Stream(Buffer), Writer(Stream, Buffer, PCMCache, {}) {}
 };
 
 void ASTUnit::clearFileLevelDecls() {
@@ -619,6 +621,10 @@
     StoredDiags.emplace_back(Level, Info);
 }
 
+IntrusiveRefCntPtr<ASTReader> ASTUnit::getASTReader() const {
+  return Reader;
+}
+
 ASTMutationListener *ASTUnit::getASTMutationListener() {
   if (WriterData)
     return &WriterData->Writer;
@@ -677,6 +683,7 @@
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
                                      AST->getFileManager(),
                                      UserFilesAreVolatile);
+  AST->PCMCache = new MemoryBufferCache;
   AST->HSOpts = std::make_shared<HeaderSearchOptions>();
   AST->HSOpts->ModuleFormat = PCHContainerRdr.getFormat();
   AST->HeaderInfo.reset(new HeaderSearch(AST->HSOpts,
@@ -697,7 +704,7 @@
 
   AST->PP = std::make_shared<Preprocessor>(
       std::move(PPOpts), AST->getDiagnostics(), AST->ASTFileLangOpts,
-      AST->getSourceManager(), HeaderInfo, *AST,
+      AST->getSourceManager(), *AST->PCMCache, HeaderInfo, *AST,
       /*IILookup=*/nullptr,
       /*OwnsHeaderSearch=*/false);
   Preprocessor &PP = *AST->PP;
@@ -1723,6 +1730,7 @@
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
                                      UserFilesAreVolatile);
+  AST->PCMCache = new MemoryBufferCache;
 
   return AST;
 }
@@ -1990,6 +1998,7 @@
   if (!VFS)
     return nullptr;
   AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
+  AST->PCMCache = new MemoryBufferCache;
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->TUKind = TUKind;
@@ -2001,7 +2010,7 @@
   AST->StoredDiagnostics.swap(StoredDiagnostics);
   AST->Invocation = CI;
   if (ForSerialization)
-    AST->WriterData.reset(new ASTWriterData());
+    AST->WriterData.reset(new ASTWriterData(*AST->PCMCache));
   // Zero out now to ease cleanup during crash recovery.
   CI = nullptr;
   Diags = nullptr;
@@ -2516,7 +2525,8 @@
 
   SmallString<128> Buffer;
   llvm::BitstreamWriter Stream(Buffer);
-  ASTWriter Writer(Stream, { });
+  MemoryBufferCache PCMCache;
+  ASTWriter Writer(Stream, Buffer, PCMCache, {});
   return serializeUnit(Writer, Buffer, getSema(), hasErrors, OS);
 }
 
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index afcaa6e..a4b72e0 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -8,11 +8,13 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/APINotes/APINotesReader.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/Version.h"
@@ -55,12 +57,15 @@
 
 CompilerInstance::CompilerInstance(
     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
-    bool BuildingModule)
-    : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()),
-      ModuleManager(nullptr),
-      ThePCHContainerOperations(std::move(PCHContainerOps)),
-      BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false),
-      ModuleBuildFailed(false) {}
+    MemoryBufferCache *SharedPCMCache)
+    : ModuleLoader(/* BuildingModule = */ SharedPCMCache),
+      Invocation(new CompilerInvocation()),
+      PCMCache(SharedPCMCache ? SharedPCMCache : new MemoryBufferCache),
+      ThePCHContainerOperations(std::move(PCHContainerOps)) {
+  // Don't allow this to invalidate buffers in use by others.
+  if (SharedPCMCache)
+    getPCMCache().finalizeCurrentBuffers();
+}
 
 CompilerInstance::~CompilerInstance() {
   assert(OutputFiles.empty() && "Still output files in flight?");
@@ -131,6 +136,8 @@
   return ModuleManager;
 }
 void CompilerInstance::setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader) {
+  assert(PCMCache.get() == &Reader->getModuleManager().getPCMCache() &&
+         "Expected ASTReader to use the same PCM cache");
   ModuleManager = std::move(Reader);
 }
 
@@ -373,7 +380,7 @@
                        getDiagnostics(), getLangOpts(), &getTarget());
   PP = std::make_shared<Preprocessor>(
       Invocation->getPreprocessorOptsPtr(), getDiagnostics(), getLangOpts(),
-      getSourceManager(), *HeaderInfo, *this, PTHMgr,
+      getSourceManager(), getPCMCache(), *HeaderInfo, *this, PTHMgr,
       /*OwnsHeaderSearch=*/true, TUKind);
   PP->Initialize(getTarget(), getAuxTarget());
 
@@ -465,7 +472,7 @@
   SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath);
   if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash)
     llvm::sys::path::append(SpecificModuleCache,
-                            getInvocation().getModuleHash());
+                            getInvocation().getModuleHash(getDiagnostics()));
   return SpecificModuleCache.str();
 }
 
@@ -491,6 +498,8 @@
       AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
       getPCHContainerReader(),
       getFrontendOpts().ModuleFileExtensions,
+      TheDependencyFileGenerator.get(),
+      DependencyCollectors,
       DeserializationListener,
       OwnDeserializationListener, Preamble,
       getFrontendOpts().UseGlobalModuleIndex);
@@ -501,6 +510,8 @@
     bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
     const PCHContainerReader &PCHContainerRdr,
     ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
+    DependencyFileGenerator *DependencyFile,
+    ArrayRef<std::shared_ptr<DependencyCollector>> DependencyCollectors,
     void *DeserializationListener, bool OwnDeserializationListener,
     bool Preamble, bool UseGlobalModuleIndex) {
   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
@@ -518,6 +529,12 @@
   Reader->setDeserializationListener(
       static_cast<ASTDeserializationListener *>(DeserializationListener),
       /*TakeOwnership=*/OwnDeserializationListener);
+
+  if (DependencyFile)
+    DependencyFile->AttachToASTReader(*Reader);
+  for (auto &Listener : DependencyCollectors)
+    Listener->attachToASTReader(*Reader);
+
   switch (Reader->ReadAST(Path,
                           Preamble ? serialization::MK_Preamble
                                    : serialization::MK_PCH,
@@ -615,6 +632,27 @@
                                   CodeCompleteConsumer *CompletionConsumer) {
   TheSema.reset(new Sema(getPreprocessor(), getASTContext(), getASTConsumer(),
                          TUKind, CompletionConsumer));
+
+  // Set up API notes.
+  TheSema->APINotes.setSwiftVersion(getAPINotesOpts().SwiftVersion);
+
+  // If we're building a module and are supposed to load API notes,
+  // notify the API notes manager.
+  if (auto currentModule = getPreprocessor().getCurrentModule()) {
+    (void)TheSema->APINotes.loadCurrentModuleAPINotes(
+            currentModule,
+            getLangOpts().APINotesModules,
+            getAPINotesOpts().ModuleSearchPaths);
+    // Check for any attributes we should add to the module
+    for (auto reader : TheSema->APINotes.getCurrentModuleReaders()) {
+      // swift_infer_import_as_member
+      if (reader->getModuleOptions().SwiftInferImportAsMember) {
+        currentModule->IsSwiftInferImportAsMember = true;
+        break;
+      }
+    }
+  }
+
   // Attach the external sema source if there is any.
   if (ExternalSemaSrc) {
     TheSema->addExternalSource(ExternalSemaSrc.get());
@@ -842,7 +880,8 @@
                             /*SearchPath=*/nullptr,
                             /*RelativePath=*/nullptr,
                             /*RequestingModule=*/nullptr,
-                            /*SuggestedModule=*/nullptr, /*SkipCache=*/true);
+                            /*SuggestedModule=*/nullptr, /*IsMapped=*/nullptr,
+                            /*SkipCache=*/true);
       // Also add the header to /showIncludes output.
       if (File)
         DepOpts.ShowIncludesPretendHeader = File->getName();
@@ -1016,7 +1055,7 @@
                               SourceLocation ImportLoc,
                               Module *Module,
                               StringRef ModuleFileName) {
-  ModuleMap &ModMap 
+  ModuleMap &ModMap
     = ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
     
   // Construct a compiler invocation for creating this module.
@@ -1032,7 +1071,7 @@
 
   // Remove any macro definitions that are explicitly ignored by the module.
   // They aren't supposed to affect how the module is built anyway.
-  const HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
+  HeaderSearchOptions &HSOpts = Invocation->getHeaderSearchOpts();
   PPOpts.Macros.erase(
       std::remove_if(PPOpts.Macros.begin(), PPOpts.Macros.end(),
                      [&HSOpts](const std::pair<std::string, bool> &def) {
@@ -1063,6 +1102,8 @@
   FrontendOpts.DisableFree = false;
   FrontendOpts.GenerateGlobalModuleIndex = false;
   FrontendOpts.BuildingImplicitModule = true;
+  // Force implicitly-built modules to hash the content of the module file.
+  HSOpts.ModulesHashContent = true;
   FrontendOpts.Inputs.clear();
   InputKind IK = getSourceInputKindFromOptions(*Invocation->getLangOpts());
 
@@ -1070,13 +1111,17 @@
   PPOpts.RetainRemappedFileBuffers = true;
     
   Invocation->getDiagnosticOpts().VerifyDiagnostics = 0;
-  assert(ImportingInstance.getInvocation().getModuleHash() ==
-         Invocation->getModuleHash() && "Module hash mismatch!");
-  
+  assert(ImportingInstance.getInvocation().getModuleHash(
+             ImportingInstance.getDiagnostics()) ==
+             Invocation->getModuleHash(ImportingInstance.getDiagnostics()) &&
+         "Module hash mismatch!");
+
   // Construct a compiler instance that will be used to actually create the
-  // module.
+  // module.  Since we're sharing a PCMCache,
+  // CompilerInstance::CompilerInstance is responsible for finalizing the
+  // buffers to prevent use-after-frees.
   CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),
-                            /*BuildingModule=*/true);
+                            &ImportingInstance.getPreprocessor().getPCMCache());
   auto &Inv = *Invocation;
   Instance.setInvocation(std::move(Invocation));
 
@@ -1180,10 +1225,14 @@
     llvm::LockFileManager Locked(ModuleFileName);
     switch (Locked) {
     case llvm::LockFileManager::LFS_Error:
-      Diags.Report(ModuleNameLoc, diag::err_module_lock_failure)
+      // PCMCache takes care of correctness and locks are only necessary for
+      // performance. Fallback to building the module in case of any lock
+      // related errors.
+      Diags.Report(ModuleNameLoc, diag::remark_module_lock_failure)
           << Module->Name << Locked.getErrorMessage();
-      return false;
-
+      // Clear out any potential leftover.
+      Locked.unsafeRemoveLockFile();
+      // FALLTHROUGH
     case llvm::LockFileManager::LFS_Owned:
       // We're responsible for building the module ourselves.
       if (!compileModuleImpl(ImportingInstance, ModuleNameLoc, Module,
@@ -1203,11 +1252,14 @@
       case llvm::LockFileManager::Res_OwnerDied:
         continue; // try again to get the lock.
       case llvm::LockFileManager::Res_Timeout:
-        Diags.Report(ModuleNameLoc, diag::err_module_lock_timeout)
+        // Since PCMCache takes care of correctness, we try waiting for another
+        // process to complete the build so clang does not do it done twice. If
+        // case of timeout, build it ourselves.
+        Diags.Report(ModuleNameLoc, diag::remark_module_lock_timeout)
             << Module->Name;
         // Clear the lock file so that future invokations can make progress.
         Locked.unsafeRemoveLockFile();
-        return false;
+        continue;
       }
       break;
     }
@@ -1794,8 +1846,13 @@
     // Check whether this module is available.
     clang::Module::Requirement Requirement;
     clang::Module::UnresolvedHeaderDirective MissingHeader;
+    clang::Module *ShadowingModule = nullptr;
     if (!Module->isAvailable(getLangOpts(), getTarget(), Requirement,
-                             MissingHeader)) {
+                             MissingHeader, ShadowingModule)) {
+
+      assert(!ShadowingModule &&
+             "lookup of module by name should never find shadowed module");
+
       if (MissingHeader.FileNameLoc.isValid()) {
         getDiagnostics().Report(MissingHeader.FileNameLoc,
                                 diag::err_module_header_missing)
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 36f6b0a..6d87ed2 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -801,18 +801,6 @@
     }
   }
 
-  if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
-    StringRef Val = A->getValue();
-    if (Val == "fast")
-      Opts.setFPContractMode(CodeGenOptions::FPC_Fast);
-    else if (Val == "on")
-      Opts.setFPContractMode(CodeGenOptions::FPC_On);
-    else if (Val == "off")
-      Opts.setFPContractMode(CodeGenOptions::FPC_Off);
-    else
-      Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
-  }
-
   if (Arg *A = Args.getLastArg(OPT_fdenormal_fp_math_EQ)) {
     StringRef Val = A->getValue();
     if (Val == "ieee")
@@ -1085,6 +1073,7 @@
 
 static void ParseFileSystemArgs(FileSystemOptions &Opts, ArgList &Args) {
   Opts.WorkingDir = Args.getLastArgValue(OPT_working_directory);
+  Opts.APINotesCachePath = Args.getLastArgValue(OPT_fapinotes_cache_path);
 }
 
 /// Parse the argument to the -ftest-module-file-extension
@@ -1407,7 +1396,8 @@
   return P.str();
 }
 
-static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
+static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
+                                  const std::string &WorkingDir) {
   using namespace options;
   Opts.Sysroot = Args.getLastArgValue(OPT_isysroot, "/");
   Opts.Verbose = Args.hasArg(OPT_v);
@@ -1417,11 +1407,23 @@
   if (const Arg *A = Args.getLastArg(OPT_stdlib_EQ))
     Opts.UseLibcxx = (strcmp(A->getValue(), "libc++") == 0);
   Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir);
-  Opts.ModuleCachePath = Args.getLastArgValue(OPT_fmodules_cache_path);
+
+  // Canonicalize -fmodules-cache-path before storing it.
+  SmallString<128> P(Args.getLastArgValue(OPT_fmodules_cache_path));
+  if (!(P.empty() || llvm::sys::path::is_absolute(P))) {
+    if (WorkingDir.empty())
+      llvm::sys::fs::make_absolute(P);
+    else
+      llvm::sys::fs::make_absolute(WorkingDir, P);
+  }
+  llvm::sys::path::remove_dots(P);
+  Opts.ModuleCachePath = P.str();
+
   Opts.ModuleUserBuildPath = Args.getLastArgValue(OPT_fmodules_user_build_path);
   for (const Arg *A : Args.filtered(OPT_fprebuilt_module_path))
     Opts.AddPrebuiltModulePath(A->getValue());
   Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
+  Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content);
   Opts.ModulesValidateDiagnosticOptions =
       !Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
   Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
@@ -1495,6 +1497,9 @@
                  !A->getOption().matches(OPT_iwithsysroot));
   for (const Arg *A : Args.filtered(OPT_iframework))
     Opts.AddPath(A->getValue(), frontend::System, true, true);
+  for (const Arg *A : Args.filtered(OPT_iframeworkwithsysroot))
+    Opts.AddPath(A->getValue(), frontend::System, /*IsFramework=*/true,
+                 /*IgnoreSysRoot=*/false);
 
   // Add the paths for the various language specific isystem flags.
   for (const Arg *A : Args.filtered(OPT_c_isystem))
@@ -1525,6 +1530,18 @@
     Opts.AddVFSOverlayFile(A->getValue());
 }
 
+static void ParseAPINotesArgs(APINotesOptions &Opts, ArgList &Args,
+                              DiagnosticsEngine &diags) {
+  using namespace options;
+  if (const Arg *A = Args.getLastArg(OPT_fapinotes_swift_version)) {
+    if (Opts.SwiftVersion.tryParse(A->getValue()))
+      diags.Report(diag::err_drv_invalid_value)
+        << A->getAsString(Args) << A->getValue();
+  }
+  for (const Arg *A : Args.filtered(OPT_iapinotes_modules))
+    Opts.ModuleSearchPaths.push_back(A->getValue());
+}
+
 static bool isOpenCL(LangStandard::Kind LangStd) {
   return LangStd == LangStandard::lang_opencl ||
          LangStd == LangStandard::lang_opencl11 ||
@@ -1618,7 +1635,7 @@
     Opts.ZVector = 0;
     Opts.CXXOperatorNames = 1;
     Opts.LaxVectorConversions = 0;
-    Opts.DefaultFPContract = 1;
+    Opts.setDefaultFPContractMode(LangOptions::FPC_On);
     Opts.NativeHalfType = 1;
     Opts.NativeHalfArgsAndReturns = 1;
     // Include default header file for OpenCL.
@@ -1629,6 +1646,9 @@
 
   Opts.CUDA = IK == IK_CUDA || IK == IK_PreprocessedCuda ||
               LangStd == LangStandard::lang_cuda;
+  if (Opts.CUDA)
+    // Set default FP_CONTRACT to FAST.
+    Opts.setDefaultFPContractMode(LangOptions::FPC_Fast);
 
   Opts.RenderScript = IK == IK_RenderScript;
   if (Opts.RenderScript) {
@@ -1947,6 +1967,7 @@
       Args.hasArg(OPT_fmodules_decluse) || Opts.ModulesStrictDeclUse;
   Opts.ModulesLocalVisibility =
       Args.hasArg(OPT_fmodules_local_submodule_visibility) || Opts.ModulesTS;
+  Opts.ModulesHashErrorDiags = Args.hasArg(OPT_fmodules_hash_error_diagnostics);
   Opts.ModulesSearchAll = Opts.Modules &&
     !Args.hasArg(OPT_fno_modules_search_all) &&
     Args.hasArg(OPT_fmodules_search_all);
@@ -2031,6 +2052,8 @@
   // is enabled.
   Opts.HalfArgsAndReturns = Args.hasArg(OPT_fallow_half_arguments_and_returns)
                             | Opts.NativeHalfArgsAndReturns;
+  Opts.APINotes = Args.hasArg(OPT_fapinotes);
+  Opts.APINotesModules = Args.hasArg(OPT_fapinotes_modules);
   Opts.GNUAsm = !Args.hasArg(OPT_fno_gnu_inline_asm);
 
   // __declspec is enabled by default for the PS4 by the driver, and also
@@ -2045,12 +2068,6 @@
       Args.hasFlag(OPT_fdeclspec, OPT_fno_declspec,
                    (Opts.MicrosoftExt || Opts.Borland || Opts.CUDA));
 
-  // For now, we only support local submodule visibility in C++ (because we
-  // heavily depend on the ODR for merging redefinitions).
-  if (Opts.ModulesLocalVisibility && !Opts.CPlusPlus)
-    Diags.Report(diag::err_drv_argument_not_allowed_with)
-        << "-fmodules-local-submodule-visibility" << "C";
-
   if (Arg *A = Args.getLastArg(OPT_faddress_space_map_mangling_EQ)) {
     switch (llvm::StringSwitch<unsigned>(A->getValue())
       .Case("target", LangOptions::ASMM_Target)
@@ -2214,6 +2231,18 @@
                       Args.hasArg(OPT_cl_unsafe_math_optimizations) ||
                       Args.hasArg(OPT_cl_fast_relaxed_math);
 
+  if (Arg *A = Args.getLastArg(OPT_ffp_contract)) {
+    StringRef Val = A->getValue();
+    if (Val == "fast")
+      Opts.setDefaultFPContractMode(LangOptions::FPC_Fast);
+    else if (Val == "on")
+      Opts.setDefaultFPContractMode(LangOptions::FPC_On);
+    else if (Val == "off")
+      Opts.setDefaultFPContractMode(LangOptions::FPC_Off);
+    else
+      Diags.Report(diag::err_drv_invalid_value) << A->getAsString(Args) << Val;
+  }
+
   Opts.RetainCommentsFromSystemHeaders =
       Args.hasArg(OPT_fretain_comments_from_system_headers);
 
@@ -2236,6 +2265,9 @@
   Opts.SanitizeAddressFieldPadding =
       getLastArgIntValue(Args, OPT_fsanitize_address_field_padding, 0, Diags);
   Opts.SanitizerBlacklistFiles = Args.getAllArgValues(OPT_fsanitize_blacklist);
+
+  // -fallow-editor-placeholders
+  Opts.AllowEditorPlaceholders = Args.hasArg(OPT_fallow_editor_placeholders);
 }
 
 static void ParsePreprocessorArgs(PreprocessorOptions &Opts, ArgList &Args,
@@ -2251,6 +2283,7 @@
   Opts.UsePredefines = !Args.hasArg(OPT_undef);
   Opts.DetailedRecord = Args.hasArg(OPT_detailed_preprocessing_record);
   Opts.DisablePCHValidation = Args.hasArg(OPT_fno_validate_pch);
+  Opts.AllowPCHWithCompilerErrors = Args.hasArg(OPT_fallow_pch_with_errors);
 
   Opts.DumpDeserializedPCHDecls = Args.hasArg(OPT_dump_deserialized_pch_decls);
   for (const Arg *A : Args.filtered(OPT_error_on_deserialized_pch_decl))
@@ -2440,7 +2473,10 @@
   ParseTargetArgs(Res.getTargetOpts(), Args, Diags);
   Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags,
                               Res.getTargetOpts());
-  ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args);
+  ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args,
+                        Res.getFileSystemOpts().WorkingDir);
+  ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
+
   if (DashX == IK_AST || DashX == IK_LLVM_IR) {
     // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
     // PassManager in BackendUtil.cpp. They need to be initializd no matter
@@ -2459,6 +2495,13 @@
       Res.getPreprocessorOpts(), Diags);
     if (Res.getFrontendOpts().ProgramAction == frontend::RewriteObjC)
       LangOpts.ObjCExceptions = 1;
+
+    // -fapinotes and -fapinotes-modules requires -fapinotes-cache-path=<directory>.
+    if ((LangOpts.APINotes || LangOpts.APINotesModules) &&
+        Res.getFileSystemOpts().APINotesCachePath.empty()) {
+      Diags.Report(diag::err_no_apinotes_cache_path);
+      Success = false;
+    }
   }
 
   if (LangOpts.CUDA) {
@@ -2466,10 +2509,6 @@
     // triple used for host compilation.
     if (LangOpts.CUDAIsDevice)
       Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
-
-    // Set default FP_CONTRACT to FAST.
-    if (!Args.hasArg(OPT_ffp_contract))
-      Res.getCodeGenOpts().setFPContractMode(CodeGenOptions::FPC_Fast);
   }
 
   // FIXME: Override value name discarding when asan or msan is used because the
@@ -2497,7 +2536,16 @@
   return Success;
 }
 
-std::string CompilerInvocation::getModuleHash() const {
+// Some extension diagnostics aren't explicitly mapped and require custom
+// logic in the dianognostic engine to be used, track -pedantic-errors
+static bool isExtHandlingFromDiagsError(DiagnosticsEngine &Diags) {
+  diag::Severity Ext = Diags.getExtensionHandlingBehavior();
+  if (Ext == diag::Severity::Warning && Diags.getWarningsAsErrors())
+    return true;
+  return Ext >= diag::Severity::Error;
+}
+
+std::string CompilerInvocation::getModuleHash(DiagnosticsEngine &Diags) const {
   // Note: For QoI reasons, the things we use as a hash here should all be
   // dumped via the -module-info flag.
   using llvm::hash_code;
@@ -2566,7 +2614,19 @@
   // Extend the signature with the module file extensions.
   const FrontendOptions &frontendOpts = getFrontendOpts();
   for (const auto &ext : frontendOpts.ModuleFileExtensions) {
-    code = ext->hashExtension(code);
+    code = hash_combine(code, ext->hashExtension(code));
+  }
+
+  // Extend the signature with the SWift version for API notes.
+  const APINotesOptions &apiNotesOpts = getAPINotesOpts();
+  if (apiNotesOpts.SwiftVersion) {
+    code = hash_combine(code, apiNotesOpts.SwiftVersion.getMajor());
+    if (auto minor = apiNotesOpts.SwiftVersion.getMinor())
+      code = hash_combine(code, *minor);
+    if (auto subminor = apiNotesOpts.SwiftVersion.getSubminor())
+      code = hash_combine(code, *subminor);
+    if (auto build = apiNotesOpts.SwiftVersion.getBuild())
+      code = hash_combine(code, *build);
   }
 
   // Darwin-specific hack: if we have a sysroot, use the contents and
@@ -2592,6 +2652,24 @@
     }
   }
 
+  // Check for a couple things (see checkDiagnosticMappings in ASTReader.cpp):
+  //  -Werror: consider all warnings into the hash
+  //  -Werror=something: consider only the specified into the hash
+  //  -pedantic-error
+  if (getLangOpts()->ModulesHashErrorDiags) {
+    bool ConsiderAllWarningsAsErrors = Diags.getWarningsAsErrors();
+    code = hash_combine(code, isExtHandlingFromDiagsError(Diags));
+    for (auto DiagIDMappingPair : Diags.getDiagnosticMappings()) {
+      diag::kind DiagID = DiagIDMappingPair.first;
+      auto CurLevel = Diags.getDiagnosticLevel(DiagID, SourceLocation());
+      if (CurLevel < DiagnosticsEngine::Error && !ConsiderAllWarningsAsErrors)
+        continue; // not significant
+      code = hash_combine(
+          code,
+          Diags.getDiagnosticIDs()->getWarningOptionForDiag(DiagID).str());
+    }
+  }
+
   return llvm::APInt(64, code).toString(36, /*Signed=*/false);
 }
 
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index 39fc137..f9ad97c 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -414,6 +414,13 @@
       CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
   }
 
+  // Add a module declaration scope so that modules from -fmodule-map-file
+  // arguments may shadow modules found implicitly in search paths.
+  CI.getPreprocessor()
+      .getHeaderSearchInfo()
+      .getModuleMap()
+      .finishModuleDeclarationScope();
+
   // If we were asked to load any module files, do so now.
   for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)
     if (!CI.loadModuleFile(ModuleFile))
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index f795a1d..8809a42 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -93,7 +93,7 @@
   Consumers.push_back(llvm::make_unique<PCHGenerator>(
                         CI.getPreprocessor(), OutputFile, Sysroot,
                         Buffer, CI.getFrontendOpts().ModuleFileExtensions,
-                        /*AllowASTWithErrors*/false,
+      /*AllowASTWithErrors*/CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
                         /*IncludeTimestamps*/
                           +CI.getFrontendOpts().IncludeTimestamps));
   Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
@@ -127,6 +127,12 @@
   return OS;
 }
 
+bool GeneratePCHAction::shouldEraseOutputFiles() {
+  if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)
+    return false;
+  return ASTFrontendAction::shouldEraseOutputFiles();
+}
+
 bool GeneratePCHAction::BeginSourceFileAction(CompilerInstance &CI,
                                               StringRef Filename) {
   CI.getLangOpts().CompilingPCH = true;
@@ -341,8 +347,13 @@
   // Check whether we can build this module at all.
   clang::Module::Requirement Requirement;
   clang::Module::UnresolvedHeaderDirective MissingHeader;
+  clang::Module *ShadowingModule = nullptr;
   if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Requirement,
-                           MissingHeader)) {
+                           MissingHeader, ShadowingModule)) {
+
+    assert(!ShadowingModule &&
+           "lookup of module by name should never find shadowed module");
+
     if (MissingHeader.FileNameLoc.isValid()) {
       CI.getDiagnostics().Report(MissingHeader.FileNameLoc,
                                  diag::err_module_header_missing)
@@ -567,6 +578,7 @@
                                  bool Complain) override {
       Out.indent(2) << "Header search options:\n";
       Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
+      Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
       Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
       DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes,
                    "Use builtin include directories [-nobuiltininc]");
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 17603ad..9002114 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -593,9 +593,6 @@
         Builder.defineMacro("OBJC_ZEROCOST_EXCEPTIONS");
     }
 
-    Builder.defineMacro("__OBJC_BOOL_IS_BOOL",
-                        Twine(TI.useSignedCharForObjCBool() ? "0" : "1"));
-
     if (LangOpts.getGC() != LangOptions::NonGC)
       Builder.defineMacro("__OBJC_GC__");
 
@@ -626,6 +623,11 @@
     Builder.defineMacro("IB_DESIGNABLE", "");
   }
 
+  // Define a macro that describes the Objective-C boolean type even for C
+  // and C++ since BOOL can be used from non Objective-C code.
+  Builder.defineMacro("__OBJC_BOOL_IS_BOOL",
+                      Twine(TI.useSignedCharForObjCBool() ? "0" : "1"));
+
   if (LangOpts.CPlusPlus)
     InitializeCPlusPlusFeatureTestMacros(LangOpts, Builder);
 
diff --git a/lib/Frontend/Rewrite/InclusionRewriter.cpp b/lib/Frontend/Rewrite/InclusionRewriter.cpp
index d953da2..ca14da3 100644
--- a/lib/Frontend/Rewrite/InclusionRewriter.cpp
+++ b/lib/Frontend/Rewrite/InclusionRewriter.cpp
@@ -392,7 +392,7 @@
   // FIXME: Why don't we call PP.LookupFile here?
   const FileEntry *File = PP.getHeaderSearchInfo().LookupFile(
       Filename, SourceLocation(), isAngled, nullptr, CurDir, Includers, nullptr,
-      nullptr, nullptr, nullptr, false);
+      nullptr, nullptr, nullptr, nullptr);
 
   FileExists = File != nullptr;
   return true;
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index e7bfced..cd22e82 100644
--- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -7500,7 +7500,7 @@
       BinaryOperator *addExpr = 
         new (Context) BinaryOperator(castExpr, DRE, BO_Add, 
                                      Context->getPointerType(Context->CharTy),
-                                     VK_RValue, OK_Ordinary, SourceLocation(), false);
+                                     VK_RValue, OK_Ordinary, SourceLocation(), FPOptions());
       // Don't forget the parens to enforce the proper binding.
       ParenExpr *PE = new (Context) ParenExpr(SourceLocation(),
                                               SourceLocation(),
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
index e842e59..055f3ce 100644
--- a/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -2992,7 +2992,7 @@
     BinaryOperator *lessThanExpr = 
       new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy,
                                    VK_RValue, OK_Ordinary, SourceLocation(),
-                                   false);
+                                   FPOptions());
     // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...))
     ConditionalOperator *CondExpr =
       new (Context) ConditionalOperator(lessThanExpr,
diff --git a/lib/Frontend/VerifyDiagnosticConsumer.cpp b/lib/Frontend/VerifyDiagnosticConsumer.cpp
index ae16ea1..427d15e 100644
--- a/lib/Frontend/VerifyDiagnosticConsumer.cpp
+++ b/lib/Frontend/VerifyDiagnosticConsumer.cpp
@@ -400,7 +400,7 @@
         const DirectoryLookup *CurDir;
         const FileEntry *FE =
             PP->LookupFile(Pos, Filename, false, nullptr, nullptr, CurDir,
-                           nullptr, nullptr, nullptr);
+                           nullptr, nullptr, nullptr, nullptr);
         if (!FE) {
           Diags.Report(Pos.getLocWithOffset(PH.C-PH.Begin),
                        diag::err_verify_missing_file) << Filename << KindStr;
diff --git a/lib/Headers/tgmath.h b/lib/Headers/tgmath.h
index 318e118..34e26dc 100644
--- a/lib/Headers/tgmath.h
+++ b/lib/Headers/tgmath.h
@@ -22,12 +22,21 @@
  *
 \*===----------------------------------------------------------------------===*/
 
-#ifndef __TGMATH_H
-#define __TGMATH_H
+#ifndef __CLANG_TGMATH_H
+#define __CLANG_TGMATH_H
 
 /* C99 7.22 Type-generic math <tgmath.h>. */
 #include <math.h>
 
+/*
+ * Allow additional definitions and implementation-defined values on Apple
+ * platforms. This is done after #include <math.h> to avoid depcycle conflicts
+ * between libcxx and darwin in C++ modules builds.
+ */
+#if defined(__APPLE__) && __STDC_HOSTED__ && __has_include_next(<tgmath.h>)
+#  include_next <tgmath.h>
+#else
+
 /* C++ handles type genericity with overloading in math.h. */
 #ifndef __cplusplus
 #include <complex.h>
@@ -1371,4 +1380,5 @@
 #undef _TG_ATTRS
 
 #endif /* __cplusplus */
-#endif /* __TGMATH_H */
+#endif /* __has_include_next */
+#endif /* __CLANG_TGMATH_H */
diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt
index 8f51ccb..c9fbfaf 100644
--- a/lib/Index/CMakeLists.txt
+++ b/lib/Index/CMakeLists.txt
@@ -24,5 +24,6 @@
   clangFormat
   clangFrontend
   clangRewrite
+  clangSerialization
   clangToolingCore
   )
diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp
index 3aa0152..d3632b8 100644
--- a/lib/Index/IndexBody.cpp
+++ b/lib/Index/IndexBody.cpp
@@ -22,6 +22,10 @@
   SmallVector<Stmt*, 16> StmtStack;
 
   typedef RecursiveASTVisitor<BodyIndexer> base;
+
+  Stmt *getParentStmt() const {
+    return StmtStack.size() < 2 ? nullptr : StmtStack.end()[-2];
+  }
 public:
   BodyIndexer(IndexingContext &indexCtx,
               const NamedDecl *Parent, const DeclContext *DC)
@@ -146,6 +150,53 @@
                                     Parent, ParentDC, Roles, Relations, E);
   }
 
+  bool indexDependentReference(
+      const Expr *E, const Type *T, const DeclarationNameInfo &NameInfo,
+      llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
+    if (!T)
+      return true;
+    const TemplateSpecializationType *TST =
+        T->getAs<TemplateSpecializationType>();
+    if (!TST)
+      return true;
+    TemplateName TN = TST->getTemplateName();
+    const ClassTemplateDecl *TD =
+        dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
+    if (!TD)
+      return true;
+    CXXRecordDecl *RD = TD->getTemplatedDecl();
+    if (!RD->hasDefinition())
+      return true;
+    RD = RD->getDefinition();
+    std::vector<const NamedDecl *> Symbols =
+        RD->lookupDependentName(NameInfo.getName(), Filter);
+    // FIXME: Improve overload handling.
+    if (Symbols.size() != 1)
+      return true;
+    SourceLocation Loc = NameInfo.getLoc();
+    if (Loc.isInvalid())
+      Loc = E->getLocStart();
+    SmallVector<SymbolRelation, 4> Relations;
+    SymbolRoleSet Roles = getRolesForRef(E, Relations);
+    return IndexCtx.handleReference(Symbols[0], Loc, Parent, ParentDC, Roles,
+                                    Relations, E);
+  }
+
+  bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+    const DeclarationNameInfo &Info = E->getMemberNameInfo();
+    return indexDependentReference(
+        E, E->getBaseType().getTypePtrOrNull(), Info,
+        [](const NamedDecl *D) { return D->isCXXInstanceMember(); });
+  }
+
+  bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+    const DeclarationNameInfo &Info = E->getNameInfo();
+    const NestedNameSpecifier *NNS = E->getQualifier();
+    return indexDependentReference(
+        E, NNS->getAsType(), Info,
+        [](const NamedDecl *D) { return !D->isCXXInstanceMember(); });
+  }
+
   bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
     for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
       if (D.isFieldDesignator() && D.getField())
@@ -178,7 +229,8 @@
       SymbolRoleSet Roles{};
       SmallVector<SymbolRelation, 2> Relations;
       addCallRole(Roles, Relations);
-      if (E->isImplicit())
+      Stmt *Containing = getParentStmt();
+      if (E->isImplicit() || (Containing && isa<PseudoObjectExpr>(Containing)))
         Roles |= (unsigned)SymbolRole::Implicit;
 
       if (isDynamic(E)) {
@@ -194,9 +246,27 @@
   }
 
   bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
-    if (E->isExplicitProperty())
+    if (E->isClassReceiver())
+      IndexCtx.handleReference(E->getClassReceiver(), E->getReceiverLocation(),
+                               Parent, ParentDC);
+    if (E->isExplicitProperty()) {
+      SmallVector<SymbolRelation, 2> Relations;
+      SymbolRoleSet Roles = getRolesForRef(E, Relations);
       return IndexCtx.handleReference(E->getExplicitProperty(), E->getLocation(),
-                                      Parent, ParentDC, SymbolRoleSet(), {}, E);
+                                      Parent, ParentDC, Roles, Relations, E);
+    } else if (const ObjCMethodDecl *Getter = E->getImplicitPropertyGetter()) {
+      // Class properties that are explicitly defined using @property
+      // declarations are represented implicitly as there is no ivar for class
+      // properties.
+      if (Getter->isClassMethod()) {
+        if (const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
+          SmallVector<SymbolRelation, 2> Relations;
+          SymbolRoleSet Roles = getRolesForRef(E, Relations);
+          return IndexCtx.handleReference(PD, E->getLocation(), Parent,
+                                          ParentDC, Roles, Relations, E);
+        }
+      }
+    }
 
     // No need to do a handleReference for the objc method, because there will
     // be a message expr as part of PseudoObjectExpr.
@@ -269,7 +339,7 @@
       const Decl *D = *I;
       if (!D)
         continue;
-      if (!IndexCtx.isFunctionLocalDecl(D))
+      if (!isFunctionLocalSymbol(D))
         IndexCtx.indexTopLevelDecl(D);
     }
 
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp
index 3b4f3f8..870b4e4 100644
--- a/lib/Index/IndexDecl.cpp
+++ b/lib/Index/IndexDecl.cpp
@@ -14,6 +14,13 @@
 using namespace clang;
 using namespace index;
 
+#define TRY_DECL(D,CALL_EXPR)                                                  \
+  do {                                                                         \
+    if (!IndexCtx.shouldIndex(D)) return true;                                 \
+    if (!CALL_EXPR)                                                            \
+      return false;                                                            \
+  } while (0)
+
 #define TRY_TO(CALL_EXPR)                                                      \
   do {                                                                         \
     if (!CALL_EXPR)                                                            \
@@ -45,6 +52,33 @@
     return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
   }
 
+  void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
+                                 const NamedDecl *Parent,
+                                 const DeclContext *DC) {
+    const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
+    switch (TALoc.getArgument().getKind()) {
+    case TemplateArgument::Expression:
+      IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
+      break;
+    case TemplateArgument::Type:
+      IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
+      break;
+    case TemplateArgument::Template:
+    case TemplateArgument::TemplateExpansion:
+      IndexCtx.indexNestedNameSpecifierLoc(TALoc.getTemplateQualifierLoc(),
+                                           Parent, DC);
+      if (const TemplateDecl *TD = TALoc.getArgument()
+                                       .getAsTemplateOrTemplatePattern()
+                                       .getAsTemplateDecl()) {
+        if (const NamedDecl *TTD = TD->getTemplatedDecl())
+          IndexCtx.handleReference(TTD, TALoc.getTemplateNameLoc(), Parent, DC);
+      }
+      break;
+    default:
+      break;
+    }
+  }
+
   void handleDeclarator(const DeclaratorDecl *D,
                         const NamedDecl *Parent = nullptr,
                         bool isIBType = false) {
@@ -75,6 +109,17 @@
           }
         }
       }
+    } else {
+      // Index the default parameter value for function definitions.
+      if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
+        if (FD->isThisDeclarationADefinition()) {
+          for (const auto *PV : FD->parameters()) {
+            if (PV->hasDefaultArg() && !PV->hasUninstantiatedDefaultArg() &&
+                !PV->hasUnparsedDefaultArg())
+              IndexCtx.indexBody(PV->getDefaultArg(), D);
+          }
+        }
+      }
     }
   }
 
@@ -98,8 +143,29 @@
     if (MethodLoc.isInvalid())
       MethodLoc = D->getLocation();
 
-    if (!IndexCtx.handleDecl(D, MethodLoc, (unsigned)SymbolRole::Dynamic, Relations))
-      return false;
+    SourceLocation AttrLoc;
+
+    // check for (getter=/setter=)
+    if (AssociatedProp) {
+      bool isGetter = !D->param_size();
+      AttrLoc = isGetter ?
+        AssociatedProp->getGetterNameLoc():
+        AssociatedProp->getSetterNameLoc();
+    }
+
+    SymbolRoleSet Roles = (SymbolRoleSet)SymbolRole::Dynamic;
+    if (D->isImplicit()) {
+      if (AttrLoc.isValid()) {
+        MethodLoc = AttrLoc;
+      } else {
+        Roles |= (SymbolRoleSet)SymbolRole::Implicit;
+      }
+    } else if (AttrLoc.isValid()) {
+      IndexCtx.handleReference(D, AttrLoc, cast<NamedDecl>(D->getDeclContext()),
+                               D->getDeclContext(), 0);
+    }
+
+    TRY_DECL(D, IndexCtx.handleDecl(D, MethodLoc, Roles, Relations));
     IndexCtx.indexTypeSourceInfo(D->getReturnTypeSourceInfo(), D);
     bool hasIBActionAndFirst = D->hasAttr<IBActionAttr>();
     for (const auto *I : D->parameters()) {
@@ -116,10 +182,52 @@
     return true;
   }
 
-  bool VisitFunctionDecl(const FunctionDecl *D) {
-    if (D->isDeleted())
-      return true;
+  /// Gather the declarations which the given declaration \D overrides in a
+  /// pseudo-override manner.
+  ///
+  /// Pseudo-overrides occur when a class template specialization declares
+  /// a declaration that has the same name as a similar declaration in the
+  /// non-specialized template.
+  void
+  gatherTemplatePseudoOverrides(const NamedDecl *D,
+                                SmallVectorImpl<SymbolRelation> &Relations) {
+    if (!IndexCtx.getLangOpts().CPlusPlus)
+      return;
+    const auto *CTSD =
+        dyn_cast<ClassTemplateSpecializationDecl>(D->getLexicalDeclContext());
+    if (!CTSD)
+      return;
+    llvm::PointerUnion<ClassTemplateDecl *,
+                       ClassTemplatePartialSpecializationDecl *>
+        Template = CTSD->getSpecializedTemplateOrPartial();
+    if (const auto *CTD = Template.dyn_cast<ClassTemplateDecl *>()) {
+      const CXXRecordDecl *Pattern = CTD->getTemplatedDecl();
+      bool TypeOverride = isa<TypeDecl>(D);
+      for (const NamedDecl *ND : Pattern->lookup(D->getDeclName())) {
+        if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
+          ND = CTD->getTemplatedDecl();
+        if (ND->isImplicit())
+          continue;
+        // Types can override other types.
+        if (!TypeOverride) {
+          if (ND->getKind() != D->getKind())
+            continue;
+        } else if (!isa<TypeDecl>(ND))
+          continue;
+        if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
+          const auto *DFD = cast<FunctionDecl>(D);
+          // Function overrides are approximated using the number of parameters.
+          if (FD->getStorageClass() != DFD->getStorageClass() ||
+              FD->getNumParams() != DFD->getNumParams())
+            continue;
+        }
+        Relations.emplace_back(
+            SymbolRoleSet(SymbolRole::RelationSpecializationOf), ND);
+      }
+    }
+  }
 
+  bool VisitFunctionDecl(const FunctionDecl *D) {
     SymbolRoleSet Roles{};
     SmallVector<SymbolRelation, 4> Relations;
     if (auto *CXXMD = dyn_cast<CXXMethodDecl>(D)) {
@@ -130,12 +238,19 @@
         Relations.emplace_back((unsigned)SymbolRole::RelationOverrideOf, *I);
       }
     }
+    gatherTemplatePseudoOverrides(D, Relations);
+    if (const auto *Base = D->getPrimaryTemplate())
+      Relations.push_back(
+          SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
+                         Base->getTemplatedDecl()));
 
-    if (!IndexCtx.handleDecl(D, Roles, Relations))
-      return false;
+    TRY_DECL(D, IndexCtx.handleDecl(D, Roles, Relations));
     handleDeclarator(D);
 
     if (const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
+      IndexCtx.handleReference(Ctor->getParent(), Ctor->getLocation(),
+                               Ctor->getParent(), Ctor->getDeclContext());
+
       // Constructor initializers.
       for (const auto *Init : Ctor->inits()) {
         if (Init->isWritten()) {
@@ -146,6 +261,18 @@
           IndexCtx.indexBody(Init->getInit(), D, D);
         }
       }
+    } else if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(D)) {
+      if (auto TypeNameInfo = Dtor->getNameInfo().getNamedTypeInfo()) {
+        IndexCtx.handleReference(Dtor->getParent(),
+                                 TypeNameInfo->getTypeLoc().getLocStart(),
+                                 Dtor->getParent(), Dtor->getDeclContext());
+      }
+    }
+    // Template specialization arguments.
+    if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
+            D->getTemplateSpecializationArgsAsWritten()) {
+      for (const auto &Arg : TemplateArgInfo->arguments())
+        handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
     }
 
     if (D->isThisDeclarationADefinition()) {
@@ -158,16 +285,18 @@
   }
 
   bool VisitVarDecl(const VarDecl *D) {
-    if (!IndexCtx.handleDecl(D))
-      return false;
+    SmallVector<SymbolRelation, 4> Relations;
+    gatherTemplatePseudoOverrides(D, Relations);
+    TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
     handleDeclarator(D);
     IndexCtx.indexBody(D->getInit(), D);
     return true;
   }
 
   bool VisitFieldDecl(const FieldDecl *D) {
-    if (!IndexCtx.handleDecl(D))
-      return false;
+    SmallVector<SymbolRelation, 4> Relations;
+    gatherTemplatePseudoOverrides(D, Relations);
+    TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
     handleDeclarator(D);
     if (D->isBitField())
       IndexCtx.indexBody(D->getBitWidth(), D);
@@ -178,17 +307,10 @@
 
   bool VisitObjCIvarDecl(const ObjCIvarDecl *D) {
     if (D->getSynthesize()) {
-      // For synthesized ivars, use the location of the ObjC implementation,
-      // not the location of the property.
-      // Otherwise the header file containing the @interface will have different
-      // indexing contents based on whether the @implementation was present or
-      // not in the translation unit.
-      return IndexCtx.handleDecl(D,
-                                 cast<Decl>(D->getDeclContext())->getLocation(),
-                                 (unsigned)SymbolRole::Implicit);
+      // handled in VisitObjCPropertyImplDecl
+      return true;
     }
-    if (!IndexCtx.handleDecl(D))
-      return false;
+    TRY_DECL(D, IndexCtx.handleDecl(D));
     handleDeclarator(D);
     return true;
   }
@@ -199,16 +321,18 @@
   }
 
   bool VisitEnumConstantDecl(const EnumConstantDecl *D) {
-    if (!IndexCtx.handleDecl(D))
-      return false;
+    TRY_DECL(D, IndexCtx.handleDecl(D));
     IndexCtx.indexBody(D->getInitExpr(), D);
     return true;
   }
 
   bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
-    if (!IndexCtx.handleDecl(D))
-      return false;
-    IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
+    if (!D->isTransparentTag()) {
+      SmallVector<SymbolRelation, 4> Relations;
+      gatherTemplatePseudoOverrides(D, Relations);
+      TRY_DECL(D, IndexCtx.handleDecl(D, SymbolRoleSet(), Relations));
+      IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
+    }
     return true;
   }
 
@@ -216,7 +340,9 @@
     // Non-free standing tags are handled in indexTypeSourceInfo.
     if (D->isFreeStanding()) {
       if (D->isThisDeclarationADefinition()) {
-        IndexCtx.indexTagDecl(D);
+        SmallVector<SymbolRelation, 4> Relations;
+        gatherTemplatePseudoOverrides(D, Relations);
+        IndexCtx.indexTagDecl(D, Relations);
       } else {
         auto *Parent = dyn_cast<NamedDecl>(D->getDeclContext());
         return IndexCtx.handleReference(D, D->getLocation(), Parent,
@@ -228,14 +354,17 @@
   }
 
   bool handleReferencedProtocols(const ObjCProtocolList &ProtList,
-                                 const ObjCContainerDecl *ContD) {
+                                 const ObjCContainerDecl *ContD,
+                                 SourceLocation SuperLoc) {
     ObjCInterfaceDecl::protocol_loc_iterator LI = ProtList.loc_begin();
     for (ObjCInterfaceDecl::protocol_iterator
          I = ProtList.begin(), E = ProtList.end(); I != E; ++I, ++LI) {
       SourceLocation Loc = *LI;
       ObjCProtocolDecl *PD = *I;
-      TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD,
-          SymbolRoleSet(),
+      SymbolRoleSet roles{};
+      if (Loc == SuperLoc)
+        roles |= (SymbolRoleSet)SymbolRole::Implicit;
+      TRY_TO(IndexCtx.handleReference(PD, Loc, ContD, ContD, roles,
           SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, ContD}));
     }
     return true;
@@ -243,13 +372,27 @@
 
   bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
     if (D->isThisDeclarationADefinition()) {
-      TRY_TO(IndexCtx.handleDecl(D));
+      TRY_DECL(D, IndexCtx.handleDecl(D));
+      SourceLocation SuperLoc = D->getSuperClassLoc();
       if (auto *SuperD = D->getSuperClass()) {
-        TRY_TO(IndexCtx.handleReference(SuperD, D->getSuperClassLoc(), D, D,
-            SymbolRoleSet(),
+        bool hasSuperTypedef = false;
+        if (auto *TInfo = D->getSuperClassTInfo()) {
+          if (auto *TT = TInfo->getType()->getAs<TypedefType>()) {
+            if (auto *TD = TT->getDecl()) {
+              hasSuperTypedef = true;
+              TRY_TO(IndexCtx.handleReference(TD, SuperLoc, D, D,
+                                              SymbolRoleSet()));
+            }
+          }
+        }
+        SymbolRoleSet superRoles{};
+        if (hasSuperTypedef)
+          superRoles |= (SymbolRoleSet)SymbolRole::Implicit;
+        TRY_TO(IndexCtx.handleReference(SuperD, SuperLoc, D, D, superRoles,
             SymbolRelation{(unsigned)SymbolRole::RelationBaseOf, D}));
       }
-      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
+      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
+                                       SuperLoc));
       TRY_TO(IndexCtx.indexDeclContext(D));
     } else {
       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
@@ -260,8 +403,9 @@
 
   bool VisitObjCProtocolDecl(const ObjCProtocolDecl *D) {
     if (D->isThisDeclarationADefinition()) {
-      TRY_TO(IndexCtx.handleDecl(D));
-      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
+      TRY_DECL(D, IndexCtx.handleDecl(D));
+      TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
+                                       /*superLoc=*/SourceLocation()));
       TRY_TO(IndexCtx.indexDeclContext(D));
     } else {
       return IndexCtx.handleReference(D, D->getLocation(), nullptr,
@@ -278,15 +422,18 @@
     if (Class->isImplicitInterfaceDecl())
       IndexCtx.handleDecl(Class);
 
-    if (!IndexCtx.handleDecl(D))
-      return false;
+    TRY_DECL(D, IndexCtx.handleDecl(D));
 
-    // Index the ivars first to make sure the synthesized ivars are indexed
-    // before indexing the methods that can reference them.
-    for (const auto *IvarI : D->ivars())
-      IndexCtx.indexDecl(IvarI);
+    // Visit implicit @synthesize property implementations first as their
+    // location is reported at the name of the @implementation block. This
+    // serves no purpose other than to simplify the FileCheck-based tests.
+    for (const auto *I : D->property_impls()) {
+      if (I->getLocation().isInvalid())
+        IndexCtx.indexDecl(I);
+    }
     for (const auto *I : D->decls()) {
-      if (!isa<ObjCIvarDecl>(I))
+      if (!isa<ObjCPropertyImplDecl>(I) ||
+          cast<ObjCPropertyImplDecl>(I)->getLocation().isValid())
         IndexCtx.indexDecl(I);
     }
 
@@ -294,6 +441,8 @@
   }
 
   bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
+    if (!IndexCtx.shouldIndex(D))
+      return true;
     const ObjCInterfaceDecl *C = D->getClassInterface();
     if (!C)
       return true;
@@ -305,7 +454,8 @@
     if (!CategoryLoc.isValid())
       CategoryLoc = D->getLocation();
     TRY_TO(IndexCtx.handleDecl(D, CategoryLoc));
-    TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D));
+    TRY_TO(handleReferencedProtocols(D->getReferencedProtocols(), D,
+                                     /*superLoc=*/SourceLocation()));
     TRY_TO(IndexCtx.indexDeclContext(D));
     return true;
   }
@@ -321,8 +471,7 @@
     SourceLocation CategoryLoc = D->getCategoryNameLoc();
     if (!CategoryLoc.isValid())
       CategoryLoc = D->getLocation();
-    if (!IndexCtx.handleDecl(D, CategoryLoc))
-      return false;
+    TRY_DECL(D, IndexCtx.handleDecl(D, CategoryLoc));
     IndexCtx.indexDeclContext(D);
     return true;
   }
@@ -344,8 +493,7 @@
     if (ObjCMethodDecl *MD = D->getSetterMethodDecl())
       if (MD->getLexicalDeclContext() == D->getLexicalDeclContext())
         handleObjCMethod(MD, D);
-    if (!IndexCtx.handleDecl(D))
-      return false;
+    TRY_DECL(D, IndexCtx.handleDecl(D));
     if (IBOutletCollectionAttr *attr = D->getAttr<IBOutletCollectionAttr>())
       IndexCtx.indexTypeSourceInfo(attr->getInterfaceLoc(), D,
                                    D->getLexicalDeclContext(), false, true);
@@ -355,43 +503,74 @@
 
   bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
     ObjCPropertyDecl *PD = D->getPropertyDecl();
-    if (!IndexCtx.handleReference(PD, D->getLocation(),
-                             /*Parent=*/cast<NamedDecl>(D->getDeclContext()),
-                             D->getDeclContext(), SymbolRoleSet(), {},
-                             /*RefE=*/nullptr, D))
-      return false;
+    auto *Container = cast<ObjCImplDecl>(D->getDeclContext());
+    SourceLocation Loc = D->getLocation();
+    SymbolRoleSet Roles = 0;
+    SmallVector<SymbolRelation, 1> Relations;
+
+    if (ObjCIvarDecl *ID = D->getPropertyIvarDecl())
+      Relations.push_back({(SymbolRoleSet)SymbolRole::RelationAccessorOf, ID});
+    if (Loc.isInvalid()) {
+      Loc = Container->getLocation();
+      Roles |= (SymbolRoleSet)SymbolRole::Implicit;
+    }
+    TRY_DECL(D, IndexCtx.handleDecl(D, Loc, Roles, Relations));
 
     if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
       return true;
-    assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
-    
-    if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
-      if (!IvarD->getSynthesize())
-        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
-                                 D->getDeclContext(), SymbolRoleSet());
-    }
 
-    auto *ImplD = cast<ObjCImplDecl>(D->getDeclContext());
+    assert(D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize);
+    SymbolRoleSet AccessorMethodRoles =
+      SymbolRoleSet(SymbolRole::Dynamic) | SymbolRoleSet(SymbolRole::Implicit);
     if (ObjCMethodDecl *MD = PD->getGetterMethodDecl()) {
       if (MD->isPropertyAccessor() &&
-          !hasUserDefined(MD, ImplD))
-        IndexCtx.handleDecl(MD, D->getLocation(), SymbolRoleSet(), {}, ImplD);
+          !hasUserDefined(MD, Container))
+        IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
     }
     if (ObjCMethodDecl *MD = PD->getSetterMethodDecl()) {
       if (MD->isPropertyAccessor() &&
-          !hasUserDefined(MD, ImplD))
-        IndexCtx.handleDecl(MD, D->getLocation(), SymbolRoleSet(), {}, ImplD);
+          !hasUserDefined(MD, Container))
+        IndexCtx.handleDecl(MD, Loc, AccessorMethodRoles, {}, Container);
+    }
+    if (ObjCIvarDecl *IvarD = D->getPropertyIvarDecl()) {
+      if (IvarD->getSynthesize()) {
+        // For synthesized ivars, use the location of its name in the
+        // corresponding @synthesize. If there isn't one, use the containing
+        // @implementation's location, rather than the property's location,
+        // otherwise the header file containing the @interface will have different
+        // indexing contents based on whether the @implementation was present or
+        // not in the translation unit.
+        SymbolRoleSet IvarRoles = 0;
+        SourceLocation IvarLoc = D->getPropertyIvarDeclLoc();
+        if (D->getLocation().isInvalid()) {
+          IvarLoc = Container->getLocation();
+          IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
+        } else if (D->getLocation() == IvarLoc) {
+          IvarRoles = (SymbolRoleSet)SymbolRole::Implicit;
+        }
+        TRY_DECL(IvarD, IndexCtx.handleDecl(IvarD, IvarLoc, IvarRoles));
+      } else {
+        IndexCtx.handleReference(IvarD, D->getPropertyIvarDeclLoc(), nullptr,
+                                 D->getDeclContext(), SymbolRoleSet());
+      }
     }
     return true;
   }
 
   bool VisitNamespaceDecl(const NamespaceDecl *D) {
-    if (!IndexCtx.handleDecl(D))
-      return false;
+    TRY_DECL(D, IndexCtx.handleDecl(D));
     IndexCtx.indexDeclContext(D);
     return true;
   }
 
+  bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
+    TRY_DECL(D, IndexCtx.handleDecl(D));
+    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
+    IndexCtx.handleReference(D->getAliasedNamespace(), D->getTargetNameLoc(), D,
+                             D->getLexicalDeclContext());
+    return true;
+  }
+
   bool VisitUsingDecl(const UsingDecl *D) {
     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
@@ -408,8 +587,12 @@
     const DeclContext *DC = D->getDeclContext()->getRedeclContext();
     const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
 
-    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
-                                         D->getLexicalDeclContext());
+    // NNS for the local 'using namespace' directives is visited by the body
+    // visitor.
+    if (!D->getParentFunctionOrMethod())
+      IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
+                                           D->getLexicalDeclContext());
+
     return IndexCtx.handleReference(D->getNominatedNamespaceAsWritten(),
                                     D->getLocation(), Parent,
                                     D->getLexicalDeclContext(),
@@ -420,13 +603,61 @@
                                            ClassTemplateSpecializationDecl *D) {
     // FIXME: Notify subsequent callbacks if info comes from implicit
     // instantiation.
-    if (D->isThisDeclarationADefinition())
-      IndexCtx.indexTagDecl(D);
+    if (D->isThisDeclarationADefinition()) {
+      llvm::PointerUnion<ClassTemplateDecl *,
+                         ClassTemplatePartialSpecializationDecl *>
+          Template = D->getSpecializedTemplateOrPartial();
+      const Decl *SpecializationOf =
+          Template.is<ClassTemplateDecl *>()
+              ? (Decl *)Template.get<ClassTemplateDecl *>()
+              : Template.get<ClassTemplatePartialSpecializationDecl *>();
+      IndexCtx.indexTagDecl(
+          D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
+                            SpecializationOf));
+    }
+    if (TypeSourceInfo *TSI = D->getTypeAsWritten())
+      IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
+                                   D->getLexicalDeclContext());
+    return true;
+  }
+
+  static bool shouldIndexTemplateParameterDefaultValue(const NamedDecl *D) {
+    if (!D)
+      return false;
+    // We want to index the template parameters only once when indexing the
+    // canonical declaration.
+    if (const auto *FD = dyn_cast<FunctionDecl>(D))
+      return FD->getCanonicalDecl() == FD;
+    else if (const auto *TD = dyn_cast<TagDecl>(D))
+      return TD->getCanonicalDecl() == TD;
+    else if (const auto *VD = dyn_cast<VarDecl>(D))
+      return VD->getCanonicalDecl() == VD;
     return true;
   }
 
   bool VisitTemplateDecl(const TemplateDecl *D) {
     // FIXME: Template parameters.
+
+    // Index the default values for the template parameters.
+    const NamedDecl *Parent = D->getTemplatedDecl();
+    if (D->getTemplateParameters() &&
+        shouldIndexTemplateParameterDefaultValue(Parent)) {
+      const TemplateParameterList *Params = D->getTemplateParameters();
+      for (const NamedDecl *TP : *Params) {
+        if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(TP)) {
+          if (TTP->hasDefaultArgument())
+            IndexCtx.indexTypeSourceInfo(TTP->getDefaultArgumentInfo(), Parent);
+        } else if (const auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(TP)) {
+          if (NTTP->hasDefaultArgument())
+            IndexCtx.indexBody(NTTP->getDefaultArgument(), Parent);
+        } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
+          if (TTPD->hasDefaultArgument())
+            handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
+                                      /*DC=*/nullptr);
+        }
+      }
+    }
+
     return Visit(D->getTemplatedDecl());
   }
 
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index 84984fc..191d480 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -49,6 +49,39 @@
   }
 }
 
+bool index::isFunctionLocalSymbol(const Decl *D) {
+  assert(D);
+
+  if (isa<ParmVarDecl>(D))
+    return true;
+
+  if (isa<TemplateTemplateParmDecl>(D))
+    return true;
+
+  if (isa<ObjCTypeParamDecl>(D))
+    return true;
+
+  if (isa<UsingDirectiveDecl>(D))
+    return false;
+  if (!D->getParentFunctionOrMethod())
+    return false;
+
+  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+    switch (ND->getFormalLinkage()) {
+      case NoLinkage:
+      case VisibleNoLinkage:
+      case InternalLinkage:
+        return true;
+      case UniqueExternalLinkage:
+        llvm_unreachable("Not a sema linkage");
+      case ExternalLinkage:
+        return false;
+    }
+  }
+
+  return true;
+}
+
 SymbolInfo index::getSymbolInfo(const Decl *D) {
   assert(D);
   SymbolInfo Info;
@@ -57,6 +90,10 @@
   Info.Properties = SymbolPropertySet();
   Info.Lang = SymbolLanguage::C;
 
+  if (isFunctionLocalSymbol(D)) {
+    Info.Properties |= (unsigned)SymbolProperty::Local;
+  }
+
   if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
     switch (TD->getTagKind()) {
     case TTK_Struct:
@@ -94,10 +131,13 @@
 
   } else if (auto *VD = dyn_cast<VarDecl>(D)) {
     Info.Kind = SymbolKind::Variable;
-    if (isa<CXXRecordDecl>(D->getDeclContext())) {
+    if (isa<ParmVarDecl>(D)) {
+      Info.Kind = SymbolKind::Parameter;
+    } else if (isa<CXXRecordDecl>(D->getDeclContext())) {
       Info.Kind = SymbolKind::StaticProperty;
       Info.Lang = SymbolLanguage::CXX;
     }
+
     if (isa<VarTemplatePartialSpecializationDecl>(D)) {
       Info.Lang = SymbolLanguage::CXX;
       Info.Properties |= (unsigned)SymbolProperty::Generic;
@@ -147,10 +187,18 @@
       Info.Lang = SymbolLanguage::ObjC;
       break;
     case Decl::ObjCCategory:
-    case Decl::ObjCCategoryImpl:
+    case Decl::ObjCCategoryImpl: {
       Info.Kind = SymbolKind::Extension;
       Info.Lang = SymbolLanguage::ObjC;
+      const ObjCInterfaceDecl *ClsD = nullptr;
+      if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D))
+        ClsD = CatD->getClassInterface();
+      else
+        ClsD = cast<ObjCCategoryImplDecl>(D)->getClassInterface();
+      if (isUnitTestCase(ClsD))
+        Info.Properties |= (unsigned)SymbolProperty::UnitTest;
       break;
+    }
     case Decl::ObjCMethod:
       if (cast<ObjCMethodDecl>(D)->isInstanceMethod()) {
         const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
@@ -272,14 +320,20 @@
   if (Info.Properties & (unsigned)SymbolProperty::Generic)
     Info.Lang = SymbolLanguage::CXX;
 
+  if (auto *attr = D->getExternalSourceSymbolAttr()) {
+    if (attr->getLanguage() == "Swift")
+      Info.Lang = SymbolLanguage::Swift;
+  }
+
   return Info;
 }
 
-void index::applyForEachSymbolRole(SymbolRoleSet Roles,
-                                   llvm::function_ref<void(SymbolRole)> Fn) {
+bool index::applyForEachSymbolRoleInterruptible(SymbolRoleSet Roles,
+                                   llvm::function_ref<bool(SymbolRole)> Fn) {
 #define APPLY_FOR_ROLE(Role) \
   if (Roles & (unsigned)SymbolRole::Role) \
-    Fn(SymbolRole::Role)
+    if (!Fn(SymbolRole::Role)) \
+      return false;
 
   APPLY_FOR_ROLE(Declaration);
   APPLY_FOR_ROLE(Definition);
@@ -299,8 +353,19 @@
   APPLY_FOR_ROLE(RelationAccessorOf);
   APPLY_FOR_ROLE(RelationContainedBy);
   APPLY_FOR_ROLE(RelationIBTypeOf);
+  APPLY_FOR_ROLE(RelationSpecializationOf);
 
 #undef APPLY_FOR_ROLE
+
+  return true;
+}
+
+void index::applyForEachSymbolRole(SymbolRoleSet Roles,
+                                   llvm::function_ref<void(SymbolRole)> Fn) {
+  applyForEachSymbolRoleInterruptible(Roles, [&](SymbolRole r) -> bool {
+    Fn(r);
+    return true;
+  });
 }
 
 void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) {
@@ -329,6 +394,7 @@
     case SymbolRole::RelationAccessorOf: OS << "RelAcc"; break;
     case SymbolRole::RelationContainedBy: OS << "RelCont"; break;
     case SymbolRole::RelationIBTypeOf: OS << "RelIBType"; break;
+    case SymbolRole::RelationSpecializationOf: OS << "RelSpecialization"; break;
     }
   });
 }
@@ -378,6 +444,8 @@
   case SymbolKind::Constructor: return "constructor";
   case SymbolKind::Destructor: return "destructor";
   case SymbolKind::ConversionFunction: return "coversion-func";
+  case SymbolKind::Parameter: return "param";
+  case SymbolKind::CommentTag: return "comment-tag";
   }
   llvm_unreachable("invalid symbol kind");
 }
@@ -389,6 +457,20 @@
   case SymbolSubKind::CXXMoveConstructor: return "cxx-move-ctor";
   case SymbolSubKind::AccessorGetter: return "acc-get";
   case SymbolSubKind::AccessorSetter: return "acc-set";
+  case SymbolSubKind::SwiftAccessorWillSet: return "acc-willset";
+  case SymbolSubKind::SwiftAccessorDidSet: return "acc-didset";
+  case SymbolSubKind::SwiftAccessorAddressor: return "acc-addr";
+  case SymbolSubKind::SwiftAccessorMutableAddressor: return "acc-mutaddr";
+  case SymbolSubKind::SwiftExtensionOfStruct: return "ext-struct";
+  case SymbolSubKind::SwiftExtensionOfClass: return "ext-class";
+  case SymbolSubKind::SwiftExtensionOfEnum: return "ext-enum";
+  case SymbolSubKind::SwiftExtensionOfProtocol: return "ext-protocol";
+  case SymbolSubKind::SwiftPrefixOperator: return "prefix-operator";
+  case SymbolSubKind::SwiftPostfixOperator: return "postfix-operator";
+  case SymbolSubKind::SwiftInfixOperator: return "infix-operator";
+  case SymbolSubKind::SwiftSubscript: return "subscript";
+  case SymbolSubKind::SwiftAssociatedType: return "associated-type";
+  case SymbolSubKind::SwiftGenericTypeParam: return "generic-type-param";
   }
   llvm_unreachable("invalid symbol subkind");
 }
@@ -398,6 +480,7 @@
   case SymbolLanguage::C: return "C";
   case SymbolLanguage::ObjC: return "ObjC";
   case SymbolLanguage::CXX: return "C++";
+  case SymbolLanguage::Swift: return "Swift";
   }
   llvm_unreachable("invalid symbol language kind");
 }
@@ -415,6 +498,7 @@
   APPLY_FOR_PROPERTY(IBAnnotated);
   APPLY_FOR_PROPERTY(IBOutletCollection);
   APPLY_FOR_PROPERTY(GKInspectable);
+  APPLY_FOR_PROPERTY(Local);
 
 #undef APPLY_FOR_PROPERTY
 }
@@ -434,6 +518,7 @@
     case SymbolProperty::IBAnnotated: OS << "IB"; break;
     case SymbolProperty::IBOutletCollection: OS << "IBColl"; break;
     case SymbolProperty::GKInspectable: OS << "GKI"; break;
+    case SymbolProperty::Local: OS << "local"; break;
     }
   });
 }
diff --git a/lib/Index/IndexTypeSourceInfo.cpp b/lib/Index/IndexTypeSourceInfo.cpp
index 38bbb30..ae27ebe 100644
--- a/lib/Index/IndexTypeSourceInfo.cpp
+++ b/lib/Index/IndexTypeSourceInfo.cpp
@@ -40,18 +40,36 @@
   
   bool shouldWalkTypesOfTypeLocs() const { return false; }
 
-  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
-    return IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
-                                    Parent, ParentDC, SymbolRoleSet(),
-                                    Relations);
-  }
-
 #define TRY_TO(CALL_EXPR)                                                      \
   do {                                                                         \
     if (!CALL_EXPR)                                                            \
       return false;                                                            \
   } while (0)
 
+  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+    SourceLocation Loc = TL.getNameLoc();
+    TypedefNameDecl *ND = TL.getTypedefNameDecl();
+    if (ND->isTransparentTag()) {
+      TagDecl *Underlying = ND->getUnderlyingType()->getAsTagDecl();
+      return IndexCtx.handleReference(Underlying, Loc, Parent,
+                                      ParentDC, SymbolRoleSet(), Relations);
+    }
+    if (IsBase) {
+      TRY_TO(IndexCtx.handleReference(ND, Loc,
+                                      Parent, ParentDC, SymbolRoleSet()));
+      if (auto *CD = TL.getType()->getAsCXXRecordDecl()) {
+        TRY_TO(IndexCtx.handleReference(CD, Loc, Parent, ParentDC,
+                                        (unsigned)SymbolRole::Implicit,
+                                        Relations));
+      }
+    } else {
+      TRY_TO(IndexCtx.handleReference(ND, Loc,
+                                      Parent, ParentDC, SymbolRoleSet(),
+                                      Relations));
+    }
+    return true;
+  }
+
   bool traverseParamVarHelper(ParmVarDecl *D) {
     TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
     if (D->getTypeSourceInfo())
@@ -123,6 +141,34 @@
     return true;
   }
 
+  bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+    const DependentNameType *DNT = TL.getTypePtr();
+    const NestedNameSpecifier *NNS = DNT->getQualifier();
+    const Type *T = NNS->getAsType();
+    if (!T)
+      return true;
+    const TemplateSpecializationType *TST =
+        T->getAs<TemplateSpecializationType>();
+    if (!TST)
+      return true;
+    TemplateName TN = TST->getTemplateName();
+    const ClassTemplateDecl *TD =
+        dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
+    if (!TD)
+      return true;
+    CXXRecordDecl *RD = TD->getTemplatedDecl();
+    if (!RD->hasDefinition())
+      return true;
+    RD = RD->getDefinition();
+    DeclarationName Name(DNT->getIdentifier());
+    std::vector<const NamedDecl *> Symbols = RD->lookupDependentName(
+        Name, [](const NamedDecl *ND) { return isa<TypeDecl>(ND); });
+    if (Symbols.size() != 1)
+      return true;
+    return IndexCtx.handleReference(Symbols[0], TL.getNameLoc(), Parent,
+                                    ParentDC, SymbolRoleSet(), Relations);
+  }
+
   bool TraverseStmt(Stmt *S) {
     IndexCtx.indexBody(S, Parent, ParentDC);
     return true;
@@ -166,7 +212,7 @@
 
   if (!DC)
     DC = Parent->getLexicalDeclContext();
-  SourceLocation Loc = NNS.getSourceRange().getBegin();
+  SourceLocation Loc = NNS.getLocalBeginLoc();
 
   switch (NNS.getNestedNameSpecifier()->getKind()) {
   case NestedNameSpecifier::Identifier:
@@ -190,11 +236,14 @@
   }
 }
 
-void IndexingContext::indexTagDecl(const TagDecl *D) {
-  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
+void IndexingContext::indexTagDecl(const TagDecl *D,
+                                   ArrayRef<SymbolRelation> Relations) {
+  if (!shouldIndex(D))
+    return;
+  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
     return;
 
-  if (handleDecl(D)) {
+  if (handleDecl(D, /*Roles=*/SymbolRoleSet(), Relations)) {
     if (D->isThisDeclarationADefinition()) {
       indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
       if (auto CXXRD = dyn_cast<CXXRecordDecl>(D)) {
diff --git a/lib/Index/IndexingAction.cpp b/lib/Index/IndexingAction.cpp
index d744293..cac24d4 100644
--- a/lib/Index/IndexingAction.cpp
+++ b/lib/Index/IndexingAction.cpp
@@ -13,6 +13,7 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Lex/Preprocessor.h"
+#include "clang/Serialization/ASTReader.h"
 
 using namespace clang;
 using namespace clang::index;
@@ -173,4 +174,20 @@
   IndexCtx.setASTContext(Unit.getASTContext());
   DataConsumer->initialize(Unit.getASTContext());
   indexTranslationUnit(Unit, IndexCtx);
+  DataConsumer->finish();
+}
+
+void index::indexModuleFile(serialization::ModuleFile &Mod,
+                            ASTReader &Reader,
+                            std::shared_ptr<IndexDataConsumer> DataConsumer,
+                            IndexingOptions Opts) {
+  ASTContext &Ctx = Reader.getContext();
+  IndexingContext IndexCtx(Opts, *DataConsumer);
+  IndexCtx.setASTContext(Ctx);
+  DataConsumer->initialize(Ctx);
+
+  for (const Decl *D :Reader.getModuleFileLevelDecls(Mod)) {
+    IndexCtx.indexTopLevelDecl(D);
+  }
+  DataConsumer->finish();
 }
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index 6dd6c0c..9995a22 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -17,6 +17,21 @@
 using namespace clang;
 using namespace index;
 
+static bool isGeneratedDecl(const Decl *D) {
+  if (auto *attr = D->getAttr<ExternalSourceSymbolAttr>()) {
+    return attr->getGeneratedDeclaration();
+  }
+  return false;
+}
+
+bool IndexingContext::shouldIndex(const Decl *D) {
+  return !isGeneratedDecl(D);
+}
+
+const LangOptions &IndexingContext::getLangOpts() const {
+  return Ctx->getLangOpts();
+}
+
 bool IndexingContext::shouldIndexFunctionLocalSymbols() const {
   return IndexOpts.IndexFunctionLocals;
 }
@@ -24,9 +39,7 @@
 bool IndexingContext::handleDecl(const Decl *D,
                                  SymbolRoleSet Roles,
                                  ArrayRef<SymbolRelation> Relations) {
-  return handleDeclOccurrence(D, D->getLocation(), /*IsRef=*/false,
-                              cast<Decl>(D->getDeclContext()), Roles, Relations,
-                              nullptr, nullptr, D->getDeclContext());
+  return handleDecl(D, D->getLocation(), Roles, Relations);
 }
 
 bool IndexingContext::handleDecl(const Decl *D, SourceLocation Loc,
@@ -35,9 +48,14 @@
                                  const DeclContext *DC) {
   if (!DC)
     DC = D->getDeclContext();
+
+  const Decl *OrigD = D;
+  if (isa<ObjCPropertyImplDecl>(D)) {
+    D = cast<ObjCPropertyImplDecl>(D)->getPropertyDecl();
+  }
   return handleDeclOccurrence(D, Loc, /*IsRef=*/false, cast<Decl>(DC),
                               Roles, Relations,
-                              nullptr, nullptr, DC);
+                              nullptr, OrigD, DC);
 }
 
 bool IndexingContext::handleReference(const NamedDecl *D, SourceLocation Loc,
@@ -47,7 +65,7 @@
                                       ArrayRef<SymbolRelation> Relations,
                                       const Expr *RefE,
                                       const Decl *RefD) {
-  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalDecl(D))
+  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
     return true;
 
   if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D))
@@ -97,34 +115,6 @@
   return DataConsumer.handleModuleOccurence(ImportD, Roles, FID, Offset);
 }
 
-bool IndexingContext::isFunctionLocalDecl(const Decl *D) {
-  assert(D);
-
-  if (isa<TemplateTemplateParmDecl>(D))
-    return true;
-
-  if (isa<ObjCTypeParamDecl>(D))
-    return true;
-
-  if (!D->getParentFunctionOrMethod())
-    return false;
-
-  if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
-    switch (ND->getFormalLinkage()) {
-    case NoLinkage:
-    case VisibleNoLinkage:
-    case InternalLinkage:
-      return true;
-    case UniqueExternalLinkage:
-      llvm_unreachable("Not a sema linkage");
-    case ExternalLinkage:
-      return false;
-    }
-  }
-
-  return true;
-}
-
 bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
   TemplateSpecializationKind TKind = TSK_Undeclared;
   if (const ClassTemplateSpecializationDecl *
@@ -134,6 +124,16 @@
     TKind = FD->getTemplateSpecializationKind();
   } else if (auto *VD = dyn_cast<VarDecl>(D)) {
     TKind = VD->getTemplateSpecializationKind();
+  } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
+    if (RD->getInstantiatedFromMemberClass())
+      TKind = RD->getTemplateSpecializationKind();
+  } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
+    if (ED->getInstantiatedFromMemberEnum())
+      TKind = ED->getTemplateSpecializationKind();
+  } else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D) ||
+             isa<EnumConstantDecl>(D)) {
+    if (const auto *Parent = dyn_cast<Decl>(D->getDeclContext()))
+      return isTemplateImplicitInstantiation(Parent);
   }
   switch (TKind) {
     case TSK_Undeclared:
@@ -161,6 +161,16 @@
   return true;
 }
 
+static const CXXRecordDecl *
+getDeclContextForTemplateInstationPattern(const Decl *D) {
+  if (const auto *CTSD =
+          dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
+    return CTSD->getTemplateInstantiationPattern();
+  else if (const auto *RD = dyn_cast<CXXRecordDecl>(D->getDeclContext()))
+    return RD->getInstantiatedFromMemberClass();
+  return nullptr;
+}
+
 static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
   if (const ClassTemplateSpecializationDecl *
       SD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
@@ -169,6 +179,28 @@
     return FD->getTemplateInstantiationPattern();
   } else if (auto *VD = dyn_cast<VarDecl>(D)) {
     return VD->getTemplateInstantiationPattern();
+  } else if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
+    return RD->getInstantiatedFromMemberClass();
+  } else if (const auto *ED = dyn_cast<EnumDecl>(D)) {
+    return ED->getInstantiatedFromMemberEnum();
+  } else if (isa<FieldDecl>(D) || isa<TypedefNameDecl>(D)) {
+    const auto *ND = cast<NamedDecl>(D);
+    if (const CXXRecordDecl *Pattern =
+            getDeclContextForTemplateInstationPattern(ND)) {
+      for (const NamedDecl *BaseND : Pattern->lookup(ND->getDeclName())) {
+        if (BaseND->isImplicit())
+          continue;
+        if (BaseND->getKind() == ND->getKind())
+          return BaseND;
+      }
+    }
+  } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
+    if (const auto *ED = dyn_cast<EnumDecl>(ECD->getDeclContext())) {
+      if (const EnumDecl *Pattern = ED->getInstantiatedFromMemberEnum()) {
+        for (const NamedDecl *BaseECD : Pattern->lookup(ECD->getDeclName()))
+          return BaseECD;
+      }
+    }
   }
   return nullptr;
 }
@@ -229,6 +261,50 @@
   return D;
 }
 
+static bool shouldReportOccurrenceForSystemDeclOnlyMode(
+    bool IsRef, SymbolRoleSet Roles, ArrayRef<SymbolRelation> Relations) {
+  if (!IsRef)
+    return true;
+
+  auto acceptForRelation = [](SymbolRoleSet roles) -> bool {
+    bool accept = false;
+    applyForEachSymbolRoleInterruptible(roles, [&accept](SymbolRole r) -> bool {
+      switch (r) {
+      case SymbolRole::RelationChildOf:
+      case SymbolRole::RelationBaseOf:
+      case SymbolRole::RelationOverrideOf:
+      case SymbolRole::RelationExtendedBy:
+      case SymbolRole::RelationAccessorOf:
+      case SymbolRole::RelationIBTypeOf:
+        accept = true;
+        return false;
+      case SymbolRole::Declaration:
+      case SymbolRole::Definition:
+      case SymbolRole::Reference:
+      case SymbolRole::Read:
+      case SymbolRole::Write:
+      case SymbolRole::Call:
+      case SymbolRole::Dynamic:
+      case SymbolRole::AddressOf:
+      case SymbolRole::Implicit:
+      case SymbolRole::RelationReceivedBy:
+      case SymbolRole::RelationCalledBy:
+      case SymbolRole::RelationContainedBy:
+      case SymbolRole::RelationSpecializationOf:
+        return true;
+      }
+    });
+    return accept;
+  };
+
+  for (auto &Rel : Relations) {
+    if (acceptForRelation(Rel.Roles))
+      return true;
+  }
+
+  return false;
+}
+
 bool IndexingContext::handleDeclOccurrence(const Decl *D, SourceLocation Loc,
                                            bool IsRef, const Decl *Parent,
                                            SymbolRoleSet Roles,
@@ -264,7 +340,7 @@
     case IndexingOptions::SystemSymbolFilterKind::None:
       return true;
     case IndexingOptions::SystemSymbolFilterKind::DeclarationsOnly:
-      if (IsRef)
+      if (!shouldReportOccurrenceForSystemDeclOnlyMode(IsRef, Roles, Relations))
         return true;
       break;
     case IndexingOptions::SystemSymbolFilterKind::All:
@@ -286,7 +362,7 @@
 
   if (IsRef)
     Roles |= (unsigned)SymbolRole::Reference;
-  else if (isDeclADefinition(D, ContainerDC, *Ctx))
+  else if (isDeclADefinition(OrigD, ContainerDC, *Ctx))
     Roles |= (unsigned)SymbolRole::Definition;
   else
     Roles |= (unsigned)SymbolRole::Declaration;
@@ -313,12 +389,12 @@
   };
 
   if (Parent) {
-    if (IsRef) {
+    if (IsRef || (!isa<ParmVarDecl>(D) && isFunctionLocalSymbol(D))) {
       addRelation(SymbolRelation{
         (unsigned)SymbolRole::RelationContainedBy,
         Parent
       });
-    } else if (!cast<DeclContext>(Parent)->isFunctionOrMethod()) {
+    } else {
       addRelation(SymbolRelation{
         (unsigned)SymbolRole::RelationChildOf,
         Parent
diff --git a/lib/Index/IndexingContext.h b/lib/Index/IndexingContext.h
index dd1dd32..566651c 100644
--- a/lib/Index/IndexingContext.h
+++ b/lib/Index/IndexingContext.h
@@ -48,6 +48,10 @@
 
   void setASTContext(ASTContext &ctx) { Ctx = &ctx; }
 
+  bool shouldIndex(const Decl *D);
+
+  const LangOptions &getLangOpts() const;
+
   bool shouldSuppressRefs() const {
     return false;
   }
@@ -58,7 +62,6 @@
     return false;
   }
 
-  static bool isFunctionLocalDecl(const Decl *D);
   static bool isTemplateImplicitInstantiation(const Decl *D);
 
   bool handleDecl(const Decl *D, SymbolRoleSet Roles = SymbolRoleSet(),
@@ -72,7 +75,7 @@
   bool handleReference(const NamedDecl *D, SourceLocation Loc,
                        const NamedDecl *Parent,
                        const DeclContext *DC,
-                       SymbolRoleSet Roles,
+                       SymbolRoleSet Roles = SymbolRoleSet(),
                        ArrayRef<SymbolRelation> Relations = None,
                        const Expr *RefE = nullptr,
                        const Decl *RefD = nullptr);
@@ -81,7 +84,8 @@
 
   bool indexDecl(const Decl *D);
 
-  void indexTagDecl(const TagDecl *D);
+  void indexTagDecl(const TagDecl *D,
+                    ArrayRef<SymbolRelation> Relations = None);
 
   void indexTypeSourceInfo(TypeSourceInfo *TInfo, const NamedDecl *Parent,
                            const DeclContext *DC = nullptr,
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 58f61c3..808150b 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -46,6 +46,15 @@
   return false;
 }
 
+static StringRef GetExternalSourceContainer(const NamedDecl *D) {
+  if (!D)
+    return StringRef();
+  if (auto *attr = D->getExternalSourceSymbolAttr()) {
+    return attr->getDefinedIn();
+  }
+  return StringRef();
+}
+
 namespace {
 class USRGenerator : public ConstDeclVisitor<USRGenerator> {
   SmallVectorImpl<char> &Buf;
@@ -79,7 +88,8 @@
   void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
   void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
   void VisitClassTemplateDecl(const ClassTemplateDecl *D);
-  void VisitObjCContainerDecl(const ObjCContainerDecl *CD);
+  void VisitObjCContainerDecl(const ObjCContainerDecl *CD,
+                              const ObjCCategoryDecl *CatD = nullptr);
   void VisitObjCMethodDecl(const ObjCMethodDecl *MD);
   void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
   void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
@@ -116,6 +126,8 @@
     return D->getParentFunctionOrMethod() != nullptr;
   }
 
+  void GenExtSymbolContainer(const NamedDecl *D);
+
   /// Generate the string component containing the location of the
   ///  declaration.
   bool GenLoc(const Decl *D, bool IncludeOffset);
@@ -127,13 +139,16 @@
   /// itself.
 
   /// Generate a USR for an Objective-C class.
-  void GenObjCClass(StringRef cls) {
-    generateUSRForObjCClass(cls, Out);
+  void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn,
+                    StringRef CategoryContextExtSymbolDefinedIn) {
+    generateUSRForObjCClass(cls, Out, ExtSymDefinedIn,
+                            CategoryContextExtSymbolDefinedIn);
   }
 
   /// Generate a USR for an Objective-C class category.
-  void GenObjCCategory(StringRef cls, StringRef cat) {
-    generateUSRForObjCCategory(cls, cat, Out);
+  void GenObjCCategory(StringRef cls, StringRef cat,
+                       StringRef clsExt, StringRef catExt) {
+    generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt);
   }
 
   /// Generate a USR fragment for an Objective-C property.
@@ -142,8 +157,8 @@
   }
 
   /// Generate a USR for an Objective-C protocol.
-  void GenObjCProtocol(StringRef prot) {
-    generateUSRForObjCProtocol(prot, Out);
+  void GenObjCProtocol(StringRef prot, StringRef ext) {
+    generateUSRForObjCProtocol(prot, Out, ext);
   }
 
   void VisitType(QualType T);
@@ -204,7 +219,11 @@
   if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
     return;
 
+  const unsigned StartSize = Buf.size();
   VisitDeclContext(D->getDeclContext());
+  if (Buf.size() == StartSize)
+    GenExtSymbolContainer(D);
+
   bool IsTemplate = false;
   if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
     IsTemplate = true;
@@ -310,7 +329,7 @@
   // For a template specialization, mangle the template arguments.
   if (const VarTemplateSpecializationDecl *Spec
                               = dyn_cast<VarTemplateSpecializationDecl>(D)) {
-    const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
+    const TemplateArgumentList &Args = Spec->getTemplateArgs();
     Out << '>';
     for (unsigned I = 0, N = Args.size(); I != N; ++I) {
       Out << '#';
@@ -367,7 +386,16 @@
       IgnoreResults = true;
       return;
     }
-    Visit(ID);
+    auto getCategoryContext = [](const ObjCMethodDecl *D) ->
+                                    const ObjCCategoryDecl * {
+      if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
+        return CD;
+      if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
+        return ICD->getCategoryDecl();
+      return nullptr;
+    };
+    auto *CD = getCategoryContext(D);
+    VisitObjCContainerDecl(ID, CD);
   }
   // Ideally we would use 'GenObjCMethod', but this is such a hot path
   // for Objective-C code that we don't want to use
@@ -376,13 +404,15 @@
       << DeclarationName(D->getSelector());
 }
 
-void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D) {
+void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
+                                          const ObjCCategoryDecl *CatD) {
   switch (D->getKind()) {
     default:
       llvm_unreachable("Invalid ObjC container.");
     case Decl::ObjCInterface:
     case Decl::ObjCImplementation:
-      GenObjCClass(D->getName());
+      GenObjCClass(D->getName(), GetExternalSourceContainer(D),
+                   GetExternalSourceContainer(CatD));
       break;
     case Decl::ObjCCategory: {
       const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
@@ -402,7 +432,9 @@
         GenLoc(CD, /*IncludeOffset=*/true);
       }
       else
-        GenObjCCategory(ID->getName(), CD->getName());
+        GenObjCCategory(ID->getName(), CD->getName(),
+                        GetExternalSourceContainer(ID),
+                        GetExternalSourceContainer(CD));
 
       break;
     }
@@ -417,12 +449,16 @@
         IgnoreResults = true;
         return;
       }
-      GenObjCCategory(ID->getName(), CD->getName());
+      GenObjCCategory(ID->getName(), CD->getName(),
+                      GetExternalSourceContainer(ID),
+                      GetExternalSourceContainer(CD));
       break;
     }
-    case Decl::ObjCProtocol:
-      GenObjCProtocol(cast<ObjCProtocolDecl>(D)->getName());
+    case Decl::ObjCProtocol: {
+      const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
+      GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
       break;
+    }
   }
 }
 
@@ -452,6 +488,8 @@
       ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
     return;
 
+  GenExtSymbolContainer(D);
+
   D = D->getCanonicalDecl();
   VisitDeclContext(D->getDeclContext());
 
@@ -521,7 +559,7 @@
   // For a class template specialization, mangle the template arguments.
   if (const ClassTemplateSpecializationDecl *Spec
                               = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
-    const TemplateArgumentList &Args = Spec->getTemplateInstantiationArgs();
+    const TemplateArgumentList &Args = Spec->getTemplateArgs();
     Out << '>';
     for (unsigned I = 0, N = Args.size(); I != N; ++I) {
       Out << '#';
@@ -544,6 +582,12 @@
   GenLoc(D, /*IncludeOffset=*/true);
 }
 
+void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
+  StringRef Container = GetExternalSourceContainer(D);
+  if (!Container.empty())
+    Out << "@M@" << Container;
+}
+
 bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
   if (generatedLoc)
     return IgnoreResults;
@@ -768,7 +812,13 @@
       T = InjT->getInjectedSpecializationType();
       continue;
     }
-    
+    if (const auto *VT = T->getAs<VectorType>()) {
+      Out << (T->isExtVectorType() ? ']' : '[');
+      Out << VT->getNumElements();
+      T = VT->getElementType();
+      continue;
+    }
+
     // Unhandled type.
     Out << ' ';
     break;
@@ -867,12 +917,34 @@
 // USR generation functions.
 //===----------------------------------------------------------------------===//
 
-void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS) {
+static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
+                                                 StringRef CatSymDefinedIn,
+                                                 raw_ostream &OS) {
+  if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
+    return;
+  if (CatSymDefinedIn.empty()) {
+    OS << "@M@" << ClsSymDefinedIn << '@';
+    return;
+  }
+  OS << "@CM@" << CatSymDefinedIn << '@';
+  if (ClsSymDefinedIn != CatSymDefinedIn) {
+    OS << ClsSymDefinedIn << '@';
+  }
+}
+
+void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
+                                           StringRef ExtSymDefinedIn,
+                                  StringRef CategoryContextExtSymbolDefinedIn) {
+  combineClassAndCategoryExtContainers(ExtSymDefinedIn,
+                                       CategoryContextExtSymbolDefinedIn, OS);
   OS << "objc(cs)" << Cls;
 }
 
 void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
-                                              raw_ostream &OS) {
+                                              raw_ostream &OS,
+                                              StringRef ClsSymDefinedIn,
+                                              StringRef CatSymDefinedIn) {
+  combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
   OS << "objc(cy)" << Cls << '@' << Cat;
 }
 
@@ -891,10 +963,25 @@
   OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
 }
 
-void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS) {
+void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
+                                              StringRef ExtSymDefinedIn) {
+  if (!ExtSymDefinedIn.empty())
+    OS << "@M@" << ExtSymDefinedIn << '@';
   OS << "objc(pl)" << Prot;
 }
 
+void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
+                                            StringRef ExtSymDefinedIn) {
+  if (!ExtSymDefinedIn.empty())
+    OS << "@M@" << ExtSymDefinedIn;
+  OS << "@E@" << EnumName;
+}
+
+void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
+                                              raw_ostream &OS) {
+  OS << '@' << EnumConstantName;
+}
+
 bool clang::index::generateUSRForDecl(const Decl *D,
                                       SmallVectorImpl<char> &Buf) {
   if (!D)
@@ -911,21 +998,30 @@
 bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD,
                                        const SourceManager &SM,
                                        SmallVectorImpl<char> &Buf) {
+  if (!MD)
+    return true;
+  return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
+                             SM, Buf);
+
+}
+
+bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
+                                       const SourceManager &SM,
+                                       SmallVectorImpl<char> &Buf) {
   // Don't generate USRs for things with invalid locations.
-  if (!MD || MD->getLocation().isInvalid())
+  if (MacroName.empty() || Loc.isInvalid())
     return true;
 
   llvm::raw_svector_ostream Out(Buf);
 
   // Assume that system headers are sane.  Don't put source location
   // information into the USR if the macro comes from a system header.
-  SourceLocation Loc = MD->getLocation();
   bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc);
 
   Out << getUSRSpacePrefix();
   if (ShouldGenerateLocation)
     printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
   Out << "@macro@";
-  Out << MD->getName()->getName();
+  Out << MacroName;
   return false;
 }
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index c667f4b..78f4ca8 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -622,7 +622,10 @@
     ArrayRef<std::pair<const FileEntry *, const DirectoryEntry *>> Includers,
     SmallVectorImpl<char> *SearchPath, SmallVectorImpl<char> *RelativePath,
     Module *RequestingModule, ModuleMap::KnownHeader *SuggestedModule,
-    bool SkipCache, bool BuildSystemModule) {
+    bool *IsMapped, bool SkipCache, bool BuildSystemModule) {
+  if (IsMapped)
+    *IsMapped = false;
+
   if (SuggestedModule)
     *SuggestedModule = ModuleMap::KnownHeader();
     
@@ -752,8 +755,11 @@
   if (!SkipCache && CacheLookup.StartIdx == i+1) {
     // Skip querying potentially lots of directories for this lookup.
     i = CacheLookup.HitIdx;
-    if (CacheLookup.MappedName)
+    if (CacheLookup.MappedName) {
       Filename = CacheLookup.MappedName;
+      if (IsMapped)
+        *IsMapped = true;
+    }
   } else {
     // Otherwise, this is the first query, or the previous query didn't match
     // our search start.  We will fill in our found location below, so prime the
@@ -774,6 +780,8 @@
     if (HasBeenMapped) {
       CacheLookup.MappedName =
           copyString(Filename, LookupFileCache.getAllocator());
+      if (IsMapped)
+        *IsMapped = true;
     }
     if (!FE) continue;
 
@@ -837,7 +845,7 @@
       const FileEntry *FE =
           LookupFile(ScratchFilename, IncludeLoc, /*isAngled=*/true, FromDir,
                      CurDir, Includers.front(), SearchPath, RelativePath,
-                     RequestingModule, SuggestedModule);
+                     RequestingModule, SuggestedModule, IsMapped);
 
       if (checkMSVCHeaderSearch(Diags, MSFE, FE, IncludeLoc)) {
         if (SuggestedModule)
@@ -1092,51 +1100,13 @@
 }
 
 bool HeaderSearch::ShouldEnterIncludeFile(Preprocessor &PP,
-                                          const FileEntry *File, bool isImport,
-                                          bool ModulesEnabled, Module *M) {
+                                          const FileEntry *File,
+                                          bool isImport, Module *M) {
   ++NumIncluded; // Count # of attempted #includes.
 
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
 
-  // FIXME: this is a workaround for the lack of proper modules-aware support
-  // for #import / #pragma once
-  auto TryEnterImported = [&](void) -> bool {
-    if (!ModulesEnabled)
-      return false;
-    // Modules with builtins are special; multiple modules use builtins as
-    // modular headers, example:
-    //
-    //    module stddef { header "stddef.h" export * }
-    //
-    // After module map parsing, this expands to:
-    //
-    //    module stddef {
-    //      header "/path_to_builtin_dirs/stddef.h"
-    //      textual "stddef.h"
-    //    }
-    //
-    // It's common that libc++ and system modules will both define such
-    // submodules. Make sure cached results for a builtin header won't
-    // prevent other builtin modules to potentially enter the builtin header.
-    // Note that builtins are header guarded and the decision to actually
-    // enter them is postponed to the controlling macros logic below.
-    bool TryEnterHdr = false;
-    if (FileInfo.isCompilingModuleHeader && FileInfo.isModuleHeader)
-      TryEnterHdr = File->getDir() == ModMap.getBuiltinDir() &&
-                    ModuleMap::isBuiltinHeader(
-                        llvm::sys::path::filename(File->getName()));
-
-    // Textual headers can be #imported from different modules. Since ObjC
-    // headers find in the wild might rely only on #import and do not contain
-    // controlling macros, be conservative and only try to enter textual headers
-    // if such macro is present.
-    if (!FileInfo.isModuleHeader &&
-        FileInfo.getControllingMacro(ExternalLookup))
-      TryEnterHdr = true;
-    return TryEnterHdr;
-  };
-
   // If this is a #import directive, check that we have not already imported
   // this header.
   if (isImport) {
@@ -1144,12 +1114,11 @@
     FileInfo.isImport = true;
 
     // Has this already been #import'ed or #include'd?
-    if (FileInfo.NumIncludes && !TryEnterImported())
-      return false;
+    if (FileInfo.NumIncludes) return false;
   } else {
     // Otherwise, if this is a #include of a file that was previously #import'd
     // or if this is the second #include of a #pragma once file, ignore it.
-    if (FileInfo.isImport && !TryEnterImported())
+    if (FileInfo.isImport)
       return false;
   }
 
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 6025a66..2d3c1c8 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -43,6 +43,8 @@
 
 /// isObjCAtKeyword - Return true if we have an ObjC keyword identifier.
 bool Token::isObjCAtKeyword(tok::ObjCKeywordKind objcKey) const {
+  if (isAnnotation())
+    return false;
   if (IdentifierInfo *II = getIdentifierInfo())
     return II->getObjCKeywordID() == objcKey;
   return false;
@@ -50,6 +52,8 @@
 
 /// getObjCKeywordID - Return the ObjC keyword kind.
 tok::ObjCKeywordKind Token::getObjCKeywordID() const {
+  if (isAnnotation())
+    return tok::objc_not_keyword;
   IdentifierInfo *specId = getIdentifierInfo();
   return specId ? specId->getObjCKeywordID() : tok::objc_not_keyword;
 }
@@ -452,6 +456,29 @@
   return false;
 }
 
+/// Returns the pointer that points to the beginning of line that contains
+/// the given offset, or null if the offset if invalid.
+static const char *findBeginningOfLine(StringRef Buffer, unsigned Offset) {
+  const char *BufStart = Buffer.data();
+  if (Offset >= Buffer.size())
+    return nullptr;
+  const char *StrData = BufStart + Offset;
+
+  if (StrData[0] == '\n' || StrData[0] == '\r')
+    return StrData;
+
+  const char *LexStart = StrData;
+  while (LexStart != BufStart) {
+    if (LexStart[0] == '\n' || LexStart[0] == '\r') {
+      ++LexStart;
+      break;
+    }
+
+    --LexStart;
+  }
+  return LexStart;
+}
+
 static SourceLocation getBeginningOfFileToken(SourceLocation Loc,
                                               const SourceManager &SM,
                                               const LangOptions &LangOpts) {
@@ -467,27 +494,15 @@
 
   // Back up from the current location until we hit the beginning of a line
   // (or the buffer). We'll relex from that point.
-  const char *BufStart = Buffer.data();
-  if (LocInfo.second >= Buffer.size())
+  const char *StrData = Buffer.data() + LocInfo.second;
+  const char *LexStart = findBeginningOfLine(Buffer, LocInfo.second);
+  if (!LexStart || LexStart == StrData)
     return Loc;
   
-  const char *StrData = BufStart+LocInfo.second;
-  if (StrData[0] == '\n' || StrData[0] == '\r')
-    return Loc;
-
-  const char *LexStart = StrData;
-  while (LexStart != BufStart) {
-    if (LexStart[0] == '\n' || LexStart[0] == '\r') {
-      ++LexStart;
-      break;
-    }
-
-    --LexStart;
-  }
-  
   // Create a lexer starting at the beginning of this token.
   SourceLocation LexerStartLoc = Loc.getLocWithOffset(-LocInfo.second);
-  Lexer TheLexer(LexerStartLoc, LangOpts, BufStart, LexStart, Buffer.end());
+  Lexer TheLexer(LexerStartLoc, LangOpts, Buffer.data(), LexStart,
+                 Buffer.end());
   TheLexer.SetCommentRetentionState(true);
   
   // Lex tokens until we find the token that contains the source location.
@@ -1038,6 +1053,27 @@
   return isIdentifierBody(c, LangOpts.DollarIdents);
 }
 
+StringRef Lexer::getIndentationForLine(SourceLocation Loc,
+                                       const SourceManager &SM) {
+  if (Loc.isInvalid() || Loc.isMacroID())
+    return "";
+  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+  if (LocInfo.first.isInvalid())
+    return "";
+  bool Invalid = false;
+  StringRef Buffer = SM.getBufferData(LocInfo.first, &Invalid);
+  if (Invalid)
+    return "";
+  const char *Line = findBeginningOfLine(Buffer, LocInfo.second);
+  if (!Line)
+    return "";
+  StringRef Rest = Buffer.substr(Line - Buffer.data());
+  size_t NumWhitespaceChars = Rest.find_first_not_of(" \t");
+  return NumWhitespaceChars == StringRef::npos
+             ? ""
+             : Rest.take_front(NumWhitespaceChars);
+}
+
 //===----------------------------------------------------------------------===//
 // Diagnostics forwarding code.
 //===----------------------------------------------------------------------===//
@@ -2722,6 +2758,37 @@
   return false;
 }
 
+static const char *findPlaceholderEnd(const char *CurPtr,
+                                      const char *BufferEnd) {
+  if (CurPtr == BufferEnd)
+    return nullptr;
+  BufferEnd -= 1; // Scan until the second last character.
+  for (; CurPtr != BufferEnd; ++CurPtr) {
+    if (CurPtr[0] == '#' && CurPtr[1] == '>')
+      return CurPtr + 2;
+  }
+  return nullptr;
+}
+
+bool Lexer::lexEditorPlaceholder(Token &Result, const char *CurPtr) {
+  assert(CurPtr[-1] == '<' && CurPtr[0] == '#' && "Not a placeholder!");
+  if (!PP || LexingRawMode)
+    return false;
+  const char *End = findPlaceholderEnd(CurPtr + 1, BufferEnd);
+  if (!End)
+    return false;
+  const char *Start = CurPtr - 1;
+  if (!LangOpts.AllowEditorPlaceholders)
+    Diag(Start, diag::err_placeholder_in_source);
+  Result.startToken();
+  FormTokenWithChars(Result, End, tok::raw_identifier);
+  Result.setRawIdentifierData(Start);
+  PP->LookUpIdentifierInfo(Result);
+  Result.setFlag(Token::IsEditorPlaceholder);
+  BufferPtr = End;
+  return true;
+}
+
 bool Lexer::isCodeCompletionPoint(const char *CurPtr) const {
   if (PP && PP->isCodeCompletionEnabled()) {
     SourceLocation Loc = FileLoc.getLocWithOffset(CurPtr-BufferStart);
@@ -3479,6 +3546,8 @@
     } else if (LangOpts.Digraphs && Char == '%') {     // '<%' -> '{'
       CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
       Kind = tok::l_brace;
+    } else if (Char == '#' && lexEditorPlaceholder(Result, CurPtr)) {
+      return true;
     } else {
       Kind = tok::less;
     }
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 1488f62..e440d32 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -144,7 +144,7 @@
 /// \brief Determine whether the given file name is the name of a builtin
 /// header, supplied by Clang to replace, override, or augment existing system
 /// headers.
-bool ModuleMap::isBuiltinHeader(StringRef FileName) {
+static bool isBuiltinHeader(StringRef FileName) {
   return llvm::StringSwitch<bool>(FileName)
            .Case("float.h", true)
            .Case("iso646.h", true)
@@ -165,7 +165,7 @@
   HeadersMap::iterator Known = Headers.find(File);
   if (HeaderInfo.getHeaderSearchOpts().ImplicitModuleMaps &&
       Known == Headers.end() && File->getDir() == BuiltinIncludeDir &&
-      ModuleMap::isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
+      isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
     HeaderInfo.loadTopLevelSystemModules();
     return Headers.find(File);
   }
@@ -568,10 +568,25 @@
     if (LangOpts.CurrentModule == Name)
       SourceModule = Result;
     Modules[Name] = Result;
+    ModuleScopeIDs[Result] = CurrentModuleScopeID;
   }
   return std::make_pair(Result, true);
 }
 
+Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework,
+                                        Module *ShadowingModule) {
+
+  // Create a new module with this name.
+  Module *Result =
+      new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework,
+                 /*IsExplicit=*/false, NumCreatedModules++);
+  Result->ShadowingModule = ShadowingModule;
+  Result->IsAvailable = false;
+  ModuleScopeIDs[Result] = CurrentModuleScopeID;
+
+  return Result;
+}
+
 Module *ModuleMap::createModuleForInterfaceUnit(SourceLocation Loc,
                                                 StringRef Name) {
   assert(LangOpts.CurrentModule == Name && "module name mismatch");
@@ -713,6 +728,8 @@
   Module *Result = new Module(ModuleName, SourceLocation(), Parent,
                               /*IsFramework=*/true, /*IsExplicit=*/false,
                               NumCreatedModules++);
+  if (!Parent)
+    ModuleScopeIDs[Result] = CurrentModuleScopeID;
   InferredModuleAllowedBy[Result] = ModuleMapFile;
   Result->IsInferred = true;
   if (!Parent) {
@@ -1324,6 +1341,8 @@
     AT_extern_c,
     /// \brief The 'exhaustive' attribute.
     AT_exhaustive,
+    // \brief The 'swift_infer_import_as_member' attribute.
+    AT_swift_infer_import_as_member,
     /// \brief The 'no_undeclared_includes' attribute.
     AT_no_undeclared_includes
   };
@@ -1460,6 +1479,7 @@
   SourceLocation LBraceLoc = consumeToken();
   
   // Determine whether this (sub)module has already been defined.
+  Module *ShadowingModule = nullptr;
   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
     if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
       // Skip the module definition.
@@ -1473,23 +1493,35 @@
       }
       return;
     }
-    
-    Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
-      << ModuleName;
-    Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
-    
-    // Skip the module definition.
-    skipUntil(MMToken::RBrace);
-    if (Tok.is(MMToken::RBrace))
-      consumeToken();
-    
-    HadError = true;
-    return;
+
+    if (!Existing->Parent && Map.mayShadowNewModule(Existing)) {
+      ShadowingModule = Existing;
+    } else {
+      // This is not a shawdowed module decl, it is an illegal redefinition.
+      Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition)
+          << ModuleName;
+      Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition);
+
+      // Skip the module definition.
+      skipUntil(MMToken::RBrace);
+      if (Tok.is(MMToken::RBrace))
+        consumeToken();
+
+      HadError = true;
+      return;
+    }
   }
 
   // Start defining this module.
-  ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,
-                                        Explicit).first;
+  if (ShadowingModule) {
+    ActiveModule =
+        Map.createShadowedModule(ModuleName, Framework, ShadowingModule);
+  } else {
+    ActiveModule =
+        Map.findOrCreateModule(ModuleName, ActiveModule, Framework, Explicit)
+            .first;
+  }
+
   ActiveModule->DefinitionLoc = ModuleNameLoc;
   if (Attrs.IsSystem || IsSystem)
     ActiveModule->IsSystem = true;
@@ -1839,7 +1871,7 @@
   Module::UnresolvedHeaderDirective Header;
   Header.FileName = Tok.getString();
   Header.FileNameLoc = consumeToken();
-  
+
   // Check whether we already have an umbrella.
   if (LeadingToken == MMToken::UmbrellaKeyword && ActiveModule->Umbrella) {
     Diags.Report(Header.FileNameLoc, diag::err_mmap_umbrella_clash)
@@ -1859,19 +1891,27 @@
     // Search for the header file within the search directory.
     SmallString<128> FullPathName(Directory->getName());
     unsigned FullPathLength = FullPathName.size();
-    
+
     if (ActiveModule->isPartOfFramework()) {
       appendSubframeworkPaths(ActiveModule, RelativePathName);
-      
+      unsigned RelativePathLength = RelativePathName.size();
+
       // Check whether this file is in the public headers.
       llvm::sys::path::append(RelativePathName, "Headers", Header.FileName);
       llvm::sys::path::append(FullPathName, RelativePathName);
       File = SourceMgr.getFileManager().getFile(FullPathName);
-      
+
+      // Check whether this file is in the private headers.
       if (!File) {
-        // Check whether this file is in the private headers.
-        // FIXME: Should we retain the subframework paths here?
-        RelativePathName.clear();
+        // Ideally, private modules in the form 'FrameworkName.Private' should
+        // be defined as 'module FrameworkName.Private', and not as
+        // 'framework module FrameworkName.Private', since a 'Private.Framework'
+        // does not usually exist. However, since both are currently widely used
+        // for private modules, make sure we find the right path in both cases.
+        if (ActiveModule->IsFramework && ActiveModule->Name == "Private")
+          RelativePathName.clear();
+        else
+          RelativePathName.resize(RelativePathLength);
         FullPathName.resize(FullPathLength);
         llvm::sys::path::append(RelativePathName, "PrivateHeaders",
                                 Header.FileName);
@@ -1889,7 +1929,7 @@
       // supplied by Clang. Find that builtin header.
       if (ActiveModule->IsSystem && LeadingToken != MMToken::UmbrellaKeyword &&
           BuiltinIncludeDir && BuiltinIncludeDir != Directory &&
-          ModuleMap::isBuiltinHeader(Header.FileName)) {
+          isBuiltinHeader(Header.FileName)) {
         SmallString<128> BuiltinPathName(BuiltinIncludeDir->getName());
         llvm::sys::path::append(BuiltinPathName, Header.FileName);
         BuiltinFile = SourceMgr.getFileManager().getFile(BuiltinPathName);
@@ -2428,6 +2468,7 @@
           .Case("extern_c", AT_extern_c)
           .Case("no_undeclared_includes", AT_no_undeclared_includes)
           .Case("system", AT_system)
+          .Case("swift_infer_import_as_member", AT_swift_infer_import_as_member)
           .Default(AT_unknown);
     switch (Attribute) {
     case AT_unknown:
@@ -2443,6 +2484,10 @@
       Attrs.IsExternC = true;
       break;
 
+    case AT_swift_infer_import_as_member:
+      Attrs.IsSwiftInferImportAsMember = true;
+      break;
+
     case AT_exhaustive:
       Attrs.IsExhaustive = true;
       break;
diff --git a/lib/Lex/PPCaching.cpp b/lib/Lex/PPCaching.cpp
index 45bdce3..f5e8cdc 100644
--- a/lib/Lex/PPCaching.cpp
+++ b/lib/Lex/PPCaching.cpp
@@ -35,6 +35,29 @@
   BacktrackPositions.pop_back();
 }
 
+Preprocessor::CachedTokensRange Preprocessor::LastCachedTokenRange() {
+  assert(isBacktrackEnabled());
+  auto PrevCachedLexPos = BacktrackPositions.back();
+  return CachedTokensRange{PrevCachedLexPos, CachedLexPos};
+}
+
+void Preprocessor::EraseCachedTokens(CachedTokensRange TokenRange) {
+  assert(TokenRange.Begin <= TokenRange.End);
+  if (CachedLexPos == TokenRange.Begin && TokenRange.Begin != TokenRange.End) {
+    // We have backtracked to the start of the token range as we want to consume
+    // them again. Erase the tokens only after consuming then.
+    assert(!CachedTokenRangeToErase);
+    CachedTokenRangeToErase = TokenRange;
+    return;
+  }
+  // The cached tokens were committed, so they should be erased now.
+  assert(TokenRange.End == CachedLexPos);
+  CachedTokens.erase(CachedTokens.begin() + TokenRange.Begin,
+                     CachedTokens.begin() + TokenRange.End);
+  CachedLexPos = TokenRange.Begin;
+  ExitCachingLexMode();
+}
+
 // Make Preprocessor re-lex the tokens that were lexed since
 // EnableBacktrackAtThisPos() was previously called.
 void Preprocessor::Backtrack() {
@@ -51,6 +74,13 @@
 
   if (CachedLexPos < CachedTokens.size()) {
     Result = CachedTokens[CachedLexPos++];
+    // Erase the some of the cached tokens after they are consumed when
+    // asked to do so.
+    if (CachedTokenRangeToErase &&
+        CachedTokenRangeToErase->End == CachedLexPos) {
+      EraseCachedTokens(*CachedTokenRangeToErase);
+      CachedTokenRangeToErase = None;
+    }
     return;
   }
 
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 322c580..2f7d34f 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -752,16 +752,11 @@
 }
 
 const FileEntry *Preprocessor::LookupFile(
-    SourceLocation FilenameLoc,
-    StringRef Filename,
-    bool isAngled,
-    const DirectoryLookup *FromDir,
-    const FileEntry *FromFile,
-    const DirectoryLookup *&CurDir,
-    SmallVectorImpl<char> *SearchPath,
+    SourceLocation FilenameLoc, StringRef Filename, bool isAngled,
+    const DirectoryLookup *FromDir, const FileEntry *FromFile,
+    const DirectoryLookup *&CurDir, SmallVectorImpl<char> *SearchPath,
     SmallVectorImpl<char> *RelativePath,
-    ModuleMap::KnownHeader *SuggestedModule,
-    bool SkipCache) {
+    ModuleMap::KnownHeader *SuggestedModule, bool *IsMapped, bool SkipCache) {
   Module *RequestingModule = getModuleForLocation(FilenameLoc);
   bool RequestingModuleIsModuleInterface = !SourceMgr.isInMainFile(FilenameLoc);
 
@@ -819,7 +814,7 @@
     while (const FileEntry *FE = HeaderInfo.LookupFile(
                Filename, FilenameLoc, isAngled, TmpFromDir, TmpCurDir,
                Includers, SearchPath, RelativePath, RequestingModule,
-               SuggestedModule, SkipCache)) {
+               SuggestedModule, /*IsMapped=*/nullptr, SkipCache)) {
       // Keep looking as if this file did a #include_next.
       TmpFromDir = TmpCurDir;
       ++TmpFromDir;
@@ -835,7 +830,7 @@
   // Do a standard file entry lookup.
   const FileEntry *FE = HeaderInfo.LookupFile(
       Filename, FilenameLoc, isAngled, FromDir, CurDir, Includers, SearchPath,
-      RelativePath, RequestingModule, SuggestedModule, SkipCache,
+      RelativePath, RequestingModule, SuggestedModule, IsMapped, SkipCache,
       BuildSystemModule);
   if (FE) {
     if (SuggestedModule && !LangOpts.AsmPreprocessor)
@@ -1783,6 +1778,7 @@
   }
 
   // Search include directories.
+  bool IsMapped = false;
   const DirectoryLookup *CurDir;
   SmallString<1024> SearchPath;
   SmallString<1024> RelativePath;
@@ -1801,7 +1797,7 @@
       FilenameLoc, LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename,
       isAngled, LookupFrom, LookupFromFile, CurDir,
       Callbacks ? &SearchPath : nullptr, Callbacks ? &RelativePath : nullptr,
-      &SuggestedModule);
+      &SuggestedModule, &IsMapped);
 
   if (!File) {
     if (Callbacks) {
@@ -1818,7 +1814,7 @@
               FilenameLoc,
               LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, isAngled,
               LookupFrom, LookupFromFile, CurDir, nullptr, nullptr,
-              &SuggestedModule, /*SkipCache*/ true);
+              &SuggestedModule, &IsMapped, /*SkipCache*/ true);
         }
       }
     }
@@ -1833,8 +1829,7 @@
             LangOpts.MSVCCompat ? NormalizedPath.c_str() : Filename, false,
             LookupFrom, LookupFromFile, CurDir,
             Callbacks ? &SearchPath : nullptr,
-            Callbacks ? &RelativePath : nullptr,
-            &SuggestedModule);
+            Callbacks ? &RelativePath : nullptr, &SuggestedModule, &IsMapped);
         if (File) {
           SourceRange Range(FilenameTok.getLocation(), CharEnd);
           Diag(FilenameTok, diag::err_pp_file_not_found_not_fatal) <<
@@ -1869,13 +1864,17 @@
     if (!SuggestedModule.getModule()->isAvailable()) {
       Module::Requirement Requirement;
       Module::UnresolvedHeaderDirective MissingHeader;
+      Module *ShadowingModule = nullptr;
       Module *M = SuggestedModule.getModule();
       // Identify the cause.
       (void)M->isAvailable(getLangOpts(), getTargetInfo(), Requirement,
-                           MissingHeader);
+                           MissingHeader, ShadowingModule);
       if (MissingHeader.FileNameLoc.isValid()) {
         Diag(MissingHeader.FileNameLoc, diag::err_module_header_missing)
             << MissingHeader.IsUmbrella << MissingHeader.FileName;
+      } else if (ShadowingModule) {
+        Diag(M->DefinitionLoc, diag::err_module_shadowed) << M->Name;
+        Diag(ShadowingModule->DefinitionLoc, diag::note_previous_definition);
       } else {
         Diag(M->DefinitionLoc, diag::err_module_unavailable)
             << M->getFullModuleName() << Requirement.second << Requirement.first;
@@ -1964,7 +1963,7 @@
   // Issue a diagnostic if the name of the file on disk has a different case
   // than the one we're about to open.
   const bool CheckIncludePathPortability =
-    File && !File->tryGetRealPathName().empty();
+      !IsMapped && File && !File->tryGetRealPathName().empty();
 
   if (CheckIncludePathPortability) {
     StringRef Name = LangOpts.MSVCCompat ? NormalizedPath.str() : Filename;
@@ -1999,7 +1998,6 @@
   bool SkipHeader = false;
   if (ShouldEnter &&
       !HeaderInfo.ShouldEnterIncludeFile(*this, File, isImport,
-                                         getLangOpts().Modules,
                                          SuggestedModule.getModule())) {
     ShouldEnter = false;
     SkipHeader = true;
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index 862a471..2e1b5de 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -157,51 +157,6 @@
     PP.LexNonComment(PeekTok);
   }
 
-  // [cpp.cond]p4:
-  //   Prior to evaluation, macro invocations in the list of preprocessing
-  //   tokens that will become the controlling constant expression are replaced
-  //   (except for those macro names modified by the 'defined' unary operator),
-  //   just as in normal text. If the token 'defined' is generated as a result
-  //   of this replacement process or use of the 'defined' unary operator does
-  //   not match one of the two specified forms prior to macro replacement, the
-  //   behavior is undefined.
-  // This isn't an idle threat, consider this program:
-  //   #define FOO
-  //   #define BAR defined(FOO)
-  //   #if BAR
-  //   ...
-  //   #else
-  //   ...
-  //   #endif
-  // clang and gcc will pick the #if branch while Visual Studio will take the
-  // #else branch.  Emit a warning about this undefined behavior.
-  if (beginLoc.isMacroID()) {
-    bool IsFunctionTypeMacro =
-        PP.getSourceManager()
-            .getSLocEntry(PP.getSourceManager().getFileID(beginLoc))
-            .getExpansion()
-            .isFunctionMacroExpansion();
-    // For object-type macros, it's easy to replace
-    //   #define FOO defined(BAR)
-    // with
-    //   #if defined(BAR)
-    //   #define FOO 1
-    //   #else
-    //   #define FOO 0
-    //   #endif
-    // and doing so makes sense since compilers handle this differently in
-    // practice (see example further up).  But for function-type macros,
-    // there is no good way to write
-    //   # define FOO(x) (defined(M_ ## x) && M_ ## x)
-    // in a different way, and compilers seem to agree on how to behave here.
-    // So warn by default on object-type macros, but only warn in -pedantic
-    // mode on function-type macros.
-    if (IsFunctionTypeMacro)
-      PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro);
-    else
-      PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro);
-  }
-
   // Invoke the 'defined' callback.
   if (PPCallbacks *Callbacks = PP.getPPCallbacks()) {
     Callbacks->Defined(macroToken, Macro,
@@ -241,8 +196,8 @@
   if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
     // Handle "defined X" and "defined(X)".
     if (II->isStr("defined"))
-      return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP);
-
+      return(EvaluateDefined(Result, PeekTok, DT, ValueLive, PP));
+    
     // If this identifier isn't 'defined' or one of the special
     // preprocessor keywords and it wasn't macro expanded, it turns
     // into a simple 0, unless it is the C++ keyword "true", in which case it
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index 4db17c3..c573a24 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -287,6 +287,48 @@
   return EndPos;
 }
 
+static void collectAllSubModulesWithUmbrellaHeader(
+    const Module &Mod, SmallVectorImpl<const Module *> &SubMods) {
+  if (Mod.getUmbrellaHeader())
+    SubMods.push_back(&Mod);
+  for (auto *M : Mod.submodules())
+    collectAllSubModulesWithUmbrellaHeader(*M, SubMods);
+}
+
+void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) {
+  assert(Mod.getUmbrellaHeader() && "Module must use umbrella header");
+  SourceLocation StartLoc =
+      SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
+  if (getDiagnostics().isIgnored(diag::warn_uncovered_module_header, StartLoc))
+    return;
+
+  ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap();
+  const DirectoryEntry *Dir = Mod.getUmbrellaDir().Entry;
+  vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
+  std::error_code EC;
+  for (vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), End;
+       Entry != End && !EC; Entry.increment(EC)) {
+    using llvm::StringSwitch;
+
+    // Check whether this entry has an extension typically associated with
+    // headers.
+    if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->getName()))
+             .Cases(".h", ".H", ".hh", ".hpp", true)
+             .Default(false))
+      continue;
+
+    if (const FileEntry *Header = getFileManager().getFile(Entry->getName()))
+      if (!getSourceManager().hasFileInfo(Header)) {
+        if (!ModMap.isHeaderInUnavailableModule(Header)) {
+          // Find the relative path that would access this header.
+          SmallString<128> RelativePath;
+          computeRelativePath(FileMgr, Dir, Header, RelativePath);
+          Diag(StartLoc, diag::warn_uncovered_module_header)
+              << Mod.getFullModuleName() << RelativePath;
+        }
+      }
+  }
+}
 
 /// HandleEndOfFile - This callback is invoked when the lexer hits the end of
 /// the current file.  This either returns the EOF token or pops a level off
@@ -474,44 +516,14 @@
   }
 
   // If we are building a module that has an umbrella header, make sure that
-  // each of the headers within the directory covered by the umbrella header
-  // was actually included by the umbrella header.
+  // each of the headers within the directory, including all submodules, is
+  // covered by the umbrella header was actually included by the umbrella
+  // header.
   if (Module *Mod = getCurrentModule()) {
-    if (Mod->getUmbrellaHeader()) {
-      SourceLocation StartLoc
-        = SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
-
-      if (!getDiagnostics().isIgnored(diag::warn_uncovered_module_header,
-                                      StartLoc)) {
-        ModuleMap &ModMap = getHeaderSearchInfo().getModuleMap();
-        const DirectoryEntry *Dir = Mod->getUmbrellaDir().Entry;
-        vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
-        std::error_code EC;
-        for (vfs::recursive_directory_iterator Entry(FS, Dir->getName(), EC), End;
-             Entry != End && !EC; Entry.increment(EC)) {
-          using llvm::StringSwitch;
-          
-          // Check whether this entry has an extension typically associated with
-          // headers.
-          if (!StringSwitch<bool>(llvm::sys::path::extension(Entry->getName()))
-                 .Cases(".h", ".H", ".hh", ".hpp", true)
-                 .Default(false))
-            continue;
-
-          if (const FileEntry *Header =
-                  getFileManager().getFile(Entry->getName()))
-            if (!getSourceManager().hasFileInfo(Header)) {
-              if (!ModMap.isHeaderInUnavailableModule(Header)) {
-                // Find the relative path that would access this header.
-                SmallString<128> RelativePath;
-                computeRelativePath(FileMgr, Dir, Header, RelativePath);              
-                Diag(StartLoc, diag::warn_uncovered_module_header)
-                  << Mod->getFullModuleName() << RelativePath;
-              }
-            }
-        }
-      }
-    }
+    llvm::SmallVector<const Module *, 4> AllMods;
+    collectAllSubModulesWithUmbrellaHeader(*Mod, AllMods);
+    for (auto *M : AllMods)
+      diagnoseMissingHeaderInUmbrellaDir(*M);
   }
 
   return true;
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index de166c7..e8e48d4 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -1106,6 +1106,7 @@
       .Case("attribute_availability_with_version_underscores", true)
       .Case("attribute_availability_tvos", true)
       .Case("attribute_availability_watchos", true)
+      .Case("attribute_availability_swift", true)
       .Case("attribute_availability_with_strict", true)
       .Case("attribute_availability_with_replacement", true)
       .Case("attribute_availability_in_templates", true)
@@ -1125,11 +1126,13 @@
       .Case("attribute_overloadable", true)
       .Case("attribute_unavailable_with_message", true)
       .Case("attribute_unused_on_fields", true)
+      .Case("attribute_diagnose_if_objc", true)
       .Case("blocks", LangOpts.Blocks)
       .Case("c_thread_safety_attributes", true)
       .Case("cxx_exceptions", LangOpts.CXXExceptions)
       .Case("cxx_rtti", LangOpts.RTTI && LangOpts.RTTIData)
       .Case("enumerator_attributes", true)
+      .Case("generalized_swift_name", true)
       .Case("nullability", true)
       .Case("nullability_on_arrays", true)
       .Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory))
@@ -1422,7 +1425,7 @@
   const DirectoryLookup *CurDir;
   const FileEntry *File =
       PP.LookupFile(FilenameLoc, Filename, isAngled, LookupFrom, LookupFromFile,
-                    CurDir, nullptr, nullptr, nullptr);
+                    CurDir, nullptr, nullptr, nullptr, nullptr);
 
   // Get the result value.  A result of true means the file exists.
   return File != nullptr;
@@ -1746,6 +1749,7 @@
           return llvm::StringSwitch<bool>(II->getName())
                       .Case("__make_integer_seq", LangOpts.CPlusPlus)
                       .Case("__type_pack_element", LangOpts.CPlusPlus)
+                      .Case("__builtin_available", true)
                       .Default(false);
         }
       });
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 100da51..94ad819 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -160,12 +160,23 @@
 
   ~LexingFor_PragmaRAII() {
     if (InMacroArgPreExpansion) {
+      // When committing/backtracking the cached pragma tokens in a macro
+      // argument pre-expansion we want to ensure that either the tokens which
+      // have been committed will be removed from the cache or that the tokens
+      // over which we just backtracked won't remain in the cache after they're
+      // consumed and that the caching will stop after consuming them.
+      // Otherwise the caching will interfere with the way macro expansion
+      // works, because we will continue to cache tokens after consuming the
+      // backtracked tokens, which shouldn't happen when we're dealing with
+      // macro argument pre-expansion.
+      auto CachedTokenRange = PP.LastCachedTokenRange();
       if (Failed) {
         PP.CommitBacktrackedTokens();
       } else {
         PP.Backtrack();
         OutTok = PragmaTok;
       }
+      PP.EraseCachedTokens(CachedTokenRange);
     }
   }
 
@@ -497,7 +508,7 @@
   const DirectoryLookup *CurDir;
   const FileEntry *File =
       LookupFile(FilenameTok.getLocation(), Filename, isAngled, nullptr,
-                 nullptr, CurDir, nullptr, nullptr, nullptr);
+                 nullptr, CurDir, nullptr, nullptr, nullptr, nullptr);
   if (!File) {
     if (!SuppressIncludeNotFoundError)
       Diag(FilenameTok, diag::err_pp_file_not_found) << Filename;
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 91319be..babef5d 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -70,15 +70,15 @@
 
 Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
                            DiagnosticsEngine &diags, LangOptions &opts,
-                           SourceManager &SM, HeaderSearch &Headers,
-                           ModuleLoader &TheModuleLoader,
+                           SourceManager &SM, MemoryBufferCache &PCMCache,
+                           HeaderSearch &Headers, ModuleLoader &TheModuleLoader,
                            IdentifierInfoLookup *IILookup, bool OwnsHeaders,
                            TranslationUnitKind TUKind)
     : PPOpts(std::move(PPOpts)), Diags(&diags), LangOpts(opts), Target(nullptr),
       AuxTarget(nullptr), FileMgr(Headers.getFileMgr()), SourceMgr(SM),
-      ScratchBuf(new ScratchBuffer(SourceMgr)), HeaderInfo(Headers),
-      TheModuleLoader(TheModuleLoader), ExternalSource(nullptr),
-      Identifiers(opts, IILookup),
+      PCMCache(PCMCache), ScratchBuf(new ScratchBuffer(SourceMgr)),
+      HeaderInfo(Headers), TheModuleLoader(TheModuleLoader),
+      ExternalSource(nullptr), Identifiers(opts, IILookup),
       PragmaHandlers(new PragmaNamespace(StringRef())),
       IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr),
       CodeCompletionFile(nullptr), CodeCompletionOffset(0),
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index c52b61e..a456c9b 100644
--- a/lib/Parse/ParseCXXInlineMethods.cpp
+++ b/lib/Parse/ParseCXXInlineMethods.cpp
@@ -47,6 +47,7 @@
                                            VS, ICIS_NoInit);
     if (FnD) {
       Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs);
+      Actions.ProcessAPINotes(FnD);
       if (PureSpecLoc.isValid())
         Actions.ActOnPureSpecifier(FnD, PureSpecLoc);
     }
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 2d32087..b986026 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -244,6 +244,38 @@
   return IL;
 }
 
+void Parser::ParseSwiftNewtypeAttribute(
+    IdentifierInfo &SwiftNewtype, SourceLocation SwiftNewtypeLoc,
+    ParsedAttributes &attrs, SourceLocation *endLoc, IdentifierInfo *ScopeName,
+    SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
+
+  BalancedDelimiterTracker Parens(*this, tok::l_paren);
+  Parens.consumeOpen();
+
+  if (Tok.is(tok::r_paren)) {
+    Diag(Tok.getLocation(), diag::err_argument_required_after_attribute);
+    Parens.consumeClose();
+    return;
+  }
+  if (Tok.isNot(tok::kw_struct) && Tok.isNot(tok::kw_enum)) {
+    Diag(Tok.getLocation(), diag::warn_attribute_type_not_supported)
+        << &SwiftNewtype << Tok.getIdentifierInfo();
+    if (!isTokenSpecial())
+      ConsumeToken();
+    Parens.consumeClose();
+    return;
+  }
+  auto IL = IdentifierLoc::create(Actions.Context, Tok.getLocation(),
+                                  Tok.getIdentifierInfo());
+  ConsumeToken();
+  auto identLoc = ArgsUnion(IL);
+
+  attrs.addNew(&SwiftNewtype,
+               SourceRange(SwiftNewtypeLoc, Parens.getCloseLocation()),
+               ScopeName, ScopeLoc, &identLoc, 1, Syntax);
+  Parens.consumeClose();
+}
+
 void Parser::ParseAttributeWithTypeArg(IdentifierInfo &AttrName,
                                        SourceLocation AttrNameLoc,
                                        ParsedAttributes &Attrs,
@@ -356,6 +388,10 @@
     ParseAvailabilityAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
                                ScopeLoc, Syntax);
     return;
+  } else if (AttrKind == AttributeList::AT_ExternalSourceSymbol) {
+    ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+                                       ScopeName, ScopeLoc, Syntax);
+    return;
   } else if (AttrKind == AttributeList::AT_ObjCBridgeRelated) {
     ParseObjCBridgeRelatedAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
                                     ScopeName, ScopeLoc, Syntax);
@@ -364,6 +400,10 @@
     ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
                                      ScopeName, ScopeLoc, Syntax);
     return;
+  } else if (AttrKind == AttributeList::AT_SwiftNewtype) {
+    ParseSwiftNewtypeAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+                               ScopeName, ScopeLoc, Syntax);
+    return;
   } else if (attributeIsTypeArgAttr(*AttrName)) {
     ParseAttributeWithTypeArg(*AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
                               ScopeLoc, Syntax);
@@ -389,6 +429,25 @@
                            ScopeLoc, Syntax);
 }
 
+unsigned Parser::ParseClangAttributeArgs(
+    IdentifierInfo *AttrName, SourceLocation AttrNameLoc,
+    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
+    SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
+  assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with '('");
+
+  AttributeList::Kind AttrKind =
+      AttributeList::getKind(AttrName, ScopeName, Syntax);
+
+  if (AttrKind == AttributeList::AT_ExternalSourceSymbol) {
+    ParseExternalSourceSymbolAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc,
+                                       ScopeName, ScopeLoc, Syntax);
+    return Attrs.getList() ? Attrs.getList()->getNumArgs() : 0;
+  }
+
+  return ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
+                                  ScopeName, ScopeLoc, Syntax);
+}
+
 bool Parser::ParseMicrosoftDeclSpecArgs(IdentifierInfo *AttrName,
                                         SourceLocation AttrNameLoc,
                                         ParsedAttributes &Attrs) {
@@ -855,7 +914,7 @@
 ///
 /// version-arg:
 ///   'introduced' '=' version
-///   'deprecated' '=' version
+///   'deprecated' ['=' version]
 ///   'obsoleted' = version
 ///   'unavailable'
 /// opt-replacement:
@@ -943,6 +1002,21 @@
       continue;
     }
 
+    if (Keyword == Ident_deprecated && Platform->Ident &&
+        Platform->Ident->getName() == "swift") {
+      // For swift, we deprecate for all versions.
+      if (!Changes[Deprecated].KeywordLoc.isInvalid()) {
+        Diag(KeywordLoc, diag::err_availability_redundant)
+          << Keyword
+          << SourceRange(Changes[Deprecated].KeywordLoc);
+      }
+
+      Changes[Deprecated].KeywordLoc = KeywordLoc;
+      // Use a fake version here.
+      Changes[Deprecated].Version = VersionTuple(1);
+      continue;
+    }
+
     if (Tok.isNot(tok::equal)) {
       Diag(Tok, diag::err_expected_after) << Keyword << tok::equal;
       SkipUntil(tok::r_paren, StopAtSemi);
@@ -1064,6 +1138,119 @@
                Syntax, StrictLoc, ReplacementExpr.get());
 }
 
+/// \brief Parse the contents of the "external_source_symbol" attribute.
+///
+/// external-source-symbol-attribute:
+///   'external_source_symbol' '(' keyword-arg-list ')'
+///
+/// keyword-arg-list:
+///   keyword-arg
+///   keyword-arg ',' keyword-arg-list
+///
+/// keyword-arg:
+///   'language' '=' <string>
+///   'defined_in' '=' <string>
+///   'generated_declaration'
+void Parser::ParseExternalSourceSymbolAttribute(
+    IdentifierInfo &ExternalSourceSymbol, SourceLocation Loc,
+    ParsedAttributes &Attrs, SourceLocation *EndLoc, IdentifierInfo *ScopeName,
+    SourceLocation ScopeLoc, AttributeList::Syntax Syntax) {
+  // Opening '('.
+  BalancedDelimiterTracker T(*this, tok::l_paren);
+  if (T.expectAndConsume())
+    return;
+
+  // Initialize the pointers for the keyword identifiers when required.
+  if (!Ident_language) {
+    Ident_language = PP.getIdentifierInfo("language");
+    Ident_defined_in = PP.getIdentifierInfo("defined_in");
+    Ident_generated_declaration = PP.getIdentifierInfo("generated_declaration");
+  }
+
+  ExprResult Language;
+  bool HasLanguage = false;
+  ExprResult DefinedInExpr;
+  bool HasDefinedIn = false;
+  IdentifierLoc *GeneratedDeclaration = nullptr;
+
+  // Parse the language/defined_in/generated_declaration keywords
+  do {
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_external_source_symbol_expected_keyword);
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return;
+    }
+
+    SourceLocation KeywordLoc = Tok.getLocation();
+    IdentifierInfo *Keyword = Tok.getIdentifierInfo();
+    if (Keyword == Ident_generated_declaration) {
+      if (GeneratedDeclaration) {
+        Diag(Tok, diag::err_external_source_symbol_duplicate_clause) << Keyword;
+        SkipUntil(tok::r_paren, StopAtSemi);
+        return;
+      }
+      GeneratedDeclaration = ParseIdentifierLoc();
+      continue;
+    }
+
+    if (Keyword != Ident_language && Keyword != Ident_defined_in) {
+      Diag(Tok, diag::err_external_source_symbol_expected_keyword);
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return;
+    }
+
+    ConsumeToken();
+    if (ExpectAndConsume(tok::equal, diag::err_expected_after,
+                         Keyword->getName())) {
+      SkipUntil(tok::r_paren, StopAtSemi);
+      return;
+    }
+
+    bool HadLanguage = HasLanguage, HadDefinedIn = HasDefinedIn;
+    if (Keyword == Ident_language)
+      HasLanguage = true;
+    else
+      HasDefinedIn = true;
+
+    if (Tok.isNot(tok::string_literal)) {
+      Diag(Tok, diag::err_expected_string_literal)
+          << /*Source='external_source_symbol attribute'*/ 3
+          << /*language | source container*/ (Keyword != Ident_language);
+      SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch);
+      continue;
+    }
+    if (Keyword == Ident_language) {
+      if (HadLanguage) {
+        Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
+            << Keyword;
+        ParseStringLiteralExpression();
+        continue;
+      }
+      Language = ParseStringLiteralExpression();
+    } else {
+      assert(Keyword == Ident_defined_in && "Invalid clause keyword!");
+      if (HadDefinedIn) {
+        Diag(KeywordLoc, diag::err_external_source_symbol_duplicate_clause)
+            << Keyword;
+        ParseStringLiteralExpression();
+        continue;
+      }
+      DefinedInExpr = ParseStringLiteralExpression();
+    }
+  } while (TryConsumeToken(tok::comma));
+
+  // Closing ')'.
+  if (T.consumeClose())
+    return;
+  if (EndLoc)
+    *EndLoc = T.getCloseLocation();
+
+  ArgsUnion Args[] = {Language.get(), DefinedInExpr.get(),
+                      GeneratedDeclaration};
+  Attrs.addNew(&ExternalSourceSymbol, SourceRange(Loc, T.getCloseLocation()),
+               ScopeName, ScopeLoc, Args, llvm::array_lengthof(Args), Syntax);
+}
+
 /// \brief Parse the contents of the "objc_bridge_related" attribute.
 /// objc_bridge_related '(' related_class ',' opt-class_method ',' opt-instance_method ')'
 /// related_class:
@@ -4806,9 +4993,10 @@
 ///              [ only if AttReqs & AR_CXX11AttributesParsed ]
 /// Note: vendor can be GNU, MS, etc and can be explicitly controlled via
 /// AttrRequirements bitmask values.
-void Parser::ParseTypeQualifierListOpt(DeclSpec &DS, unsigned AttrReqs,
-                                       bool AtomicAllowed,
-                                       bool IdentifierRequired) {
+void Parser::ParseTypeQualifierListOpt(
+    DeclSpec &DS, unsigned AttrReqs, bool AtomicAllowed,
+    bool IdentifierRequired,
+    Optional<llvm::function_ref<void()>> CodeCompletionHandler) {
   if (getLangOpts().CPlusPlus11 && (AttrReqs & AR_CXX11AttributesParsed) &&
       isCXX11AttributeSpecifier()) {
     ParsedAttributesWithRange attrs(AttrFactory);
@@ -4826,7 +5014,10 @@
 
     switch (Tok.getKind()) {
     case tok::code_completion:
-      Actions.CodeCompleteTypeQualifiers(DS);
+      if (CodeCompletionHandler)
+        (*CodeCompletionHandler)();
+      else
+        Actions.CodeCompleteTypeQualifiers(DS);
       return cutOffParsing();
 
     case tok::kw_const:
@@ -5409,6 +5600,21 @@
     if (Tok.is(tok::l_square))
       return ParseMisplacedBracketDeclarator(D);
     if (D.getContext() == Declarator::MemberContext) {
+      // Objective-C++: Detect C++ keywords and try to prevent further errors by
+      // treating these keyword as valid member names.
+      if (getLangOpts().ObjC1 && getLangOpts().CPlusPlus &&
+          Tok.getIdentifierInfo() &&
+          Tok.getIdentifierInfo()->isCPlusPlusKeyword(getLangOpts())) {
+        Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
+             diag::err_expected_member_name_or_semi_objcxx_keyword)
+            << Tok.getIdentifierInfo()
+            << (D.getDeclSpec().isEmpty() ? SourceRange()
+                                          : D.getDeclSpec().getSourceRange());
+        D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
+        D.SetRangeEnd(Tok.getLocation());
+        ConsumeToken();
+        goto PastIdentifier;
+      }
       Diag(getMissingDeclaratorIdLoc(D, Tok.getLocation()),
            diag::err_expected_member_name_or_semi)
           << (D.getDeclSpec().isEmpty() ? SourceRange()
@@ -5744,7 +5950,11 @@
 
       // Parse cv-qualifier-seq[opt].
       ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed,
-                                /*AtomicAllowed*/ false);
+                                /*AtomicAllowed*/ false,
+                                /*IdentifierRequired=*/false,
+                                llvm::function_ref<void()>([&]() {
+                                  Actions.CodeCompleteFunctionQualifiers(DS, D);
+                                }));
       if (!DS.getSourceRange().getEnd().isInvalid()) {
         EndLoc = DS.getSourceRange().getEnd();
         ConstQualifierLoc = DS.getConstSpecLoc();
@@ -6553,3 +6763,68 @@
   }
   return false;
 }
+
+TypeResult Parser::parseTypeFromString(StringRef typeStr, StringRef context,
+                                       SourceLocation includeLoc) {
+  // Consume (unexpanded) tokens up to the end-of-directive.
+  SmallVector<Token, 4> tokens;
+  {
+    // Create a new buffer from which we will parse the type.
+    auto &sourceMgr = PP.getSourceManager();
+    FileID fileID = sourceMgr.createFileID(
+                      llvm::MemoryBuffer::getMemBufferCopy(typeStr, context),
+                      SrcMgr::C_User, 0, 0, includeLoc);
+
+    // Form a new lexer that references the buffer.
+    Lexer lexer(fileID, sourceMgr.getBuffer(fileID), PP);
+    lexer.setParsingPreprocessorDirective(true);
+    lexer.setIsPragmaLexer(true);
+
+    // Lex the tokens from that buffer.
+    Token tok;
+    do {
+      lexer.Lex(tok);
+      tokens.push_back(tok);
+    } while (tok.isNot(tok::eod));
+  }
+
+  // Replace the "eod" token with an "eof" token identifying the end of
+  // the provided string.
+  Token &endToken = tokens.back();
+  endToken.startToken();
+  endToken.setKind(tok::eof);
+  endToken.setLocation(Tok.getLocation());
+  endToken.setEofData(typeStr.data());
+
+  // Add the current token back.
+  tokens.push_back(Tok);
+
+  // Enter the tokens into the token stream.
+  PP.EnterTokenStream(tokens, /*DisableMacroExpansion=*/false);
+
+  // Consume the current token so that we'll start parsing the tokens we
+  // added to the stream.
+  ConsumeAnyToken();
+
+  // Enter a new scope.
+  ParseScope localScope(this, 0);
+
+  // Parse the type.
+  TypeResult result = ParseTypeName(nullptr);
+
+  // Check if we parsed the whole thing.
+  if (result.isUsable() &&
+      (Tok.isNot(tok::eof) || Tok.getEofData() != typeStr.data())) {
+    Diag(Tok.getLocation(), diag::err_type_unparsed);
+  }
+
+  // There could be leftover tokens (e.g. because of an error).
+  // Skip through until we reach the 'end of directive' token.
+  while (Tok.isNot(tok::eof))
+    ConsumeAnyToken();
+
+  // Consume the end token.
+  if (Tok.is(tok::eof) && Tok.getEofData() == typeStr.data())
+    ConsumeAnyToken();
+  return result;
+}
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index 3f1fe7e..1758578 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -2283,7 +2283,11 @@
 
   // GNU-style and C++11 attributes are not allowed here, but they will be
   // handled by the caller.  Diagnose everything else.
-  ParseTypeQualifierListOpt(DS, AR_NoAttributesParsed, false);
+  ParseTypeQualifierListOpt(
+      DS, AR_NoAttributesParsed, false,
+      /*IdentifierRequired=*/false, llvm::function_ref<void()>([&]() {
+        Actions.CodeCompleteFunctionQualifiers(DS, D, &VS);
+      }));
   D.ExtendWithDeclSpec(DS);
 
   if (D.isFunctionDeclarator()) {
@@ -2724,8 +2728,10 @@
         // initialize it.
         ThisDecl = VT->getTemplatedDecl();
 
-      if (ThisDecl && AccessAttrs)
+      if (ThisDecl) {
         Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);
+        Actions.ProcessAPINotes(ThisDecl);
+      }
     }
 
     // Error recovery might have converted a non-static member into a static
@@ -3817,36 +3823,44 @@
     return false;
   }
 
-  if (ScopeName && ScopeName->getName() == "gnu")
+  if (ScopeName && ScopeName->getName() == "gnu") {
     // GNU-scoped attributes have some special cases to handle GNU-specific
     // behaviors.
     ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
                           ScopeLoc, AttributeList::AS_CXX11, nullptr);
-  else {
-    unsigned NumArgs =
+    return true;
+  }
+
+  unsigned NumArgs;
+  // Some Clang-scoped attributes have some special parsing behavior.
+  if (ScopeName && ScopeName->getName() == "clang")
+    NumArgs =
+        ParseClangAttributeArgs(AttrName, AttrNameLoc, Attrs, EndLoc, ScopeName,
+                                ScopeLoc, AttributeList::AS_CXX11);
+  else
+    NumArgs =
         ParseAttributeArgsCommon(AttrName, AttrNameLoc, Attrs, EndLoc,
                                  ScopeName, ScopeLoc, AttributeList::AS_CXX11);
-    
-    const AttributeList *Attr = Attrs.getList();
-    if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
-      // If the attribute is a standard or built-in attribute and we are
-      // parsing an argument list, we need to determine whether this attribute
-      // was allowed to have an argument list (such as [[deprecated]]), and how
-      // many arguments were parsed (so we can diagnose on [[deprecated()]]).
-      if (Attr->getMaxArgs() && !NumArgs) {
-        // The attribute was allowed to have arguments, but none were provided
-        // even though the attribute parsed successfully. This is an error.
-        Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
-        Attr->setInvalid(true);
-      } else if (!Attr->getMaxArgs()) {
-        // The attribute parsed successfully, but was not allowed to have any
-        // arguments. It doesn't matter whether any were provided -- the
-        // presence of the argument list (even if empty) is diagnosed.
-        Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
-            << AttrName
-            << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
-        Attr->setInvalid(true);
-      }
+
+  const AttributeList *Attr = Attrs.getList();
+  if (Attr && IsBuiltInOrStandardCXX11Attribute(AttrName, ScopeName)) {
+    // If the attribute is a standard or built-in attribute and we are
+    // parsing an argument list, we need to determine whether this attribute
+    // was allowed to have an argument list (such as [[deprecated]]), and how
+    // many arguments were parsed (so we can diagnose on [[deprecated()]]).
+    if (Attr->getMaxArgs() && !NumArgs) {
+      // The attribute was allowed to have arguments, but none were provided
+      // even though the attribute parsed successfully. This is an error.
+      Diag(LParenLoc, diag::err_attribute_requires_arguments) << AttrName;
+      Attr->setInvalid(true);
+    } else if (!Attr->getMaxArgs()) {
+      // The attribute parsed successfully, but was not allowed to have any
+      // arguments. It doesn't matter whether any were provided -- the
+      // presence of the argument list (even if empty) is diagnosed.
+      Diag(LParenLoc, diag::err_cxx11_attribute_forbids_arguments)
+          << AttrName
+          << FixItHint::CreateRemoval(SourceRange(LParenLoc, *EndLoc));
+      Attr->setInvalid(true);
     }
   }
   return true;
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 852e226..5e02d90 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2933,6 +2933,11 @@
     return AvailabilitySpec(ConsumeToken());
   } else {
     // Parse the platform name.
+    if (Tok.is(tok::code_completion)) {
+      Actions.CodeCompleteAvailabilityPlatformName();
+      cutOffParsing();
+      return None;
+    }
     if (Tok.isNot(tok::identifier)) {
       Diag(Tok, diag::err_avail_query_expected_platform_name);
       return None;
@@ -2945,12 +2950,14 @@
     if (Version.empty())
       return None;
 
-    StringRef Platform = PlatformIdentifier->Ident->getName();
+    StringRef GivenPlatform = PlatformIdentifier->Ident->getName();
+    StringRef Platform =
+        AvailabilityAttr::canonicalizePlatformName(GivenPlatform);
 
     if (AvailabilityAttr::getPrettyPlatformName(Platform).empty()) {
       Diag(PlatformIdentifier->Loc,
            diag::err_avail_query_unrecognized_platform_name)
-          << Platform;
+          << GivenPlatform;
       return None;
     }
 
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 81761bf..99cc00f7 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -137,8 +137,7 @@
 
   while (1) {
     MaybeSkipAttributes(tok::objc_class);
-    if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected) << tok::identifier;
+    if (expectIdentifier()) {
       SkipUntil(tok::semi);
       return Actions.ConvertDeclToDeclGroup(nullptr);
     }
@@ -212,6 +211,8 @@
 ///     __attribute__((unavailable))
 ///     __attribute__((objc_exception)) - used by NSException on 64-bit
 ///     __attribute__((objc_root_class))
+///     __attribute__((objc_subclassing_restricted))
+///     __attribute__((objc_complete_definition))
 ///
 Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc,
                                               ParsedAttributes &attrs) {
@@ -229,11 +230,8 @@
 
   MaybeSkipAttributes(tok::objc_interface);
 
-  if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected)
-        << tok::identifier; // missing class or category name.
-    return nullptr;
-  }
+  if (expectIdentifier())
+    return nullptr; // missing class or category name.
 
   // We have a class or category name - consume it.
   IdentifierInfo *nameId = Tok.getIdentifierInfo();
@@ -278,11 +276,6 @@
     T.consumeClose();
     if (T.getCloseLocation().isInvalid())
       return nullptr;
-
-    if (!attrs.empty()) { // categories don't support attributes.
-      Diag(nameLoc, diag::err_objc_no_attributes_on_category);
-      attrs.clear();
-    }
     
     // Next, we need to check for any protocol references.
     assert(LAngleLoc.isInvalid() && "Cannot have already parsed protocols");
@@ -294,16 +287,11 @@
                                     /*consumeLastToken=*/true))
       return nullptr;
 
-    Decl *CategoryType =
-    Actions.ActOnStartCategoryInterface(AtLoc,
-                                        nameId, nameLoc,
-                                        typeParameterList,
-                                        categoryId, categoryLoc,
-                                        ProtocolRefs.data(),
-                                        ProtocolRefs.size(),
-                                        ProtocolLocs.data(),
-                                        EndProtoLoc);
-    
+    Decl *CategoryType = Actions.ActOnStartCategoryInterface(
+        AtLoc, nameId, nameLoc, typeParameterList, categoryId, categoryLoc,
+        ProtocolRefs.data(), ProtocolRefs.size(), ProtocolLocs.data(),
+        EndProtoLoc, attrs.getList());
+
     if (Tok.is(tok::l_brace))
       ParseObjCClassInstanceVariables(CategoryType, tok::objc_private, AtLoc);
       
@@ -329,11 +317,8 @@
       return nullptr;
     }
 
-    if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected)
-          << tok::identifier; // missing super class name.
-      return nullptr;
-    }
+    if (expectIdentifier())
+      return nullptr; // missing super class name.
     superClassId = Tok.getIdentifierInfo();
     superClassLoc = ConsumeToken();
 
@@ -929,7 +914,7 @@
 
       if (IsSetter) {
         DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter);
-        DS.setSetterName(SelIdent);
+        DS.setSetterName(SelIdent, SelLoc);
 
         if (ExpectAndConsume(tok::colon,
                              diag::err_expected_colon_after_setter_name)) {
@@ -938,7 +923,7 @@
         }
       } else {
         DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter);
-        DS.setGetterName(SelIdent);
+        DS.setGetterName(SelIdent, SelLoc);
       }
     } else if (II->isStr("nonnull")) {
       if (DS.getPropertyAttributes() & ObjCDeclSpec::DQ_PR_nullability)
@@ -1448,12 +1433,9 @@
       cutOffParsing();
       return nullptr;
     }
-    
-    if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected)
-          << tok::identifier; // missing argument name.
-      break;
-    }
+
+    if (expectIdentifier())
+      break; // missing argument name.
 
     ArgInfo.Name = Tok.getIdentifierInfo();
     ArgInfo.NameLoc = Tok.getLocation();
@@ -1562,8 +1544,7 @@
       return true;
     }
 
-    if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected) << tok::identifier;
+    if (expectIdentifier()) {
       SkipUntil(tok::greater, StopAtSemi);
       return true;
     }
@@ -2045,10 +2026,8 @@
 
   MaybeSkipAttributes(tok::objc_protocol);
 
-  if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected) << tok::identifier; // missing protocol name.
-    return nullptr;
-  }
+  if (expectIdentifier())
+    return nullptr; // missing protocol name.
   // Save the protocol name, then consume it.
   IdentifierInfo *protocolName = Tok.getIdentifierInfo();
   SourceLocation nameLoc = ConsumeToken();
@@ -2068,8 +2047,7 @@
     // Parse the list of forward declarations.
     while (1) {
       ConsumeToken(); // the ','
-      if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected) << tok::identifier;
+      if (expectIdentifier()) {
         SkipUntil(tok::semi);
         return nullptr;
       }
@@ -2136,11 +2114,8 @@
 
   MaybeSkipAttributes(tok::objc_implementation);
 
-  if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected)
-        << tok::identifier; // missing class or category name.
-    return nullptr;
-  }
+  if (expectIdentifier())
+    return nullptr; // missing class or category name.
   // We have a class or category name - consume it.
   IdentifierInfo *nameId = Tok.getIdentifierInfo();
   SourceLocation nameLoc = ConsumeToken(); // consume class or category name
@@ -2210,11 +2185,8 @@
     IdentifierInfo *superClassId = nullptr;
     if (TryConsumeToken(tok::colon)) {
       // We have a super class
-      if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected)
-            << tok::identifier; // missing super class name.
-        return nullptr;
-      }
+      if (expectIdentifier())
+        return nullptr; // missing super class name.
       superClassId = Tok.getIdentifierInfo();
       superClassLoc = ConsumeToken(); // Consume super class name
     }
@@ -2314,16 +2286,12 @@
   assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) &&
          "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias");
   ConsumeToken(); // consume compatibility_alias
-  if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected) << tok::identifier;
+  if (expectIdentifier())
     return nullptr;
-  }
   IdentifierInfo *aliasId = Tok.getIdentifierInfo();
   SourceLocation aliasLoc = ConsumeToken(); // consume alias-name
-  if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected) << tok::identifier;
+  if (expectIdentifier())
     return nullptr;
-  }
   IdentifierInfo *classId = Tok.getIdentifierInfo();
   SourceLocation classLoc = ConsumeToken(); // consume class-name;
   ExpectAndConsume(tok::semi, diag::err_expected_after, "@compatibility_alias");
@@ -2371,11 +2339,9 @@
         cutOffParsing();
         return nullptr;
       }
-      
-      if (Tok.isNot(tok::identifier)) {
-        Diag(Tok, diag::err_expected) << tok::identifier;
+
+      if (expectIdentifier())
         break;
-      }
       propertyIvar = Tok.getIdentifierInfo();
       propertyIvarLoc = ConsumeToken(); // consume ivar-name
     }
@@ -2433,9 +2399,8 @@
       cutOffParsing();
       return nullptr;
     }
-    
-    if (Tok.isNot(tok::identifier)) {
-      Diag(Tok, diag::err_expected) << tok::identifier;
+
+    if (expectIdentifier()) {
       SkipUntil(tok::semi);
       return nullptr;
     }
@@ -3571,8 +3536,8 @@
   BalancedDelimiterTracker T(*this, tok::l_paren);
   T.consumeOpen();
 
-  if (Tok.isNot(tok::identifier))
-    return ExprError(Diag(Tok, diag::err_expected) << tok::identifier);
+  if (expectIdentifier())
+    return ExprError();
 
   IdentifierInfo *protocolId = Tok.getIdentifierInfo();
   SourceLocation ProtoIdLoc = ConsumeToken();
diff --git a/lib/Parse/ParsePragma.cpp b/lib/Parse/ParsePragma.cpp
index 8973323..c011612 100644
--- a/lib/Parse/ParsePragma.cpp
+++ b/lib/Parse/ParsePragma.cpp
@@ -86,6 +86,12 @@
                     Token &FirstToken) override;
 };
 
+struct PragmaFPHandler : public PragmaHandler {
+  PragmaFPHandler() : PragmaHandler("fp") {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+};
+
 struct PragmaNoOpenMPHandler : public PragmaHandler {
   PragmaNoOpenMPHandler() : PragmaHandler("omp") { }
   void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
@@ -177,6 +183,17 @@
   Sema &Actions;
 };
 
+/// PragmaAttributeHandler - "\#pragma clang attribute ...".
+struct PragmaAttributeHandler : public PragmaHandler {
+  PragmaAttributeHandler(AttributeFactory &AttrFactory)
+      : PragmaHandler("attribute"), AttributesForPragmaAttribute(AttrFactory) {}
+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+                    Token &FirstToken) override;
+
+  /// A pool of attributes that were parsed in \#pragma clang attribute.
+  ParsedAttributes AttributesForPragmaAttribute;
+};
+
 }  // end namespace
 
 void Parser::initializePragmaHandlers() {
@@ -266,6 +283,12 @@
 
   NoUnrollHintHandler.reset(new PragmaUnrollHintHandler("nounroll"));
   PP.AddPragmaHandler(NoUnrollHintHandler.get());
+
+  FPHandler.reset(new PragmaFPHandler());
+  PP.AddPragmaHandler("clang", FPHandler.get());
+
+  AttributePragmaHandler.reset(new PragmaAttributeHandler(AttrFactory));
+  PP.AddPragmaHandler("clang", AttributePragmaHandler.get());
 }
 
 void Parser::resetPragmaHandlers() {
@@ -344,6 +367,12 @@
 
   PP.RemovePragmaHandler(NoUnrollHintHandler.get());
   NoUnrollHintHandler.reset();
+
+  PP.RemovePragmaHandler("clang", FPHandler.get());
+  FPHandler.reset();
+
+  PP.RemovePragmaHandler("clang", AttributePragmaHandler.get());
+  AttributePragmaHandler.reset();
 }
 
 /// \brief Handle the annotation token produced for #pragma unused(...)
@@ -454,7 +483,21 @@
   tok::OnOffSwitch OOS =
     static_cast<tok::OnOffSwitch>(
     reinterpret_cast<uintptr_t>(Tok.getAnnotationValue()));
-  Actions.ActOnPragmaFPContract(OOS);
+
+  LangOptions::FPContractModeKind FPC;
+  switch (OOS) {
+  case tok::OOS_ON:
+    FPC = LangOptions::FPC_On;
+    break;
+  case tok::OOS_OFF:
+    FPC = LangOptions::FPC_Off;
+    break;
+  case tok::OOS_DEFAULT:
+    FPC = getLangOpts().getDefaultFPContractMode();
+    break;
+  }
+
+  Actions.ActOnPragmaFPContract(FPC);
   ConsumeToken(); // The annotation token.
 }
 
@@ -940,6 +983,422 @@
   return true;
 }
 
+namespace {
+struct PragmaAttributeInfo {
+  enum ActionType { Push, Pop };
+  ParsedAttributes &Attributes;
+  ActionType Action;
+  ArrayRef<Token> Tokens;
+
+  PragmaAttributeInfo(ParsedAttributes &Attributes) : Attributes(Attributes) {}
+};
+
+#include "clang/Parse/AttrSubMatchRulesParserStringSwitches.inc"
+
+} // end anonymous namespace
+
+static StringRef getIdentifier(const Token &Tok) {
+  if (Tok.is(tok::identifier))
+    return Tok.getIdentifierInfo()->getName();
+  const char *S = tok::getKeywordSpelling(Tok.getKind());
+  if (!S)
+    return "";
+  return S;
+}
+
+static bool isAbstractAttrMatcherRule(attr::SubjectMatchRule Rule) {
+  using namespace attr;
+  switch (Rule) {
+#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)                           \
+  case Value:                                                                  \
+    return IsAbstract;
+#include "clang/Basic/AttrSubMatchRulesList.inc"
+  }
+  llvm_unreachable("Invalid attribute subject match rule");
+  return false;
+}
+
+static void diagnoseExpectedAttributeSubjectSubRule(
+    Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
+    SourceLocation SubRuleLoc) {
+  auto Diagnostic =
+      PRef.Diag(SubRuleLoc,
+                diag::err_pragma_attribute_expected_subject_sub_identifier)
+      << PrimaryRuleName;
+  if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
+    Diagnostic << /*SubRulesSupported=*/1 << SubRules;
+  else
+    Diagnostic << /*SubRulesSupported=*/0;
+}
+
+static void diagnoseUnknownAttributeSubjectSubRule(
+    Parser &PRef, attr::SubjectMatchRule PrimaryRule, StringRef PrimaryRuleName,
+    StringRef SubRuleName, SourceLocation SubRuleLoc) {
+
+  auto Diagnostic =
+      PRef.Diag(SubRuleLoc, diag::err_pragma_attribute_unknown_subject_sub_rule)
+      << SubRuleName << PrimaryRuleName;
+  if (const char *SubRules = validAttributeSubjectMatchSubRules(PrimaryRule))
+    Diagnostic << /*SubRulesSupported=*/1 << SubRules;
+  else
+    Diagnostic << /*SubRulesSupported=*/0;
+}
+
+bool Parser::ParsePragmaAttributeSubjectMatchRuleSet(
+    attr::ParsedSubjectMatchRuleSet &SubjectMatchRules, SourceLocation &AnyLoc,
+    SourceLocation &LastMatchRuleEndLoc) {
+  bool IsAny = false;
+  BalancedDelimiterTracker AnyParens(*this, tok::l_paren);
+  if (getIdentifier(Tok) == "any") {
+    AnyLoc = ConsumeToken();
+    IsAny = true;
+    if (AnyParens.expectAndConsume())
+      return true;
+  }
+
+  do {
+    // Parse the subject matcher rule.
+    StringRef Name = getIdentifier(Tok);
+    if (Name.empty()) {
+      Diag(Tok, diag::err_pragma_attribute_expected_subject_identifier);
+      return true;
+    }
+    std::pair<Optional<attr::SubjectMatchRule>,
+              Optional<attr::SubjectMatchRule> (*)(StringRef, bool)>
+        Rule = isAttributeSubjectMatchRule(Name);
+    if (!Rule.first) {
+      Diag(Tok, diag::err_pragma_attribute_unknown_subject_rule) << Name;
+      return true;
+    }
+    attr::SubjectMatchRule PrimaryRule = *Rule.first;
+    SourceLocation RuleLoc = ConsumeToken();
+
+    BalancedDelimiterTracker Parens(*this, tok::l_paren);
+    if (isAbstractAttrMatcherRule(PrimaryRule)) {
+      if (Parens.expectAndConsume())
+        return true;
+    } else if (Parens.consumeOpen()) {
+      if (!SubjectMatchRules
+               .insert(
+                   std::make_pair(PrimaryRule, SourceRange(RuleLoc, RuleLoc)))
+               .second)
+        Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
+            << Name
+            << FixItHint::CreateRemoval(SourceRange(
+                   RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleLoc));
+      LastMatchRuleEndLoc = RuleLoc;
+      continue;
+    }
+
+    // Parse the sub-rules.
+    StringRef SubRuleName = getIdentifier(Tok);
+    if (SubRuleName.empty()) {
+      diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
+                                              Tok.getLocation());
+      return true;
+    }
+    attr::SubjectMatchRule SubRule;
+    if (SubRuleName == "unless") {
+      SourceLocation SubRuleLoc = ConsumeToken();
+      BalancedDelimiterTracker Parens(*this, tok::l_paren);
+      if (Parens.expectAndConsume())
+        return true;
+      SubRuleName = getIdentifier(Tok);
+      if (SubRuleName.empty()) {
+        diagnoseExpectedAttributeSubjectSubRule(*this, PrimaryRule, Name,
+                                                SubRuleLoc);
+        return true;
+      }
+      auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/true);
+      if (!SubRuleOrNone) {
+        std::string SubRuleUnlessName = "unless(" + SubRuleName.str() + ")";
+        diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
+                                               SubRuleUnlessName, SubRuleLoc);
+        return true;
+      }
+      SubRule = *SubRuleOrNone;
+      ConsumeToken();
+      if (Parens.consumeClose())
+        return true;
+    } else {
+      auto SubRuleOrNone = Rule.second(SubRuleName, /*IsUnless=*/false);
+      if (!SubRuleOrNone) {
+        diagnoseUnknownAttributeSubjectSubRule(*this, PrimaryRule, Name,
+                                               SubRuleName, Tok.getLocation());
+        return true;
+      }
+      SubRule = *SubRuleOrNone;
+      ConsumeToken();
+    }
+    SourceLocation RuleEndLoc = Tok.getLocation();
+    LastMatchRuleEndLoc = RuleEndLoc;
+    if (Parens.consumeClose())
+      return true;
+    if (!SubjectMatchRules
+             .insert(std::make_pair(SubRule, SourceRange(RuleLoc, RuleEndLoc)))
+             .second) {
+      Diag(RuleLoc, diag::err_pragma_attribute_duplicate_subject)
+          << attr::getSubjectMatchRuleSpelling(SubRule)
+          << FixItHint::CreateRemoval(SourceRange(
+                 RuleLoc, Tok.is(tok::comma) ? Tok.getLocation() : RuleEndLoc));
+      continue;
+    }
+  } while (IsAny && TryConsumeToken(tok::comma));
+
+  if (IsAny)
+    if (AnyParens.consumeClose())
+      return true;
+
+  return false;
+}
+
+namespace {
+
+/// Describes the stage at which attribute subject rule parsing was interruped.
+enum class MissingAttributeSubjectRulesRecoveryPoint {
+  Comma,
+  ApplyTo,
+  Equals,
+  Any,
+  None,
+};
+
+MissingAttributeSubjectRulesRecoveryPoint
+getAttributeSubjectRulesRecoveryPointForToken(const Token &Tok) {
+  if (const auto *II = Tok.getIdentifierInfo()) {
+    if (II->isStr("apply_to"))
+      return MissingAttributeSubjectRulesRecoveryPoint::ApplyTo;
+    if (II->isStr("any"))
+      return MissingAttributeSubjectRulesRecoveryPoint::Any;
+  }
+  if (Tok.is(tok::equal))
+    return MissingAttributeSubjectRulesRecoveryPoint::Equals;
+  return MissingAttributeSubjectRulesRecoveryPoint::None;
+}
+
+/// Creates a diagnostic for the attribute subject rule parsing diagnostic that
+/// suggests the possible attribute subject rules in a fix-it together with
+/// any other missing tokens.
+DiagnosticBuilder createExpectedAttributeSubjectRulesTokenDiagnostic(
+    unsigned DiagID, AttributeList &Attribute,
+    MissingAttributeSubjectRulesRecoveryPoint Point, Parser &PRef) {
+  SourceLocation Loc = PRef.getEndOfPreviousToken();
+  if (Loc.isInvalid())
+    Loc = PRef.getCurToken().getLocation();
+  auto Diagnostic = PRef.Diag(Loc, DiagID);
+  std::string FixIt;
+  MissingAttributeSubjectRulesRecoveryPoint EndPoint =
+      getAttributeSubjectRulesRecoveryPointForToken(PRef.getCurToken());
+  if (Point == MissingAttributeSubjectRulesRecoveryPoint::Comma)
+    FixIt = ", ";
+  if (Point <= MissingAttributeSubjectRulesRecoveryPoint::ApplyTo &&
+      EndPoint > MissingAttributeSubjectRulesRecoveryPoint::ApplyTo)
+    FixIt += "apply_to";
+  if (Point <= MissingAttributeSubjectRulesRecoveryPoint::Equals &&
+      EndPoint > MissingAttributeSubjectRulesRecoveryPoint::Equals)
+    FixIt += " = ";
+  SourceRange FixItRange(Loc);
+  if (EndPoint == MissingAttributeSubjectRulesRecoveryPoint::None) {
+    // Gather the subject match rules that are supported by the attribute.
+    SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> SubjectMatchRuleSet;
+    Attribute.getMatchRules(PRef.getLangOpts(), SubjectMatchRuleSet);
+    if (SubjectMatchRuleSet.empty()) {
+      // FIXME: We can emit a "fix-it" with a subject list placeholder when
+      // placeholders will be supported by the fix-its.
+      return Diagnostic;
+    }
+    FixIt += "any(";
+    bool NeedsComma = false;
+    for (const auto &I : SubjectMatchRuleSet) {
+      // Ensure that the missing rule is reported in the fix-it only when it's
+      // supported in the current language mode.
+      if (!I.second)
+        continue;
+      if (NeedsComma)
+        FixIt += ", ";
+      else
+        NeedsComma = true;
+      FixIt += attr::getSubjectMatchRuleSpelling(I.first);
+    }
+    FixIt += ")";
+    // Check if we need to remove the range
+    PRef.SkipUntil(tok::eof, Parser::StopBeforeMatch);
+    FixItRange.setEnd(PRef.getCurToken().getLocation());
+  }
+  if (FixItRange.getBegin() == FixItRange.getEnd())
+    Diagnostic << FixItHint::CreateInsertion(FixItRange.getBegin(), FixIt);
+  else
+    Diagnostic << FixItHint::CreateReplacement(
+        CharSourceRange::getCharRange(FixItRange), FixIt);
+  return Diagnostic;
+}
+
+} // end anonymous namespace
+
+void Parser::HandlePragmaAttribute() {
+  assert(Tok.is(tok::annot_pragma_attribute) &&
+         "Expected #pragma attribute annotation token");
+  SourceLocation PragmaLoc = Tok.getLocation();
+  auto *Info = static_cast<PragmaAttributeInfo *>(Tok.getAnnotationValue());
+  if (Info->Action == PragmaAttributeInfo::Pop) {
+    ConsumeToken();
+    Actions.ActOnPragmaAttributePop(PragmaLoc);
+    return;
+  }
+  // Parse the actual attribute with its arguments.
+  assert(Info->Action == PragmaAttributeInfo::Push &&
+         "Unexpected #pragma attribute command");
+  PP.EnterTokenStream(Info->Tokens, /*DisableMacroExpansion=*/false);
+  ConsumeToken();
+
+  ParsedAttributes &Attrs = Info->Attributes;
+  Attrs.clearListOnly();
+
+  auto SkipToEnd = [this]() {
+    SkipUntil(tok::eof, StopBeforeMatch);
+    ConsumeToken();
+  };
+
+  if (Tok.is(tok::l_square) && NextToken().is(tok::l_square)) {
+    // Parse the CXX11 style attribute.
+    ParseCXX11AttributeSpecifier(Attrs);
+  } else if (Tok.is(tok::kw___attribute)) {
+    ConsumeToken();
+    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
+                         "attribute"))
+      return SkipToEnd();
+    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "("))
+      return SkipToEnd();
+
+    if (Tok.isNot(tok::identifier)) {
+      Diag(Tok, diag::err_pragma_attribute_expected_attribute_name);
+      SkipToEnd();
+      return;
+    }
+    IdentifierInfo *AttrName = Tok.getIdentifierInfo();
+    SourceLocation AttrNameLoc = ConsumeToken();
+
+    if (Tok.isNot(tok::l_paren))
+      Attrs.addNew(AttrName, AttrNameLoc, nullptr, AttrNameLoc, nullptr, 0,
+                   AttributeList::AS_GNU);
+    else
+      ParseGNUAttributeArgs(AttrName, AttrNameLoc, Attrs, /*EndLoc=*/nullptr,
+                            /*ScopeName=*/nullptr,
+                            /*ScopeLoc=*/SourceLocation(),
+                            AttributeList::AS_GNU,
+                            /*Declarator=*/nullptr);
+
+    if (ExpectAndConsume(tok::r_paren))
+      return SkipToEnd();
+    if (ExpectAndConsume(tok::r_paren))
+      return SkipToEnd();
+  } else if (Tok.is(tok::kw___declspec)) {
+    ParseMicrosoftDeclSpecs(Attrs);
+  } else {
+    Diag(Tok, diag::err_pragma_attribute_expected_attribute_syntax);
+    if (Tok.getIdentifierInfo()) {
+      // If we suspect that this is an attribute suggest the use of
+      // '__attribute__'.
+      if (AttributeList::getKind(Tok.getIdentifierInfo(), /*ScopeName=*/nullptr,
+                                 AttributeList::AS_GNU) !=
+          AttributeList::UnknownAttribute) {
+        SourceLocation InsertStartLoc = Tok.getLocation();
+        ConsumeToken();
+        if (Tok.is(tok::l_paren)) {
+          ConsumeAnyToken();
+          SkipUntil(tok::r_paren, StopBeforeMatch);
+          if (Tok.isNot(tok::r_paren))
+            return SkipToEnd();
+        }
+        Diag(Tok, diag::note_pragma_attribute_use_attribute_kw)
+            << FixItHint::CreateInsertion(InsertStartLoc, "__attribute__((")
+            << FixItHint::CreateInsertion(Tok.getEndLoc(), "))");
+      }
+    }
+    SkipToEnd();
+    return;
+  }
+
+  if (!Attrs.getList() || Attrs.getList()->isInvalid()) {
+    SkipToEnd();
+    return;
+  }
+
+  // Ensure that we don't have more than one attribute.
+  if (Attrs.getList()->getNext()) {
+    SourceLocation Loc = Attrs.getList()->getNext()->getLoc();
+    Diag(Loc, diag::err_pragma_attribute_multiple_attributes);
+    SkipToEnd();
+    return;
+  }
+
+  if (!Attrs.getList()->isSupportedByPragmaAttribute()) {
+    Diag(PragmaLoc, diag::err_pragma_attribute_unsupported_attribute)
+        << Attrs.getList()->getName();
+    SkipToEnd();
+    return;
+  }
+  AttributeList &Attribute = *Attrs.getList();
+
+  // Parse the subject-list.
+  if (!TryConsumeToken(tok::comma)) {
+    createExpectedAttributeSubjectRulesTokenDiagnostic(
+        diag::err_expected, Attribute,
+        MissingAttributeSubjectRulesRecoveryPoint::Comma, *this)
+        << tok::comma;
+    SkipToEnd();
+    return;
+  }
+
+  if (Tok.isNot(tok::identifier)) {
+    createExpectedAttributeSubjectRulesTokenDiagnostic(
+        diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
+        MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
+    SkipToEnd();
+    return;
+  }
+  const IdentifierInfo *II = Tok.getIdentifierInfo();
+  if (!II->isStr("apply_to")) {
+    createExpectedAttributeSubjectRulesTokenDiagnostic(
+        diag::err_pragma_attribute_invalid_subject_set_specifier, Attribute,
+        MissingAttributeSubjectRulesRecoveryPoint::ApplyTo, *this);
+    SkipToEnd();
+    return;
+  }
+  ConsumeToken();
+
+  if (!TryConsumeToken(tok::equal)) {
+    createExpectedAttributeSubjectRulesTokenDiagnostic(
+        diag::err_expected, Attribute,
+        MissingAttributeSubjectRulesRecoveryPoint::Equals, *this)
+        << tok::equal;
+    SkipToEnd();
+    return;
+  }
+
+  attr::ParsedSubjectMatchRuleSet SubjectMatchRules;
+  SourceLocation AnyLoc, LastMatchRuleEndLoc;
+  if (ParsePragmaAttributeSubjectMatchRuleSet(SubjectMatchRules, AnyLoc,
+                                              LastMatchRuleEndLoc)) {
+    SkipToEnd();
+    return;
+  }
+
+  // Tokens following an ill-formed attribute will remain in the token stream
+  // and must be removed.
+  if (Tok.isNot(tok::eof)) {
+    Diag(Tok, diag::err_pragma_attribute_extra_tokens_after_attribute);
+    SkipToEnd();
+    return;
+  }
+
+  // Consume the eof terminator token.
+  ConsumeToken();
+
+  Actions.ActOnPragmaAttributePush(Attribute, PragmaLoc,
+                                   std::move(SubjectMatchRules));
+}
+
 // #pragma GCC visibility comes in two variants:
 //   'push' '(' [visibility] ')'
 //   'pop'
@@ -1947,6 +2406,129 @@
   Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
 }
 
+namespace {
+/// Used as the annotation value for tok::annot_pragma_fp.
+struct TokFPAnnotValue {
+  enum FlagKinds { Contract };
+  enum FlagValues { On, Off, Fast };
+
+  FlagKinds FlagKind;
+  FlagValues FlagValue;
+};
+} // end anonymous namespace
+
+void PragmaFPHandler::HandlePragma(Preprocessor &PP,
+                                   PragmaIntroducerKind Introducer,
+                                   Token &Tok) {
+  // fp
+  Token PragmaName = Tok;
+  SmallVector<Token, 1> TokenList;
+
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
+        << /*MissingOption=*/true << "";
+    return;
+  }
+
+  while (Tok.is(tok::identifier)) {
+    IdentifierInfo *OptionInfo = Tok.getIdentifierInfo();
+
+    auto FlagKind =
+        llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagKinds>>(
+            OptionInfo->getName())
+            .Case("contract", TokFPAnnotValue::Contract)
+            .Default(None);
+    if (!FlagKind) {
+      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_option)
+          << /*MissingOption=*/false << OptionInfo;
+      return;
+    }
+    PP.Lex(Tok);
+
+    // Read '('
+    if (Tok.isNot(tok::l_paren)) {
+      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
+      return;
+    }
+    PP.Lex(Tok);
+
+    if (Tok.isNot(tok::identifier)) {
+      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
+          << PP.getSpelling(Tok) << OptionInfo->getName();
+      return;
+    }
+    const IdentifierInfo *II = Tok.getIdentifierInfo();
+
+    auto FlagValue =
+        llvm::StringSwitch<llvm::Optional<TokFPAnnotValue::FlagValues>>(
+            II->getName())
+            .Case("on", TokFPAnnotValue::On)
+            .Case("off", TokFPAnnotValue::Off)
+            .Case("fast", TokFPAnnotValue::Fast)
+            .Default(llvm::None);
+
+    if (!FlagValue) {
+      PP.Diag(Tok.getLocation(), diag::err_pragma_fp_invalid_argument)
+          << PP.getSpelling(Tok) << OptionInfo->getName();
+      return;
+    }
+    PP.Lex(Tok);
+
+    // Read ')'
+    if (Tok.isNot(tok::r_paren)) {
+      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
+      return;
+    }
+    PP.Lex(Tok);
+
+    auto *AnnotValue = new (PP.getPreprocessorAllocator())
+        TokFPAnnotValue{*FlagKind, *FlagValue};
+    // Generate the loop hint token.
+    Token FPTok;
+    FPTok.startToken();
+    FPTok.setKind(tok::annot_pragma_fp);
+    FPTok.setLocation(PragmaName.getLocation());
+    FPTok.setAnnotationEndLoc(PragmaName.getLocation());
+    FPTok.setAnnotationValue(reinterpret_cast<void *>(AnnotValue));
+    TokenList.push_back(FPTok);
+  }
+
+  if (Tok.isNot(tok::eod)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+        << "clang fp";
+    return;
+  }
+
+  auto TokenArray = llvm::make_unique<Token[]>(TokenList.size());
+  std::copy(TokenList.begin(), TokenList.end(), TokenArray.get());
+
+  PP.EnterTokenStream(std::move(TokenArray), TokenList.size(),
+                      /*DisableMacroExpansion=*/false);
+}
+
+void Parser::HandlePragmaFP() {
+  assert(Tok.is(tok::annot_pragma_fp));
+  auto *AnnotValue =
+      reinterpret_cast<TokFPAnnotValue *>(Tok.getAnnotationValue());
+
+  LangOptions::FPContractModeKind FPC;
+  switch (AnnotValue->FlagValue) {
+  case TokFPAnnotValue::On:
+    FPC = LangOptions::FPC_On;
+    break;
+  case TokFPAnnotValue::Fast:
+    FPC = LangOptions::FPC_Fast;
+    break;
+  case TokFPAnnotValue::Off:
+    FPC = LangOptions::FPC_Off;
+    break;
+  }
+
+  Actions.ActOnPragmaFPContract(FPC);
+  ConsumeToken(); // The annotation token.
+}
+
 /// \brief Parses loop or unroll pragma hint value and fills in Info.
 static bool ParseLoopHintValue(Preprocessor &PP, Token &Tok, Token PragmaName,
                                Token Option, bool ValueInParens,
@@ -2246,3 +2828,104 @@
     PP.Diag(FirstTok.getLocation(),
             diag::warn_pragma_force_cuda_host_device_bad_arg);
 }
+
+/// \brief Handle the #pragma clang attribute directive.
+///
+/// The syntax is:
+/// \code
+///  #pragma clang attribute push(attribute, subject-set)
+///  #pragma clang attribute pop
+/// \endcode
+///
+/// The subject-set clause defines the set of declarations which receive the
+/// attribute. Its exact syntax is described in the LanguageExtensions document
+/// in Clang's documentation.
+///
+/// This directive instructs the compiler to begin/finish applying the specified
+/// attribute to the set of attribute-specific declarations in the active range
+/// of the pragma.
+void PragmaAttributeHandler::HandlePragma(Preprocessor &PP,
+                                          PragmaIntroducerKind Introducer,
+                                          Token &FirstToken) {
+  Token Tok;
+  PP.Lex(Tok);
+  auto *Info = new (PP.getPreprocessorAllocator())
+      PragmaAttributeInfo(AttributesForPragmaAttribute);
+
+  // Parse the 'push' or 'pop'.
+  if (Tok.isNot(tok::identifier)) {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_push_pop);
+    return;
+  }
+  const auto *II = Tok.getIdentifierInfo();
+  if (II->isStr("push"))
+    Info->Action = PragmaAttributeInfo::Push;
+  else if (II->isStr("pop"))
+    Info->Action = PragmaAttributeInfo::Pop;
+  else {
+    PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_invalid_argument)
+        << PP.getSpelling(Tok);
+    return;
+  }
+  PP.Lex(Tok);
+
+  // Parse the actual attribute.
+  if (Info->Action == PragmaAttributeInfo::Push) {
+    if (Tok.isNot(tok::l_paren)) {
+      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::l_paren;
+      return;
+    }
+    PP.Lex(Tok);
+
+    // Lex the attribute tokens.
+    SmallVector<Token, 16> AttributeTokens;
+    int OpenParens = 1;
+    while (Tok.isNot(tok::eod)) {
+      if (Tok.is(tok::l_paren))
+        OpenParens++;
+      else if (Tok.is(tok::r_paren)) {
+        OpenParens--;
+        if (OpenParens == 0)
+          break;
+      }
+
+      AttributeTokens.push_back(Tok);
+      PP.Lex(Tok);
+    }
+
+    if (AttributeTokens.empty()) {
+      PP.Diag(Tok.getLocation(), diag::err_pragma_attribute_expected_attribute);
+      return;
+    }
+    if (Tok.isNot(tok::r_paren)) {
+      PP.Diag(Tok.getLocation(), diag::err_expected) << tok::r_paren;
+      return;
+    }
+    SourceLocation EndLoc = Tok.getLocation();
+    PP.Lex(Tok);
+
+    // Terminate the attribute for parsing.
+    Token EOFTok;
+    EOFTok.startToken();
+    EOFTok.setKind(tok::eof);
+    EOFTok.setLocation(EndLoc);
+    AttributeTokens.push_back(EOFTok);
+
+    Info->Tokens =
+        llvm::makeArrayRef(AttributeTokens).copy(PP.getPreprocessorAllocator());
+  }
+
+  if (Tok.isNot(tok::eod))
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+        << "clang attribute";
+
+  // Generate the annotated pragma token.
+  auto TokenArray = llvm::make_unique<Token[]>(1);
+  TokenArray[0].startToken();
+  TokenArray[0].setKind(tok::annot_pragma_attribute);
+  TokenArray[0].setLocation(FirstToken.getLocation());
+  TokenArray[0].setAnnotationEndLoc(FirstToken.getLocation());
+  TokenArray[0].setAnnotationValue(static_cast<void *>(Info));
+  PP.EnterTokenStream(std::move(TokenArray), 1,
+                      /*DisableMacroExpansion=*/false);
+}
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 30e392f..68f9ddf 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -341,6 +341,12 @@
     ConsumeToken();
     return StmtError();
 
+  case tok::annot_pragma_fp:
+    ProhibitAttributes(Attrs);
+    Diag(Tok, diag::err_pragma_fp_scope);
+    ConsumeToken();
+    return StmtError();
+
   case tok::annot_pragma_opencl_extension:
     ProhibitAttributes(Attrs);
     HandlePragmaOpenCLExtension();
@@ -376,6 +382,10 @@
   case tok::annot_pragma_dump:
     HandlePragmaDump();
     return StmtEmpty();
+
+  case tok::annot_pragma_attribute:
+    HandlePragmaAttribute();
+    return StmtEmpty();
   }
 
   // If we reached this code, the statement must end in a semicolon.
@@ -900,6 +910,9 @@
     case tok::annot_pragma_fp_contract:
       HandlePragmaFPContract();
       break;
+    case tok::annot_pragma_fp:
+      HandlePragmaFP();
+      break;
     case tok::annot_pragma_ms_pointers_to_members:
       HandlePragmaMSPointersToMembers();
       break;
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 52e5194..1a57b1d 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -87,6 +87,11 @@
   PP.addCommentHandler(CommentSemaHandler.get());
 
   PP.setCodeCompletionHandler(*this);
+
+  Actions.ParseTypeFromStringCallback =
+    [this](StringRef typeStr, StringRef context, SourceLocation includeLoc) {
+      return this->parseTypeFromString(typeStr, context, includeLoc);
+    };
 }
 
 DiagnosticBuilder Parser::Diag(SourceLocation Loc, unsigned DiagID) {
@@ -231,6 +236,21 @@
       << FixItHint::CreateRemoval(SourceRange(StartLoc, EndLoc));
 }
 
+bool Parser::expectIdentifier() {
+  if (Tok.is(tok::identifier))
+    return false;
+  if (const auto *II = Tok.getIdentifierInfo()) {
+    if (II->isCPlusPlusKeyword(getLangOpts())) {
+      Diag(Tok, diag::err_expected_token_instead_of_objcxx_keyword)
+          << tok::identifier << Tok.getIdentifierInfo();
+      // Objective-C++: Recover by treating this keyword as a valid identifier.
+      return false;
+    }
+  }
+  Diag(Tok, diag::err_expected) << tok::identifier;
+  return true;
+}
+
 //===----------------------------------------------------------------------===//
 // Error recovery.
 //===----------------------------------------------------------------------===//
@@ -419,6 +439,9 @@
 //===----------------------------------------------------------------------===//
 
 Parser::~Parser() {
+  // Clear out the parse-type-from-string callback.
+  Actions.ParseTypeFromStringCallback = nullptr;
+
   // If we still have scopes active, delete the scope tree.
   delete getCurScope();
   Actions.CurScope = nullptr;
@@ -493,6 +516,8 @@
   Ident_strict = nullptr;
   Ident_replacement = nullptr;
 
+  Ident_language = Ident_defined_in = Ident_generated_declaration = nullptr;
+
   Ident__except = nullptr;
 
   Ident__exception_code = Ident__exception_info = nullptr;
@@ -605,6 +630,10 @@
     ConsumeToken();
     return false;
 
+  case tok::annot_pragma_attribute:
+    HandlePragmaAttribute();
+    return false;
+
   case tok::eof:
     // Late template parsing can begin.
     if (getLangOpts().DelayedTemplateParsing)
@@ -688,6 +717,9 @@
   case tok::annot_pragma_fp_contract:
     HandlePragmaFPContract();
     return nullptr;
+  case tok::annot_pragma_fp:
+    HandlePragmaFP();
+    break;
   case tok::annot_pragma_opencl_extension:
     HandlePragmaOpenCLExtension();
     return nullptr;
@@ -847,6 +879,10 @@
 
   default:
   dont_know:
+    if (Tok.isEditorPlaceholder()) {
+      ConsumeToken();
+      return nullptr;
+    }
     // We can't tell whether this is a function-definition or declaration yet.
     return ParseDeclarationOrFunctionDefinition(attrs, DS);
   }
@@ -1675,6 +1711,8 @@
           return false;
         }
       }
+      if (Tok.isEditorPlaceholder())
+        return true;
 
       Diag(Tok.getLocation(), diag::err_expected_qualified_after_typename);
       return true;
diff --git a/lib/Sema/AttributeList.cpp b/lib/Sema/AttributeList.cpp
index 55e9601..724db45 100644
--- a/lib/Sema/AttributeList.cpp
+++ b/lib/Sema/AttributeList.cpp
@@ -16,6 +16,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
+#include "clang/Basic/AttrSubjectMatchRules.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Sema/SemaInternal.h"
@@ -160,12 +161,16 @@
   unsigned IsType : 1;
   unsigned IsStmt : 1;
   unsigned IsKnownToGCC : 1;
+  unsigned IsSupportedByPragmaAttribute : 1;
 
   bool (*DiagAppertainsToDecl)(Sema &S, const AttributeList &Attr,
                                const Decl *);
   bool (*DiagLangOpts)(Sema &S, const AttributeList &Attr);
   bool (*ExistsInTarget)(const TargetInfo &Target);
   unsigned (*SpellingIndexToSemanticSpelling)(const AttributeList &Attr);
+  void (*GetPragmaAttributeMatchRules)(
+      llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules,
+      const LangOptions &LangOpts);
 };
 
 namespace {
@@ -192,6 +197,18 @@
   return getInfo(*this).DiagAppertainsToDecl(S, *this, D);
 }
 
+bool AttributeList::appliesToDecl(const Decl *D,
+                                  attr::SubjectMatchRule MatchRule) const {
+  return checkAttributeMatchRuleAppliesTo(D, MatchRule);
+}
+
+void AttributeList::getMatchRules(
+    const LangOptions &LangOpts,
+    SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &MatchRules)
+    const {
+  return getInfo(*this).GetPragmaAttributeMatchRules(MatchRules, LangOpts);
+}
+
 bool AttributeList::diagnoseLangOpts(Sema &S) const {
   return getInfo(*this).DiagLangOpts(S, *this);
 }
@@ -216,6 +233,10 @@
   return getInfo(*this).IsKnownToGCC;
 }
 
+bool AttributeList::isSupportedByPragmaAttribute() const {
+  return getInfo(*this).IsSupportedByPragmaAttribute;
+}
+
 unsigned AttributeList::getSemanticSpelling() const {
   return getInfo(*this).SpellingIndexToSemanticSpelling(*this);
 }
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 7a59732..c92879a 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -20,6 +20,7 @@
   Sema.cpp
   SemaAccess.cpp
   SemaAttr.cpp
+  SemaAPINotes.cpp
   SemaCXXScopeSpec.cpp
   SemaCast.cpp
   SemaChecking.cpp
@@ -61,4 +62,5 @@
   clangBasic
   clangEdit
   clangLex
+  clangAPINotes
   )
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp
index 0bdb194..53263ba 100644
--- a/lib/Sema/IdentifierResolver.cpp
+++ b/lib/Sema/IdentifierResolver.cpp
@@ -381,7 +381,7 @@
     PP.getExternalSource()->updateOutOfDateIdentifier(II);
   
   if (II.isFromAST())
-    II.setFETokenInfoChangedSinceDeserialization();
+    II.setChangedSinceDeserialization();
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Sema/JumpDiagnostics.cpp b/lib/Sema/JumpDiagnostics.cpp
index 899d3fa..865aea9 100644
--- a/lib/Sema/JumpDiagnostics.cpp
+++ b/lib/Sema/JumpDiagnostics.cpp
@@ -287,6 +287,15 @@
     IndirectJumpTargets.push_back(cast<AddrLabelExpr>(S)->getLabel());
     break;
 
+  case Stmt::ObjCForCollectionStmtClass: {
+    auto *CS = cast<ObjCForCollectionStmt>(S);
+    unsigned Diag = diag::note_protected_by_objc_fast_enumeration;
+    unsigned NewParentScope = Scopes.size();
+    Scopes.push_back(GotoScope(ParentScope, Diag, 0, S->getLocStart()));
+    BuildScopeInformation(CS->getBody(), NewParentScope);
+    return;
+  }
+
   case Stmt::IndirectGotoStmtClass:
     // "goto *&&lbl;" is a special case which we treat as equivalent
     // to a normal goto.  In addition, we don't calculate scope in the
diff --git a/lib/Sema/ScopeInfo.cpp b/lib/Sema/ScopeInfo.cpp
index 3970b41..58d44ba 100644
--- a/lib/Sema/ScopeInfo.cpp
+++ b/lib/Sema/ScopeInfo.cpp
@@ -184,7 +184,7 @@
   }
 
   // Has this weak object been seen before?
-  FunctionScopeInfo::WeakObjectUseMap::iterator Uses;
+  FunctionScopeInfo::WeakObjectUseMap::iterator Uses = WeakObjectUses.end();
   if (const ObjCPropertyRefExpr *RefExpr = dyn_cast<ObjCPropertyRefExpr>(E)) {
     if (!RefExpr->isObjectReceiver())
       return;
@@ -197,10 +197,10 @@
   }
   else if (const ObjCIvarRefExpr *IvarE = dyn_cast<ObjCIvarRefExpr>(E))
     Uses = WeakObjectUses.find(WeakObjectProfileTy(IvarE));
-  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
-    Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
-  else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
-    Uses = WeakObjectUses.end();
+  else if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
+    if (isa<VarDecl>(DRE->getDecl()))
+      Uses = WeakObjectUses.find(WeakObjectProfileTy(DRE));
+  } else if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
     if (const ObjCMethodDecl *MD = MsgE->getMethodDecl()) {
       if (const ObjCPropertyDecl *Prop = MD->findPropertyDecl()) {
         Uses =
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 412f944..24904e6 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -77,7 +77,8 @@
     isMultiplexExternalSource(false), FPFeatures(pp.getLangOpts()),
     LangOpts(pp.getLangOpts()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
-    CollectStats(false), CodeCompleter(CodeCompleter),
+    APINotes(SourceMgr, LangOpts), CollectStats(false),
+    CodeCompleter(CodeCompleter),
     CurContext(nullptr), OriginalLexicalContext(nullptr),
     MSStructPragmaOn(false),
     MSPointerToMemberRepresentationMethod(
@@ -85,7 +86,7 @@
     VtorDispStack(MSVtorDispAttr::Mode(LangOpts.VtorDispMode)),
     PackStack(0), DataSegStack(nullptr), BSSSegStack(nullptr),
     ConstSegStack(nullptr), CodeSegStack(nullptr), CurInitSeg(nullptr),
-    VisContext(nullptr),
+    VisContext(nullptr), PragmaAttributeCurrentTargetDecl(nullptr),
     IsBuildingRecoveryCallExpr(false),
     Cleanup{}, LateTemplateParser(nullptr),
     LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), IdResolver(pp),
@@ -731,6 +732,8 @@
     CheckDelayedMemberExceptionSpecs();
   }
 
+  DiagnoseUnterminatedPragmaAttribute();
+
   // All delayed member exception specs should be checked or we end up accepting
   // incompatible declarations.
   // FIXME: This is wrong for TUKind == TU_Prefix. In that case, we need to
@@ -1102,6 +1105,8 @@
     PrintInstantiationStack();
     LastTemplateInstantiationErrorContext = ActiveTemplateInstantiations.back();
   }
+  if (PragmaAttributeCurrentTargetDecl)
+    PrintPragmaAttributeInstantiationPoint();
 }
 
 Sema::SemaDiagnosticBuilder
@@ -1243,14 +1248,14 @@
   return CurBSI;
 }
 
-LambdaScopeInfo *Sema::getCurLambda(bool IgnoreCapturedRegions) {
+LambdaScopeInfo *Sema::getCurLambda(bool IgnoreNonLambdaCapturingScope) {
   if (FunctionScopes.empty())
     return nullptr;
 
   auto I = FunctionScopes.rbegin();
-  if (IgnoreCapturedRegions) {
+  if (IgnoreNonLambdaCapturingScope) {
     auto E = FunctionScopes.rend();
-    while (I != E && isa<CapturedRegionScopeInfo>(*I))
+    while (I != E && isa<CapturingScopeInfo>(*I) && !isa<LambdaScopeInfo>(*I))
       ++I;
     if (I == E)
       return nullptr;
diff --git a/lib/Sema/SemaAPINotes.cpp b/lib/Sema/SemaAPINotes.cpp
new file mode 100644
index 0000000..6145fef
--- /dev/null
+++ b/lib/Sema/SemaAPINotes.cpp
@@ -0,0 +1,887 @@
+//===--- SemaAPINotes.cpp - API Notes Handling ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements the mapping from API notes to declaration attributes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Sema/SemaInternal.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/APINotes/APINotesReader.h"
+using namespace clang;
+
+namespace {
+  enum IsActive_t : bool {
+    IsNotActive,
+    IsActive
+  };
+
+  struct VersionedInfoMetadata {
+    /// An empty version refers to unversioned metadata.
+    VersionTuple Version;
+    bool IsActive;
+
+    VersionedInfoMetadata(VersionTuple version, IsActive_t active)
+        : Version(version), IsActive(active == IsActive_t::IsActive) {}
+  };
+} // end anonymous namespace
+
+/// Determine whether this is a multi-level pointer type.
+static bool isMultiLevelPointerType(QualType type) {
+  QualType pointee = type->getPointeeType();
+  if (pointee.isNull())
+    return false;
+
+  return pointee->isAnyPointerType() || pointee->isObjCObjectPointerType() ||
+         pointee->isMemberPointerType();
+}
+
+// Apply nullability to the given declaration.
+static void applyNullability(Sema &S, Decl *decl, NullabilityKind nullability,
+                             VersionedInfoMetadata metadata) {
+  if (!metadata.IsActive)
+    return;
+
+  QualType type;
+
+  // Nullability for a function/method appertains to the retain type.
+  if (auto function = dyn_cast<FunctionDecl>(decl)) {
+    type = function->getReturnType();
+  } else if (auto method = dyn_cast<ObjCMethodDecl>(decl)) {
+    type = method->getReturnType();
+  } else if (auto value = dyn_cast<ValueDecl>(decl)) {
+    type = value->getType();
+  } else if (auto property = dyn_cast<ObjCPropertyDecl>(decl)) {
+    type = property->getType();
+  } else {
+    return;
+  }
+
+  // Check the nullability specifier on this type.
+  QualType origType = type;
+  S.checkNullabilityTypeSpecifier(type, nullability, decl->getLocation(),
+                                  /*isContextSensitive=*/false,
+                                  isa<ParmVarDecl>(decl), /*implicit=*/true,
+                                  /*overrideExisting=*/true);
+  if (type.getTypePtr() == origType.getTypePtr())
+    return;
+
+  if (auto function = dyn_cast<FunctionDecl>(decl)) {
+    const FunctionType *fnType = function->getType()->castAs<FunctionType>();
+    if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType)) {
+      function->setType(S.Context.getFunctionType(type, proto->getParamTypes(),
+                                                  proto->getExtProtoInfo()));
+    } else {
+      function->setType(S.Context.getFunctionNoProtoType(type,
+                                                         fnType->getExtInfo()));
+    }
+  } else if (auto method = dyn_cast<ObjCMethodDecl>(decl)) {
+    method->setReturnType(type);
+
+    // Make it a context-sensitive keyword if we can.
+    if (!isMultiLevelPointerType(type)) {
+      method->setObjCDeclQualifier(
+        Decl::ObjCDeclQualifier(method->getObjCDeclQualifier() |
+                                Decl::OBJC_TQ_CSNullability));
+    }
+  } else if (auto value = dyn_cast<ValueDecl>(decl)) {
+    value->setType(type);
+
+    // Make it a context-sensitive keyword if we can.
+    if (auto parm = dyn_cast<ParmVarDecl>(decl)) {
+      if (parm->isObjCMethodParameter() && !isMultiLevelPointerType(type)) {
+        parm->setObjCDeclQualifier(
+          Decl::ObjCDeclQualifier(parm->getObjCDeclQualifier() |
+                                  Decl::OBJC_TQ_CSNullability));
+      }
+    }
+  } else if (auto property = dyn_cast<ObjCPropertyDecl>(decl)) {
+    property->setType(type, property->getTypeSourceInfo());
+
+    // Make it a property attribute if we can.
+    if (!isMultiLevelPointerType(type)) {
+      property->setPropertyAttributes(
+        ObjCPropertyDecl::OBJC_PR_null_resettable);
+    }
+  } else {
+    llvm_unreachable("cannot handle nullability here");
+  }
+}
+
+/// Copy a string into ASTContext-allocated memory.
+static StringRef CopyString(ASTContext &ctx, StringRef string) {
+  void *mem = ctx.Allocate(string.size(), alignof(char));
+  memcpy(mem, string.data(), string.size());
+  return StringRef(static_cast<char *>(mem), string.size());
+}
+
+namespace {
+  template <typename A>
+  struct AttrKindFor {};
+
+#define ATTR(X) \
+  template <> struct AttrKindFor<X##Attr> { \
+    static const attr::Kind value = attr::X; \
+  };
+#include "clang/Basic/AttrList.inc"
+
+  /// Handle an attribute introduced by API notes.
+  ///
+  /// \param shouldAddAttribute Whether we should add a new attribute
+  /// (otherwise, we might remove an existing attribute).
+  /// \param createAttr Create the new attribute to be added.
+  template<typename A>
+  void handleAPINotedAttribute(
+         Sema &S, Decl *D, bool shouldAddAttribute,
+         VersionedInfoMetadata metadata,
+         llvm::function_ref<A *()> createAttr,
+         llvm::function_ref<specific_attr_iterator<A>(Decl*)> getExistingAttr) {
+    if (metadata.IsActive) {
+      auto end = D->specific_attr_end<A>();
+      auto existing = getExistingAttr(D);
+      if (existing != end) {
+        // Remove the existing attribute, and treat it as a superseded
+        // non-versioned attribute.
+        auto *versioned =
+            SwiftVersionedAttr::CreateImplicit(S.Context, clang::VersionTuple(),
+                                               *existing);
+
+        D->getAttrs().erase(existing.getCurrent());
+        D->addAttr(versioned);
+      }
+
+      // If we're supposed to add a new attribute, do so.
+      if (shouldAddAttribute) {
+        if (auto attr = createAttr()) {
+          D->addAttr(attr);
+        }
+      }
+
+    } else {
+      if (shouldAddAttribute) {
+        if (auto attr = createAttr()) {
+          auto *versioned =
+              SwiftVersionedAttr::CreateImplicit(S.Context, metadata.Version, 
+                                                 attr);
+          D->addAttr(versioned);
+        }
+      } else {
+        // FIXME: This isn't preserving enough information for things like
+        // availability, where we're trying to remove a /specific/ kind of
+        // attribute.
+        auto *versioned =
+            SwiftVersionedRemovalAttr::CreateImplicit(S.Context, 
+                                                      metadata.Version,
+                                                      AttrKindFor<A>::value);
+        D->addAttr(versioned);
+      }
+    }
+  }
+  
+  template<typename A>
+  void handleAPINotedAttribute(
+         Sema &S, Decl *D, bool shouldAddAttribute,
+         VersionedInfoMetadata metadata,
+         llvm::function_ref<A *()> createAttr) {
+    handleAPINotedAttribute<A>(S, D, shouldAddAttribute, metadata, createAttr,
+    [](Decl *decl) {
+        return decl->specific_attr_begin<A>();
+    });
+  }
+}
+
+static void ProcessAPINotes(Sema &S, Decl *D,
+                            const api_notes::CommonEntityInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Availability
+  if (info.Unavailable) {
+    handleAPINotedAttribute<UnavailableAttr>(S, D, true, metadata,
+      [&] {
+        return UnavailableAttr::CreateImplicit(S.Context,
+                                               CopyString(S.Context,
+                                                          info.UnavailableMsg));
+    });
+  }
+
+  if (info.UnavailableInSwift) {
+    handleAPINotedAttribute<AvailabilityAttr>(S, D, true, metadata, [&] {
+      return AvailabilityAttr::CreateImplicit(
+                   S.Context,
+                   &S.Context.Idents.get("swift"),
+                   VersionTuple(),
+                   VersionTuple(),
+                   VersionTuple(),
+                   /*Unavailable=*/true,
+                   CopyString(S.Context, info.UnavailableMsg),
+                   /*Strict=*/false,
+                   /*Replacement=*/StringRef());
+    },
+    [](Decl *decl) {
+      auto existing = decl->specific_attr_begin<AvailabilityAttr>(),
+        end = decl->specific_attr_end<AvailabilityAttr>();
+      while (existing != end) {
+        if (auto platform = (*existing)->getPlatform()) {
+          if (platform->isStr("swift"))
+            break;
+        }
+
+        ++existing;
+      }
+
+      return existing;
+    });
+  }
+
+  // swift_private
+  if (auto swiftPrivate = info.isSwiftPrivate()) {
+    handleAPINotedAttribute<SwiftPrivateAttr>(S, D, *swiftPrivate, metadata,
+                                              [&] {
+      return SwiftPrivateAttr::CreateImplicit(S.Context);
+    });
+  }
+
+  // swift_name
+  if (!info.SwiftName.empty()) {
+    handleAPINotedAttribute<SwiftNameAttr>(S, D, true, metadata,
+                                           [&]() -> SwiftNameAttr * {
+      auto &APINoteName = S.getASTContext().Idents.get("SwiftName API Note");
+      
+      if (!S.DiagnoseSwiftName(D, info.SwiftName, D->getLocation(),
+                               &APINoteName)) {
+        return nullptr;
+      }
+
+      return SwiftNameAttr::CreateImplicit(S.Context,
+                                           CopyString(S.Context,
+                                                      info.SwiftName));
+    });
+  }
+}
+
+static void ProcessAPINotes(Sema &S, Decl *D,
+                            const api_notes::CommonTypeInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // swift_bridge
+  if (auto swiftBridge = info.getSwiftBridge()) {
+    handleAPINotedAttribute<SwiftBridgeAttr>(S, D, !swiftBridge->empty(),
+                                             metadata, [&] {
+      return SwiftBridgeAttr::CreateImplicit(S.Context,
+                                             CopyString(S.Context,
+                                                        *swiftBridge));
+    });
+  }
+
+  // ns_error_domain
+  if (auto nsErrorDomain = info.getNSErrorDomain()) {
+    handleAPINotedAttribute<NSErrorDomainAttr>(S, D, !nsErrorDomain->empty(),
+                                               metadata, [&] {
+      return NSErrorDomainAttr::CreateImplicit(
+               S.Context,
+               &S.Context.Idents.get(*nsErrorDomain));
+    });
+  }
+
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),
+                  metadata);
+}
+
+/// Check that the replacement type provided by API notes is reasonable.
+///
+/// This is a very weak form of ABI check.
+static bool checkAPINotesReplacementType(Sema &S, SourceLocation loc,
+                                         QualType origType,
+                                         QualType replacementType) {
+  if (S.Context.getTypeSize(origType) !=
+        S.Context.getTypeSize(replacementType)) {
+    S.Diag(loc, diag::err_incompatible_replacement_type)
+      << replacementType << origType;
+    return true;
+  }
+
+  return false;
+}
+
+/// Process API notes for a variable or property.
+static void ProcessAPINotes(Sema &S, Decl *D,
+                            const api_notes::VariableInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Type override.
+  if (metadata.IsActive && !info.getType().empty() &&
+      S.ParseTypeFromStringCallback) {
+    auto parsedType = S.ParseTypeFromStringCallback(info.getType(),
+                                                    "<API Notes>",
+                                                    D->getLocation());
+    if (parsedType.isUsable()) {
+      QualType type = Sema::GetTypeFromParser(parsedType.get());
+      auto typeInfo =
+        S.Context.getTrivialTypeSourceInfo(type, D->getLocation());
+
+      if (auto var = dyn_cast<VarDecl>(D)) {
+        // Make adjustments to parameter types.
+        if (isa<ParmVarDecl>(var)) {
+          type = S.adjustParameterTypeForObjCAutoRefCount(type,
+                                                          D->getLocation());
+          type = S.Context.getAdjustedParameterType(type);
+        }
+
+        if (!checkAPINotesReplacementType(S, var->getLocation(), var->getType(),
+                                          type)) {
+          var->setType(type);
+          var->setTypeSourceInfo(typeInfo);
+        }
+      } else if (auto property = dyn_cast<ObjCPropertyDecl>(D)) {
+        if (!checkAPINotesReplacementType(S, property->getLocation(),
+                                          property->getType(),
+                                          type)) {
+          property->setType(type, typeInfo);
+        }
+      } else {
+        llvm_unreachable("API notes allowed a type on an unknown declaration");
+      }
+    }
+  }
+
+  // Nullability.
+  if (auto Nullability = info.getNullability()) {
+    applyNullability(S, D, *Nullability, metadata);
+  }
+
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for a parameter.
+static void ProcessAPINotes(Sema &S, ParmVarDecl *D,
+                            const api_notes::ParamInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // noescape
+  if (auto noescape = info.isNoEscape()) {
+    handleAPINotedAttribute<NoEscapeAttr>(S, D, *noescape, metadata, [&] {
+      return NoEscapeAttr::CreateImplicit(S.Context);
+    });
+  }
+
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for a global variable.
+static void ProcessAPINotes(Sema &S, VarDecl *D,
+                            const api_notes::GlobalVariableInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for an Objective-C property.
+static void ProcessAPINotes(Sema &S, ObjCPropertyDecl *D,
+                            const api_notes::ObjCPropertyInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::VariableInfo &>(info),
+                  metadata);
+  if (auto asAccessors = info.getSwiftImportAsAccessors()) {
+    handleAPINotedAttribute<SwiftImportPropertyAsAccessorsAttr>(S, D,
+                                                                *asAccessors,
+                                                                metadata, [&] {
+      return SwiftImportPropertyAsAccessorsAttr::CreateImplicit(S.Context);
+    });
+  }
+}
+
+namespace {
+  typedef llvm::PointerUnion<FunctionDecl *, ObjCMethodDecl *> FunctionOrMethod;
+}
+
+/// Process API notes for a function or method.
+static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc,
+                            const api_notes::FunctionInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Find the declaration itself.
+  FunctionDecl *FD = AnyFunc.dyn_cast<FunctionDecl *>();
+  Decl *D = FD;
+  ObjCMethodDecl *MD = 0;
+  if (!D) {
+    MD = AnyFunc.get<ObjCMethodDecl *>();
+    D = MD;
+  }
+
+  // Nullability of return type.
+  if (info.NullabilityAudited) {
+    applyNullability(S, D, info.getReturnTypeInfo(), metadata);
+  }
+
+  // Parameters.
+  unsigned NumParams;
+  if (FD)
+    NumParams = FD->getNumParams();
+  else
+    NumParams = MD->param_size();
+
+  bool anyTypeChanged = false;
+  for (unsigned I = 0; I != NumParams; ++I) {
+    ParmVarDecl *Param;
+    if (FD)
+      Param = FD->getParamDecl(I);
+    else
+      Param = MD->param_begin()[I];
+
+    QualType paramTypeBefore = Param->getType();
+
+    if (I < info.Params.size()) {
+      ProcessAPINotes(S, Param, info.Params[I], metadata);
+    }
+
+    // Nullability.
+    if (info.NullabilityAudited)
+      applyNullability(S, Param, info.getParamTypeInfo(I), metadata);
+
+    if (paramTypeBefore.getAsOpaquePtr() != Param->getType().getAsOpaquePtr())
+      anyTypeChanged = true;
+  }
+
+  // Result type override.
+  QualType overriddenResultType;
+  if (metadata.IsActive && !info.ResultType.empty() &&
+      S.ParseTypeFromStringCallback) {
+    auto parsedType = S.ParseTypeFromStringCallback(info.ResultType,
+                                                    "<API Notes>",
+                                                    D->getLocation());
+    if (parsedType.isUsable()) {
+      QualType resultType = Sema::GetTypeFromParser(parsedType.get());
+
+      if (MD) {
+        if (!checkAPINotesReplacementType(S, D->getLocation(),
+                                          MD->getReturnType(), resultType)) {
+          auto resultTypeInfo =
+            S.Context.getTrivialTypeSourceInfo(resultType, D->getLocation());
+          MD->setReturnType(resultType);
+          MD->setReturnTypeSourceInfo(resultTypeInfo);
+        }
+      } else if (!checkAPINotesReplacementType(S, FD->getLocation(),
+                                               FD->getReturnType(),
+                                               resultType)) {
+        overriddenResultType = resultType;
+        anyTypeChanged = true;
+      }
+    }
+  }
+
+  // If the result type or any of the parameter types changed for a function
+  // declaration, we have to rebuild the type.
+  if (FD && anyTypeChanged) {
+    if (const auto *fnProtoType = FD->getType()->getAs<FunctionProtoType>()) {
+      if (overriddenResultType.isNull())
+        overriddenResultType = fnProtoType->getReturnType();
+
+      SmallVector<QualType, 4> paramTypes;
+      for (auto param : FD->parameters()) {
+        paramTypes.push_back(param->getType());
+      }
+      FD->setType(S.Context.getFunctionType(overriddenResultType,
+                                            paramTypes,
+                                            fnProtoType->getExtProtoInfo()));
+    } else if (!overriddenResultType.isNull()) {
+      const auto *fnNoProtoType = FD->getType()->castAs<FunctionNoProtoType>();
+      FD->setType(
+              S.Context.getFunctionNoProtoType(overriddenResultType,
+                                               fnNoProtoType->getExtInfo()));
+    }
+  }
+
+  // Handle common entity information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonEntityInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for a global function.
+static void ProcessAPINotes(Sema &S, FunctionDecl *D,
+                            const api_notes::GlobalFunctionInfo &info,
+                            VersionedInfoMetadata metadata) {
+
+  // Handle common function information.
+  ProcessAPINotes(S, FunctionOrMethod(D),
+                  static_cast<const api_notes::FunctionInfo &>(info), metadata);
+}
+
+/// Process API notes for an enumerator.
+static void ProcessAPINotes(Sema &S, EnumConstantDecl *D,
+                            const api_notes::EnumConstantInfo &info,
+                            VersionedInfoMetadata metadata) {
+
+  // Handle common information.
+  ProcessAPINotes(S, D,
+                  static_cast<const api_notes::CommonEntityInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for an Objective-C method.
+static void ProcessAPINotes(Sema &S, ObjCMethodDecl *D,
+                            const api_notes::ObjCMethodInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // Designated initializers.
+  if (info.DesignatedInit) {
+    handleAPINotedAttribute<ObjCDesignatedInitializerAttr>(S, D, true, metadata,
+                                                           [&] {
+      if (ObjCInterfaceDecl *IFace = D->getClassInterface()) {
+        IFace->setHasDesignatedInitializers();
+      }
+      return ObjCDesignatedInitializerAttr::CreateImplicit(S.Context);
+    });
+  }
+
+  // Handle common function information.
+  ProcessAPINotes(S, FunctionOrMethod(D),
+                  static_cast<const api_notes::FunctionInfo &>(info), metadata);
+}
+
+/// Process API notes for a tag.
+static void ProcessAPINotes(Sema &S, TagDecl *D,
+                            const api_notes::TagInfo &info,
+                            VersionedInfoMetadata metadata) {
+  if (auto extensibility = info.EnumExtensibility) {
+    using api_notes::EnumExtensibilityKind;
+    bool shouldAddAttribute = (*extensibility != EnumExtensibilityKind::None);
+    handleAPINotedAttribute<EnumExtensibilityAttr>(S, D, shouldAddAttribute,
+                                                   metadata, [&] {
+      EnumExtensibilityAttr::Kind kind;
+      switch (extensibility.getValue()) {
+      case EnumExtensibilityKind::None:
+        llvm_unreachable("remove only");
+      case EnumExtensibilityKind::Open:
+        kind = EnumExtensibilityAttr::Open;
+        break;
+      case EnumExtensibilityKind::Closed:
+        kind = EnumExtensibilityAttr::Closed;
+        break;
+      }
+      return EnumExtensibilityAttr::CreateImplicit(S.Context, kind);
+    });
+  }
+
+  if (auto flagEnum = info.isFlagEnum()) {
+    handleAPINotedAttribute<FlagEnumAttr>(S, D, flagEnum.getValue(), metadata,
+                                          [&] {
+      return FlagEnumAttr::CreateImplicit(S.Context);
+    });
+  }
+
+  // Handle common type information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for a typedef.
+static void ProcessAPINotes(Sema &S, TypedefNameDecl *D,
+                            const api_notes::TypedefInfo &info,
+                            VersionedInfoMetadata metadata) {
+  // swift_wrapper
+  using SwiftWrapperKind = api_notes::SwiftWrapperKind;
+
+  if (auto swiftWrapper = info.SwiftWrapper) {
+    handleAPINotedAttribute<SwiftNewtypeAttr>(S, D,
+      *swiftWrapper != SwiftWrapperKind::None, metadata,
+      [&] {
+        SwiftNewtypeAttr::NewtypeKind kind;
+        switch (*swiftWrapper) {
+        case SwiftWrapperKind::None:
+          llvm_unreachable("Shouldn't build an attribute");
+
+        case SwiftWrapperKind::Struct:
+          kind = SwiftNewtypeAttr::NK_Struct;
+          break;
+
+        case SwiftWrapperKind::Enum:
+          kind = SwiftNewtypeAttr::NK_Enum;
+          break;
+        }
+        return SwiftNewtypeAttr::CreateImplicit(
+                 S.Context,
+                 SwiftNewtypeAttr::GNU_swift_wrapper,
+                 kind);
+    });
+  }
+
+  // Handle common type information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for an Objective-C class or protocol.
+static void ProcessAPINotes(Sema &S, ObjCContainerDecl *D,
+                            const api_notes::ObjCContextInfo &info,
+                            VersionedInfoMetadata metadata) {
+
+  // Handle common type information.
+  ProcessAPINotes(S, D, static_cast<const api_notes::CommonTypeInfo &>(info),
+                  metadata);
+}
+
+/// Process API notes for an Objective-C class.
+static void ProcessAPINotes(Sema &S, ObjCInterfaceDecl *D,
+                            const api_notes::ObjCContextInfo &info,
+                            VersionedInfoMetadata metadata) {
+  if (auto asNonGeneric = info.getSwiftImportAsNonGeneric()) {
+    handleAPINotedAttribute<SwiftImportAsNonGenericAttr>(S, D, *asNonGeneric,
+                                                         metadata, [&] {
+      return SwiftImportAsNonGenericAttr::CreateImplicit(S.Context);
+    });
+  }
+
+    if (auto objcMembers = info.getSwiftObjCMembers()) {
+    handleAPINotedAttribute<SwiftObjCMembersAttr>(S, D, *objcMembers,
+                                                         metadata, [&] {
+      return SwiftObjCMembersAttr::CreateImplicit(S.Context);
+    });
+  }
+
+  // Handle information common to Objective-C classes and protocols.
+  ProcessAPINotes(S, static_cast<clang::ObjCContainerDecl *>(D), info,
+                  metadata);
+}
+
+/// If we're applying API notes with an active, non-default version, and the
+/// versioned API notes have a SwiftName but the declaration normally wouldn't
+/// have one, add a removal attribute to make it clear that the new SwiftName
+/// attribute only applies to the active version of \p D, not to all versions.
+///
+/// This must be run \em before processing API notes for \p D, because otherwise
+/// any existing SwiftName attribute will have been packaged up in a 
+/// SwiftVersionedAttr.
+template <typename SpecificInfo>
+static void maybeAttachUnversionedSwiftName(
+    Sema &S, Decl *D,
+    const api_notes::APINotesReader::VersionedInfo<SpecificInfo> Info) {
+  if (D->hasAttr<SwiftNameAttr>())
+    return;
+  if (!Info.getSelected())
+    return;
+
+  // Is the active slice versioned, and does it set a Swift name?
+  VersionTuple SelectedVersion;
+  SpecificInfo SelectedInfoSlice;
+  std::tie(SelectedVersion, SelectedInfoSlice) = Info[*Info.getSelected()];
+  if (SelectedVersion.empty())
+    return;
+  if (SelectedInfoSlice.SwiftName.empty())
+    return;
+
+  // Does the unversioned slice /not/ set a Swift name?
+  for (const auto &VersionAndInfoSlice : Info) {
+    if (!VersionAndInfoSlice.first.empty())
+      continue;
+    if (!VersionAndInfoSlice.second.SwiftName.empty())
+      return;
+  }
+
+  // Then explicitly call that out with a removal attribute.
+  VersionedInfoMetadata DummyFutureMetadata(VersionTuple(), IsNotActive);
+  handleAPINotedAttribute<SwiftNameAttr>(S, D, /*add*/false,
+                                         DummyFutureMetadata,
+                                         []() -> SwiftNameAttr * {
+    llvm_unreachable("should not try to add an attribute here");
+  });
+}
+
+/// Processes all versions of versioned API notes.
+///
+/// Just dispatches to the various ProcessAPINotes functions in this file.
+template <typename SpecificDecl, typename SpecificInfo>
+static void ProcessVersionedAPINotes(
+    Sema &S, SpecificDecl *D,
+    const api_notes::APINotesReader::VersionedInfo<SpecificInfo> Info) {
+
+  maybeAttachUnversionedSwiftName(S, D, Info);
+
+  unsigned Selected = Info.getSelected().getValueOr(Info.size());
+
+  VersionTuple Version;
+  SpecificInfo InfoSlice;
+  for (unsigned i = 0, e = Info.size(); i != e; ++i) {
+    std::tie(Version, InfoSlice) = Info[i];
+    auto Active = (i == Selected) ? IsActive : IsNotActive;
+    ProcessAPINotes(S, D, InfoSlice, VersionedInfoMetadata(Version, Active));
+  }
+}
+
+/// Process API notes that are associated with this declaration, mapping them
+/// to attributes as appropriate.
+void Sema::ProcessAPINotes(Decl *D) {
+  if (!D)
+    return;
+
+  // Globals.
+  if (D->getDeclContext()->isFileContext()) {
+    // Global variables.
+    if (auto VD = dyn_cast<VarDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupGlobalVariable(VD->getName());
+        ProcessVersionedAPINotes(*this, VD, Info);
+      }
+
+      return;
+    }
+
+    // Global functions.
+    if (auto FD = dyn_cast<FunctionDecl>(D)) {
+      if (FD->getDeclName().isIdentifier()) {
+        for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+          auto Info = Reader->lookupGlobalFunction(FD->getName());
+          ProcessVersionedAPINotes(*this, FD, Info);
+        }
+      }
+
+      return;
+    }
+
+    // Objective-C classes.
+    if (auto Class = dyn_cast<ObjCInterfaceDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupObjCClassInfo(Class->getName());
+        ProcessVersionedAPINotes(*this, Class, Info);
+      }
+
+      return;
+    }
+
+    // Objective-C protocols.
+    if (auto Protocol = dyn_cast<ObjCProtocolDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupObjCProtocolInfo(Protocol->getName());
+        ProcessVersionedAPINotes(*this, Protocol, Info);
+      }
+
+      return;
+    }
+
+    // Tags
+    if (auto Tag = dyn_cast<TagDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupTag(Tag->getName());
+        ProcessVersionedAPINotes(*this, Tag, Info);
+      }
+
+      return;
+    }
+
+    // Typedefs
+    if (auto Typedef = dyn_cast<TypedefNameDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupTypedef(Typedef->getName());
+        ProcessVersionedAPINotes(*this, Typedef, Info);
+      }
+
+      return;
+    }
+
+    return;
+  }
+
+  // Enumerators.
+  if (D->getDeclContext()->getRedeclContext()->isFileContext()) {
+    if (auto EnumConstant = dyn_cast<EnumConstantDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        auto Info = Reader->lookupEnumConstant(EnumConstant->getName());
+        ProcessVersionedAPINotes(*this, EnumConstant, Info);
+      }
+
+      return;
+    }
+  }
+
+  if (auto ObjCContainer = dyn_cast<ObjCContainerDecl>(D->getDeclContext())) {
+    // Location function that looks up an Objective-C context.
+    auto GetContext = [&](api_notes::APINotesReader *Reader)
+                        -> Optional<api_notes::ContextID> {
+      if (auto Protocol = dyn_cast<ObjCProtocolDecl>(ObjCContainer)) {
+        if (auto Found = Reader->lookupObjCProtocolID(Protocol->getName()))
+          return *Found;
+
+        return None;
+      }
+
+      if (auto Impl = dyn_cast<ObjCCategoryImplDecl>(ObjCContainer)) {
+        if (auto Cat = Impl->getCategoryDecl())
+          ObjCContainer = Cat;
+        else
+          return None;
+      }
+
+      if (auto Category = dyn_cast<ObjCCategoryDecl>(ObjCContainer)) {
+        if (Category->getClassInterface())
+          ObjCContainer = Category->getClassInterface();
+        else
+          return None;
+      }
+
+      if (auto Impl = dyn_cast<ObjCImplDecl>(ObjCContainer)) {
+        if (Impl->getClassInterface())
+          ObjCContainer = Impl->getClassInterface();
+        else
+          return None;
+      }
+
+      if (auto Class = dyn_cast<ObjCInterfaceDecl>(ObjCContainer)) {
+        if (auto Found = Reader->lookupObjCClassID(Class->getName()))
+          return *Found;
+
+        return None;
+
+      }
+
+      return None;
+    };
+
+    // Objective-C methods.
+    if (auto Method = dyn_cast<ObjCMethodDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        if (auto Context = GetContext(Reader)) {
+          // Map the selector.
+          Selector Sel = Method->getSelector();
+          SmallVector<StringRef, 2> SelPieces;
+          if (Sel.isUnarySelector())
+            SelPieces.push_back(Sel.getNameForSlot(0));
+          else {
+            for (unsigned i = 0, n = Sel.getNumArgs(); i != n; ++i)
+              SelPieces.push_back(Sel.getNameForSlot(i));
+          }
+
+          api_notes::ObjCSelectorRef SelectorRef;
+          SelectorRef.NumPieces = Sel.getNumArgs();
+          SelectorRef.Identifiers = SelPieces;
+
+          auto Info = Reader->lookupObjCMethod(*Context, SelectorRef,
+                                               Method->isInstanceMethod());
+          ProcessVersionedAPINotes(*this, Method, Info);
+        }
+      }
+    }
+
+    // Objective-C properties.
+    if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
+      for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
+        if (auto Context = GetContext(Reader)) {
+          bool isInstanceProperty =
+            (Property->getPropertyAttributesAsWritten() &
+               ObjCPropertyDecl::OBJC_PR_class) == 0;
+          auto Info = Reader->lookupObjCProperty(*Context, Property->getName(),
+                                                 isInstanceProperty);
+          ProcessVersionedAPINotes(*this, Property, Info);
+        }
+      }
+
+      return;
+    }
+
+    return;
+  }
+}
diff --git a/lib/Sema/SemaAttr.cpp b/lib/Sema/SemaAttr.cpp
index bad9e70..e052566 100644
--- a/lib/Sema/SemaAttr.cpp
+++ b/lib/Sema/SemaAttr.cpp
@@ -215,6 +215,7 @@
                                        ValueType Value) {
   if (Action == PSK_Reset) {
     CurrentValue = DefaultValue;
+    CurrentPragmaLocation = PragmaLocation;
     return;
   }
   if (Action & PSK_Push)
@@ -367,6 +368,219 @@
   D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
 }
 
+namespace {
+
+Optional<attr::SubjectMatchRule>
+getParentAttrMatcherRule(attr::SubjectMatchRule Rule) {
+  using namespace attr;
+  switch (Rule) {
+  default:
+    return None;
+#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
+#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated)    \
+  case Value:                                                                  \
+    return Parent;
+#include "clang/Basic/AttrSubMatchRulesList.inc"
+  }
+}
+
+bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) {
+  using namespace attr;
+  switch (Rule) {
+  default:
+    return false;
+#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
+#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated)    \
+  case Value:                                                                  \
+    return IsNegated;
+#include "clang/Basic/AttrSubMatchRulesList.inc"
+  }
+}
+
+CharSourceRange replacementRangeForListElement(const Sema &S,
+                                               SourceRange Range) {
+  // Make sure that the ',' is removed as well.
+  SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken(
+      Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(),
+      /*SkipTrailingWhitespaceAndNewLine=*/false);
+  if (AfterCommaLoc.isValid())
+    return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc);
+  else
+    return CharSourceRange::getTokenRange(Range);
+}
+
+std::string
+attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+  for (const auto &I : llvm::enumerate(Rules)) {
+    if (I.Index)
+      OS << (I.Index == Rules.size() - 1 ? ", and " : ", ");
+    OS << "'" << attr::getSubjectMatchRuleSpelling(I.Value) << "'";
+  }
+  return OS.str();
+}
+
+} // end anonymous namespace
+
+void Sema::ActOnPragmaAttributePush(AttributeList &Attribute,
+                                    SourceLocation PragmaLoc,
+                                    attr::ParsedSubjectMatchRuleSet Rules) {
+  SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules;
+  // Gather the subject match rules that are supported by the attribute.
+  SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4>
+      StrictSubjectMatchRuleSet;
+  Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet);
+
+  // Figure out which subject matching rules are valid.
+  if (StrictSubjectMatchRuleSet.empty()) {
+    // Check for contradicting match rules. Contradicting match rules are
+    // either:
+    //  - a top-level rule and one of its sub-rules. E.g. variable and
+    //    variable(is_parameter).
+    //  - a sub-rule and a sibling that's negated. E.g.
+    //    variable(is_thread_local) and variable(unless(is_parameter))
+    llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2>
+        RulesToFirstSpecifiedNegatedSubRule;
+    for (const auto &Rule : Rules) {
+      attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
+      Optional<attr::SubjectMatchRule> ParentRule =
+          getParentAttrMatcherRule(MatchRule);
+      if (!ParentRule)
+        continue;
+      auto It = Rules.find(*ParentRule);
+      if (It != Rules.end()) {
+        // A sub-rule contradicts a parent rule.
+        Diag(Rule.second.getBegin(),
+             diag::err_pragma_attribute_matcher_subrule_contradicts_rule)
+            << attr::getSubjectMatchRuleSpelling(MatchRule)
+            << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second
+            << FixItHint::CreateRemoval(
+                   replacementRangeForListElement(*this, Rule.second));
+        // Keep going without removing this rule as it won't change the set of
+        // declarations that receive the attribute.
+        continue;
+      }
+      if (isNegatedAttrMatcherSubRule(MatchRule))
+        RulesToFirstSpecifiedNegatedSubRule.insert(
+            std::make_pair(*ParentRule, Rule));
+    }
+    bool IgnoreNegatedSubRules = false;
+    for (const auto &Rule : Rules) {
+      attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
+      Optional<attr::SubjectMatchRule> ParentRule =
+          getParentAttrMatcherRule(MatchRule);
+      if (!ParentRule)
+        continue;
+      auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule);
+      if (It != RulesToFirstSpecifiedNegatedSubRule.end() &&
+          It->second != Rule) {
+        // Negated sub-rule contradicts another sub-rule.
+        Diag(
+            It->second.second.getBegin(),
+            diag::
+                err_pragma_attribute_matcher_negated_subrule_contradicts_subrule)
+            << attr::getSubjectMatchRuleSpelling(
+                   attr::SubjectMatchRule(It->second.first))
+            << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second
+            << FixItHint::CreateRemoval(
+                   replacementRangeForListElement(*this, It->second.second));
+        // Keep going but ignore all of the negated sub-rules.
+        IgnoreNegatedSubRules = true;
+        RulesToFirstSpecifiedNegatedSubRule.erase(It);
+      }
+    }
+
+    if (!IgnoreNegatedSubRules) {
+      for (const auto &Rule : Rules)
+        SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
+    } else {
+      for (const auto &Rule : Rules) {
+        if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first)))
+          SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
+      }
+    }
+    Rules.clear();
+  } else {
+    for (const auto &Rule : StrictSubjectMatchRuleSet) {
+      if (Rules.erase(Rule.first)) {
+        // Add the rule to the set of attribute receivers only if it's supported
+        // in the current language mode.
+        if (Rule.second)
+          SubjectMatchRules.push_back(Rule.first);
+      }
+    }
+  }
+
+  if (!Rules.empty()) {
+    auto Diagnostic =
+        Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers)
+        << Attribute.getName();
+    SmallVector<attr::SubjectMatchRule, 2> ExtraRules;
+    for (const auto &Rule : Rules) {
+      ExtraRules.push_back(attr::SubjectMatchRule(Rule.first));
+      Diagnostic << FixItHint::CreateRemoval(
+          replacementRangeForListElement(*this, Rule.second));
+    }
+    Diagnostic << attrMatcherRuleListToString(ExtraRules);
+  }
+
+  PragmaAttributeStack.push_back(
+      {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
+}
+
+void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc) {
+  if (PragmaAttributeStack.empty()) {
+    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch);
+    return;
+  }
+  const PragmaAttributeEntry &Entry = PragmaAttributeStack.back();
+  if (!Entry.IsUsed) {
+    assert(Entry.Attribute && "Expected an attribute");
+    Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
+        << Entry.Attribute->getName();
+    Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
+  }
+  PragmaAttributeStack.pop_back();
+}
+
+void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
+  if (PragmaAttributeStack.empty())
+    return;
+  for (auto &Entry : PragmaAttributeStack) {
+    const AttributeList *Attribute = Entry.Attribute;
+    assert(Attribute && "Expected an attribute");
+
+    // Ensure that the attribute can be applied to the given declaration.
+    bool Applies = false;
+    for (const auto &Rule : Entry.MatchRules) {
+      if (Attribute->appliesToDecl(D, Rule)) {
+        Applies = true;
+        break;
+      }
+    }
+    if (!Applies)
+      continue;
+    Entry.IsUsed = true;
+    assert(!Attribute->getNext() && "Expected just one attribute");
+    PragmaAttributeCurrentTargetDecl = D;
+    ProcessDeclAttributeList(S, D, Attribute);
+    PragmaAttributeCurrentTargetDecl = nullptr;
+  }
+}
+
+void Sema::PrintPragmaAttributeInstantiationPoint() {
+  assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
+  Diags.Report(PragmaAttributeCurrentTargetDecl->getLocStart(),
+               diag::note_pragma_attribute_applied_decl_here);
+}
+
+void Sema::DiagnoseUnterminatedPragmaAttribute() {
+  if (PragmaAttributeStack.empty())
+    return;
+  Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof);
+}
+
 void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
   if(On)
     OptimizeOffPragmaLocation = SourceLocation();
@@ -447,16 +661,16 @@
   }
 }
 
-void Sema::ActOnPragmaFPContract(tok::OnOffSwitch OOS) {
-  switch (OOS) {
-  case tok::OOS_ON:
-    FPFeatures.fp_contract = 1;
+void Sema::ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC) {
+  switch (FPC) {
+  case LangOptions::FPC_On:
+    FPFeatures.setAllowFPContractWithinStatement();
     break;
-  case tok::OOS_OFF:
-    FPFeatures.fp_contract = 0; 
+  case LangOptions::FPC_Fast:
+    FPFeatures.setAllowFPContractAcrossStatement();
     break;
-  case tok::OOS_DEFAULT:
-    FPFeatures.fp_contract = getLangOpts().DefaultFPContract;
+  case LangOptions::FPC_Off:
+    FPFeatures.setDisallowFPContract();
     break;
   }
 }
diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp
index d8971c0..244675a 100644
--- a/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/lib/Sema/SemaCXXScopeSpec.cpp
@@ -480,6 +480,8 @@
                                        NamedDecl *ScopeLookupResult,
                                        bool ErrorRecoveryLookup,
                                        bool *IsCorrectedToColon) {
+  if (IdInfo.Identifier->isEditorPlaceholder())
+    return true;
   LookupResult Found(*this, IdInfo.Identifier, IdInfo.IdentifierLoc,
                      LookupNestedNameSpecifierName);
   QualType ObjectType = GetTypeFromParser(IdInfo.ObjectType);
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index 6222e4c..7fd5874 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -120,12 +120,12 @@
       Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);
     }
 
-    void checkObjCARCConversion(Sema::CheckedConversionKind CCK) {
-      assert(Self.getLangOpts().ObjCAutoRefCount);
+    void checkObjCConversion(Sema::CheckedConversionKind CCK) {
+      assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());
 
       Expr *src = SrcExpr.get();
-      if (Self.CheckObjCARCConversion(OpRange, DestType, src, CCK) ==
-            Sema::ACR_unbridged)
+      if (Self.CheckObjCConversion(OpRange, DestType, src, CCK) ==
+          Sema::ACR_unbridged)
         IsARCUnbridgedCast = true;
       SrcExpr = src;
     }
@@ -871,8 +871,8 @@
     }
     SrcExpr = ExprError();
   } else if (tcr == TC_Success) {
-    if (Self.getLangOpts().ObjCAutoRefCount)
-      checkObjCARCConversion(Sema::CCK_OtherCast);
+    if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
+      checkObjCConversion(Sema::CCK_OtherCast);
     DiagnoseReinterpretUpDownCast(Self, SrcExpr.get(), DestType, OpRange);
   }
 }
@@ -935,8 +935,8 @@
   } else if (tcr == TC_Success) {
     if (Kind == CK_BitCast)
       checkCastAlign();
-    if (Self.getLangOpts().ObjCAutoRefCount)
-      checkObjCARCConversion(Sema::CCK_OtherCast);
+    if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
+      checkObjCConversion(Sema::CCK_OtherCast);
   } else if (Kind == CK_BitCast) {
     checkCastAlign();
   }
@@ -2273,8 +2273,9 @@
     }
   }
 
-  if (Self.getLangOpts().ObjCAutoRefCount && tcr == TC_Success)
-    checkObjCARCConversion(CCK);
+  if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
+      tcr == TC_Success)
+    checkObjCConversion(CCK);
 
   if (tcr != TC_Success && msg != 0) {
     if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {
@@ -2540,12 +2541,13 @@
   }
 
   // ARC imposes extra restrictions on casts.
-  if (Self.getLangOpts().ObjCAutoRefCount) {
-    checkObjCARCConversion(Sema::CCK_CStyleCast);
+  if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {
+    checkObjCConversion(Sema::CCK_CStyleCast);
     if (SrcExpr.isInvalid())
       return;
-    
-    if (const PointerType *CastPtr = DestType->getAs<PointerType>()) {
+
+    const PointerType *CastPtr = DestType->getAs<PointerType>();
+    if (Self.getLangOpts().ObjCAutoRefCount && CastPtr) {
       if (const PointerType *ExprPtr = SrcType->getAs<PointerType>()) {
         Qualifiers CastQuals = CastPtr->getPointeeType().getQualifiers();
         Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 3aedb2a..2565f0c 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -4623,20 +4623,6 @@
 
     return SLCT_NotALiteral;
   }
-  case Stmt::ObjCMessageExprClass: {
-    const auto *ME = cast<ObjCMessageExpr>(E);
-    if (const auto *ND = ME->getMethodDecl()) {
-      if (const auto *FA = ND->getAttr<FormatArgAttr>()) {
-        unsigned ArgIndex = FA->getFormatIdx();
-        const Expr *Arg = ME->getArg(ArgIndex - 1);
-        return checkFormatStringExpr(
-            S, Arg, Args, HasVAListArg, format_idx, firstDataArg, Type,
-            CallType, InFunctionCall, CheckedVarArgs, UncoveredArg, Offset);
-      }
-    }
-
-    return SLCT_NotALiteral;
-  }
   case Stmt::ObjCStringLiteralClass:
   case Stmt::StringLiteralClass: {
     const StringLiteral *StrE = nullptr;
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 94cfc4b..9030d02 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -1334,8 +1334,9 @@
       Builder.AddChunk(CodeCompletionString::CK_RightParen);
       Results.AddResult(Result(Builder.TakeString()));
     }
-  }
-  
+  } else
+    Results.AddResult(Result("__auto_type", CCP_Type));
+
   // GNU extensions
   if (LangOpts.GNUMode) {
     // FIXME: Enable when we actually support decimal floating point.
@@ -1370,6 +1371,21 @@
   // in C++0x as a type specifier.
   Results.AddResult(Result("extern"));
   Results.AddResult(Result("static"));
+
+  if (LangOpts.CPlusPlus11) {
+    CodeCompletionAllocator &Allocator = Results.getAllocator();
+    CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());
+
+    // alignas
+    Builder.AddTypedTextChunk("alignas");
+    Builder.AddChunk(CodeCompletionString::CK_LeftParen);
+    Builder.AddPlaceholderChunk("expression");
+    Builder.AddChunk(CodeCompletionString::CK_RightParen);
+    Results.AddResult(Result(Builder.TakeString()));
+
+    Results.AddResult(Result("constexpr"));
+    Results.AddResult(Result("thread_local"));
+  }
 }
 
 static void AddFunctionSpecifiers(Sema::ParserCompletionContext CCC,
@@ -1527,6 +1543,21 @@
   Results.AddResult(CodeCompletionResult(Builder.TakeString()));
 }
 
+static void AddStaticAssertResult(CodeCompletionBuilder &Builder,
+                                  ResultBuilder &Results,
+                                  const LangOptions &LangOpts) {
+  if (!LangOpts.CPlusPlus11)
+    return;
+
+  Builder.AddTypedTextChunk("static_assert");
+  Builder.AddChunk(CodeCompletionString::CK_LeftParen);
+  Builder.AddPlaceholderChunk("expression");
+  Builder.AddChunk(CodeCompletionString::CK_Comma);
+  Builder.AddPlaceholderChunk("message");
+  Builder.AddChunk(CodeCompletionString::CK_RightParen);
+  Results.AddResult(CodeCompletionResult(Builder.TakeString()));
+}
+
 /// \brief Add language constructs that show up for "ordinary" names.
 static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
                                    Scope *S,
@@ -1611,6 +1642,8 @@
         Results.AddResult(Result(Builder.TakeString()));
       }
 
+      AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
+
       if (CCC == Sema::PCC_Class) {
         AddTypedefResult(Results);
 
@@ -1824,6 +1857,8 @@
     Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
     Builder.AddPlaceholderChunk("identifier");
     Results.AddResult(Result(Builder.TakeString()));
+
+    AddStaticAssertResult(Builder, Results, SemaRef.getLangOpts());
   }
 
   // Fall through (for statement expressions).
@@ -2253,6 +2288,15 @@
   FunctionProtoTypeLoc BlockProto;
   findTypeLocationForBlockDecl(Param->getTypeSourceInfo(), Block, BlockProto,
                                SuppressBlock);
+  // Try to retrieve the block type information from the property if this is a
+  // parameter in a setter.
+  if (!Block && ObjCMethodParam &&
+      cast<ObjCMethodDecl>(Param->getDeclContext())->isPropertyAccessor()) {
+    if (const auto *PD = cast<ObjCMethodDecl>(Param->getDeclContext())
+                             ->findPropertyDecl(/*CheckOverrides=*/false))
+      findTypeLocationForBlockDecl(PD->getTypeSourceInfo(), Block, BlockProto,
+                                   SuppressBlock);
+  }
 
   if (!Block) {
     // We were unable to find a FunctionProtoTypeLoc with parameter names
@@ -3482,6 +3526,11 @@
     Results.AddResult(Result("restrict"));
 
   if (getLangOpts().CPlusPlus) {
+    if (getLangOpts().CPlusPlus11 &&
+        (DS.getTypeSpecType() == DeclSpec::TST_class ||
+         DS.getTypeSpecType() == DeclSpec::TST_struct))
+      Results.AddResult("final");
+
     if (AllowNonIdentifiers) {
       Results.AddResult(Result("operator")); 
     }
@@ -3819,6 +3868,41 @@
   }
 }
 
+static void AddRecordMembersCompletionResults(Sema &SemaRef,
+                                              ResultBuilder &Results, Scope *S,
+                                              QualType BaseType,
+                                              RecordDecl *RD) {
+  // Indicate that we are performing a member access, and the cv-qualifiers
+  // for the base object type.
+  Results.setObjectTypeQualifiers(BaseType.getQualifiers());
+
+  // Access to a C/C++ class, struct, or union.
+  Results.allowNestedNameSpecifiers();
+  CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
+  SemaRef.LookupVisibleDecls(RD, Sema::LookupMemberName, Consumer,
+                             SemaRef.CodeCompleter->includeGlobals(),
+                             /*IncludeDependentBases=*/true);
+
+  if (SemaRef.getLangOpts().CPlusPlus) {
+    if (!Results.empty()) {
+      // The "template" keyword can follow "->" or "." in the grammar.
+      // However, we only want to suggest the template keyword if something
+      // is dependent.
+      bool IsDependent = BaseType->isDependentType();
+      if (!IsDependent) {
+        for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
+          if (DeclContext *Ctx = DepScope->getEntity()) {
+            IsDependent = Ctx->isDependentContext();
+            break;
+          }
+      }
+
+      if (IsDependent)
+        Results.AddResult(CodeCompletionResult("template"));
+    }
+  }
+}
+
 void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
                                            SourceLocation OpLoc, bool IsArrow,
                                            bool IsBaseExprStatement) {
@@ -3829,8 +3913,6 @@
   if (ConvertedBase.isInvalid())
     return;
   Base = ConvertedBase.get();
-
-  typedef CodeCompletionResult Result;
   
   QualType BaseType = Base->getType();
 
@@ -3865,34 +3947,18 @@
                         &ResultBuilder::IsMember);
   Results.EnterNewScope();
   if (const RecordType *Record = BaseType->getAs<RecordType>()) {
-    // Indicate that we are performing a member access, and the cv-qualifiers
-    // for the base object type.
-    Results.setObjectTypeQualifiers(BaseType.getQualifiers());
-    
-    // Access to a C/C++ class, struct, or union.
-    Results.allowNestedNameSpecifiers();
-    CodeCompletionDeclConsumer Consumer(Results, CurContext);
-    LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
-                       CodeCompleter->includeGlobals());
-
-    if (getLangOpts().CPlusPlus) {
-      if (!Results.empty()) {
-        // The "template" keyword can follow "->" or "." in the grammar.
-        // However, we only want to suggest the template keyword if something
-        // is dependent.
-        bool IsDependent = BaseType->isDependentType();
-        if (!IsDependent) {
-          for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
-            if (DeclContext *Ctx = DepScope->getEntity()) {
-              IsDependent = Ctx->isDependentContext();
-              break;
-            }
-        }
-
-        if (IsDependent)
-          Results.AddResult(Result("template"));
-      }
+    AddRecordMembersCompletionResults(*this, Results, S, BaseType,
+                                      Record->getDecl());
+  } else if (const auto *TST = BaseType->getAs<TemplateSpecializationType>()) {
+    TemplateName TN = TST->getTemplateName();
+    if (const auto *TD =
+            dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl())) {
+      CXXRecordDecl *RD = TD->getTemplatedDecl();
+      AddRecordMembersCompletionResults(*this, Results, S, BaseType, RD);
     }
+  } else if (const auto *ICNT = BaseType->getAs<InjectedClassNameType>()) {
+    if (auto *RD = ICNT->getDecl())
+      AddRecordMembersCompletionResults(*this, Results, S, BaseType, RD);
   } else if (!IsArrow && BaseType->isObjCObjectPointerType()) {
     // Objective-C property reference.
     AddedPropertiesSet AddedProperties;
@@ -4012,30 +4078,54 @@
                             Results.data(),Results.size());
 }
 
+static void AddTypeQualifierResults(DeclSpec &DS, ResultBuilder &Results,
+                                    const LangOptions &LangOpts) {
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
+    Results.AddResult("const");
+  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
+    Results.AddResult("volatile");
+  if (LangOpts.C99 && !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
+    Results.AddResult("restrict");
+  if (LangOpts.C11 && !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
+    Results.AddResult("_Atomic");
+  if (LangOpts.MSVCCompat && !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
+    Results.AddResult("__unaligned");
+}
+
 void Sema::CodeCompleteTypeQualifiers(DeclSpec &DS) {
   ResultBuilder Results(*this, CodeCompleter->getAllocator(),
                         CodeCompleter->getCodeCompletionTUInfo(),
                         CodeCompletionContext::CCC_TypeQualifiers);
   Results.EnterNewScope();
-  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_const))
-    Results.AddResult("const");
-  if (!(DS.getTypeQualifiers() & DeclSpec::TQ_volatile))
-    Results.AddResult("volatile");
-  if (getLangOpts().C99 &&
-      !(DS.getTypeQualifiers() & DeclSpec::TQ_restrict))
-    Results.AddResult("restrict");
-  if (getLangOpts().C11 &&
-      !(DS.getTypeQualifiers() & DeclSpec::TQ_atomic))
-    Results.AddResult("_Atomic");
-  if (getLangOpts().MSVCCompat &&
-      !(DS.getTypeQualifiers() & DeclSpec::TQ_unaligned))
-    Results.AddResult("__unaligned");
+  AddTypeQualifierResults(DS, Results, LangOpts);
   Results.ExitScope();
   HandleCodeCompleteResults(this, CodeCompleter, 
                             Results.getCompletionContext(),
                             Results.data(), Results.size());
 }
 
+void Sema::CodeCompleteFunctionQualifiers(DeclSpec &DS, Declarator &D,
+                                          const VirtSpecifiers *VS) {
+  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
+                        CodeCompletionContext::CCC_TypeQualifiers);
+  Results.EnterNewScope();
+  AddTypeQualifierResults(DS, Results, LangOpts);
+  if (LangOpts.CPlusPlus11) {
+    Results.AddResult("noexcept");
+    if (D.getContext() == Declarator::MemberContext && !D.isCtorOrDtor() &&
+        !D.isStaticMember()) {
+      if (!VS || !VS->isFinalSpecified())
+        Results.AddResult("final");
+      if (!VS || !VS->isOverrideSpecified())
+        Results.AddResult("override");
+    }
+  }
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter, Results.getCompletionContext(),
+                            Results.data(), Results.size());
+}
+
 void Sema::CodeCompleteBracketDeclarator(Scope *S) {
   CodeCompleteExpression(S, QualType(getASTContext().getSizeType()));
 }
@@ -4244,7 +4334,10 @@
       UME->copyTemplateArgumentsInto(TemplateArgsBuffer);
       TemplateArgs = &TemplateArgsBuffer;
     }
-    SmallVector<Expr *, 12> ArgExprs(1, UME->getBase());
+
+    // Add the base as first argument (use a nullptr if the base is implicit).
+    SmallVector<Expr *, 12> ArgExprs(
+        1, UME->isImplicitAccess() ? nullptr : UME->getBase());
     ArgExprs.append(Args.begin(), Args.end());
     UnresolvedSet<8> Decls;
     Decls.append(UME->decls_begin(), UME->decls_end());
@@ -5230,24 +5323,22 @@
 /// when it has the same number of parameters as we have selector identifiers.
 ///
 /// \param Results the structure into which we'll add results.
-static void AddObjCMethods(ObjCContainerDecl *Container, 
-                           bool WantInstanceMethods,
-                           ObjCMethodKind WantKind,
+static void AddObjCMethods(ObjCContainerDecl *Container,
+                           bool WantInstanceMethods, ObjCMethodKind WantKind,
                            ArrayRef<IdentifierInfo *> SelIdents,
                            DeclContext *CurContext,
-                           VisitedSelectorSet &Selectors,
-                           bool AllowSameLength,
-                           ResultBuilder &Results,
-                           bool InOriginalClass = true) {
+                           VisitedSelectorSet &Selectors, bool AllowSameLength,
+                           ResultBuilder &Results, bool InOriginalClass = true,
+                           bool IsRootClass = false) {
   typedef CodeCompletionResult Result;
   Container = getContainerDef(Container);
   ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
-  bool isRootClass = IFace && !IFace->getSuperClass();
+  IsRootClass = IsRootClass || (IFace && !IFace->getSuperClass());
   for (auto *M : Container->methods()) {
     // The instance methods on the root class can be messaged via the
     // metaclass.
     if (M->isInstanceMethod() == WantInstanceMethods ||
-        (isRootClass && !WantInstanceMethods)) {
+        (IsRootClass && !WantInstanceMethods)) {
       // Check whether the selector identifiers we've been given are a 
       // subset of the identifiers for this particular method.
       if (!isAcceptableObjCMethod(M, WantKind, SelIdents, AllowSameLength))
@@ -5273,8 +5364,8 @@
       for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
                                                 E = Protocols.end(); 
            I != E; ++I)
-        AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 
-                       CurContext, Selectors, AllowSameLength, Results, false);
+        AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                       Selectors, AllowSameLength, Results, false, IsRootClass);
     }
   }
   
@@ -5283,43 +5374,43 @@
   
   // Add methods in protocols.
   for (auto *I : IFace->protocols())
-    AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents,
-                   CurContext, Selectors, AllowSameLength, Results, false);
-  
+    AddObjCMethods(I, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                   Selectors, AllowSameLength, Results, false, IsRootClass);
+
   // Add methods in categories.
   for (auto *CatDecl : IFace->known_categories()) {
     AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
-                   CurContext, Selectors, AllowSameLength,
-                   Results, InOriginalClass);
-    
+                   CurContext, Selectors, AllowSameLength, Results,
+                   InOriginalClass, IsRootClass);
+
     // Add a categories protocol methods.
     const ObjCList<ObjCProtocolDecl> &Protocols 
       = CatDecl->getReferencedProtocols();
     for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
                                               E = Protocols.end();
          I != E; ++I)
-      AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, 
-                     CurContext, Selectors, AllowSameLength,
-                     Results, false);
-    
+      AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                     Selectors, AllowSameLength, Results, false, IsRootClass);
+
     // Add methods in category implementations.
     if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
-      AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, 
-                     CurContext, Selectors, AllowSameLength,
-                     Results, InOriginalClass);
+      AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                     Selectors, AllowSameLength, Results, InOriginalClass,
+                     IsRootClass);
   }
   
   // Add methods in superclass.
+  // Avoid passing in IsRootClass since root classes won't have super classes.
   if (IFace->getSuperClass())
-    AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind, 
-                   SelIdents, CurContext, Selectors,
-                   AllowSameLength, Results, false);
+    AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
+                   SelIdents, CurContext, Selectors, AllowSameLength, Results,
+                   /*IsRootClass=*/false);
 
   // Add methods in our implementation, if any.
   if (ObjCImplementationDecl *Impl = IFace->getImplementation())
-    AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
-                   CurContext, Selectors, AllowSameLength,
-                   Results, InOriginalClass);
+    AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents, CurContext,
+                   Selectors, AllowSameLength, Results, InOriginalClass,
+                   IsRootClass);
 }
 
 
@@ -7736,6 +7827,23 @@
                             nullptr, 0);
 }
 
+void Sema::CodeCompleteAvailabilityPlatformName() {
+  ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+                        CodeCompleter->getCodeCompletionTUInfo(),
+                        CodeCompletionContext::CCC_Other);
+  Results.EnterNewScope();
+  static const char *Platforms[] = {"macOS", "iOS", "watchOS", "tvOS"};
+  for (const char *Platform : llvm::makeArrayRef(Platforms)) {
+    Results.AddResult(CodeCompletionResult(Platform));
+    Results.AddResult(CodeCompletionResult(Results.getAllocator().CopyString(
+        Twine(Platform) + "ApplicationExtension")));
+  }
+  Results.ExitScope();
+  HandleCodeCompleteResults(this, CodeCompleter,
+                            CodeCompletionContext::CCC_Other, Results.data(),
+                            Results.size());
+}
+
 void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
                                        CodeCompletionTUInfo &CCTUInfo,
                  SmallVectorImpl<CodeCompletionResult> &Results) {
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index adcf2ee..efae641 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -589,7 +589,7 @@
 
     CXXRecordDecl *RD = cast<CXXRecordDecl>(CurContext);
     for (const auto &Base : RD->bases())
-      if (Context.hasSameUnqualifiedType(QualType(Ty, 1), Base.getType()))
+      if (Ty && Context.hasSameUnqualifiedType(QualType(Ty, 1), Base.getType()))
         return true;
     return S->isFunctionPrototypeScope();
   }
@@ -602,6 +602,9 @@
                                    CXXScopeSpec *SS,
                                    ParsedType &SuggestedType,
                                    bool AllowClassTemplates) {
+  // Don't report typename errors for editor placeholders.
+  if (II->isEditorPlaceholder())
+    return;
   // We don't have anything to suggest (yet).
   SuggestedType = nullptr;
 
@@ -1916,7 +1919,7 @@
     Diag(New->getLocation(), diag::err_redefinition_variably_modified_typedef)
       << Kind << NewType;
     if (Old->getLocation().isValid())
-      Diag(Old->getLocation(), diag::note_previous_definition);
+      notePreviousDefinition(Old->getLocation(), New->getLocation());
     New->setInvalidDecl();
     return true;
   }
@@ -1929,7 +1932,7 @@
     Diag(New->getLocation(), diag::err_redefinition_different_typedef)
       << Kind << NewType << OldType;
     if (Old->getLocation().isValid())
-      Diag(Old->getLocation(), diag::note_previous_definition);
+      notePreviousDefinition(Old->getLocation(), New->getLocation());
     New->setInvalidDecl();
     return true;
   }
@@ -1996,7 +1999,7 @@
 
     NamedDecl *OldD = OldDecls.getRepresentativeDecl();
     if (OldD->getLocation().isValid())
-      Diag(OldD->getLocation(), diag::note_previous_definition);
+      notePreviousDefinition(OldD->getLocation(), New->getLocation());
 
     return New->setInvalidDecl();
   }
@@ -2088,7 +2091,7 @@
 
     Diag(New->getLocation(), diag::err_redefinition)
       << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    notePreviousDefinition(Old->getLocation(), New->getLocation());
     return New->setInvalidDecl();
   }
 
@@ -2107,7 +2110,7 @@
 
   Diag(New->getLocation(), diag::ext_redefinition_of_typedef)
     << New->getDeclName();
-  Diag(Old->getLocation(), diag::note_previous_definition);
+  notePreviousDefinition(Old->getLocation(), New->getLocation());
 }
 
 /// DeclhasAttr - returns true if decl Declaration already has the target
@@ -2307,6 +2310,10 @@
     NewAttr = S.mergeMinSizeAttr(D, MA->getRange(), AttrSpellingListIndex);
   else if (const auto *OA = dyn_cast<OptimizeNoneAttr>(Attr))
     NewAttr = S.mergeOptimizeNoneAttr(D, OA->getRange(), AttrSpellingListIndex);
+  else if (const auto *SNA = dyn_cast<SwiftNameAttr>(Attr))
+    NewAttr = S.mergeSwiftNameAttr(D, SNA->getRange(), SNA->getName(),
+                                   AMK == Sema::AMK_Override,
+                                   AttrSpellingListIndex);
   else if (const auto *InternalLinkageA = dyn_cast<InternalLinkageAttr>(Attr))
     NewAttr = S.mergeInternalLinkageAttr(
         D, InternalLinkageA->getRange(),
@@ -2324,6 +2331,8 @@
            (AMK == Sema::AMK_Override ||
             AMK == Sema::AMK_ProtocolImplementation))
     NewAttr = nullptr;
+  else if (isa<SwiftPrivateAttr>(Attr) && AMK == Sema::AMK_Override)
+    NewAttr = nullptr;
   else if (const auto *UA = dyn_cast<UuidAttr>(Attr))
     NewAttr = S.mergeUuidAttr(D, UA->getRange(), AttrSpellingListIndex,
                               UA->getGuid());
@@ -2394,7 +2403,10 @@
                             ? diag::err_alias_after_tentative
                             : diag::err_redefinition;
         S.Diag(VD->getLocation(), Diag) << VD->getDeclName();
-        S.Diag(Def->getLocation(), diag::note_previous_definition);
+        if (Diag == diag::err_redefinition)
+          S.notePreviousDefinition(Def->getLocation(), VD->getLocation());
+        else
+          S.Diag(Def->getLocation(), diag::note_previous_definition);
         VD->setInvalidDecl();
       }
       ++I;
@@ -2781,7 +2793,7 @@
     } else {
       Diag(New->getLocation(), diag::err_redefinition_different_kind)
         << New->getDeclName();
-      Diag(OldD->getLocation(), diag::note_previous_definition);
+      notePreviousDefinition(OldD->getLocation(), New->getLocation());
       return true;
     }
   }
@@ -2818,7 +2830,7 @@
       !Old->hasAttr<InternalLinkageAttr>()) {
     Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
         << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    notePreviousDefinition(Old->getLocation(), New->getLocation());
     New->dropAttr<InternalLinkageAttr>();
   }
 
@@ -3532,8 +3544,8 @@
   if (!Old) {
     Diag(New->getLocation(), diag::err_redefinition_different_kind)
       << New->getDeclName();
-    Diag(Previous.getRepresentativeDecl()->getLocation(),
-         diag::note_previous_definition);
+    notePreviousDefinition(Previous.getRepresentativeDecl()->getLocation(),
+                         New->getLocation());
     return New->setInvalidDecl();
   }
 
@@ -3562,7 +3574,7 @@
       Old->getStorageClass() == SC_None &&
       !Old->hasAttr<WeakImportAttr>()) {
     Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    notePreviousDefinition(Old->getLocation(), New->getLocation());
     // Remove weak_import attribute on new declaration.
     New->dropAttr<WeakImportAttr>();
   }
@@ -3571,7 +3583,7 @@
       !Old->hasAttr<InternalLinkageAttr>()) {
     Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
         << New->getDeclName();
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    notePreviousDefinition(Old->getLocation(), New->getLocation());
     New->dropAttr<InternalLinkageAttr>();
   }
 
@@ -3728,6 +3740,67 @@
     New->setImplicitlyInline();
 }
 
+void Sema::notePreviousDefinition(SourceLocation Old, SourceLocation New) {
+  SourceManager &SrcMgr = getSourceManager();
+  auto FNewDecLoc = SrcMgr.getDecomposedLoc(New);
+  auto FOldDecLoc = SrcMgr.getDecomposedLoc(Old);
+  auto *FNew = SrcMgr.getFileEntryForID(FNewDecLoc.first);
+  auto *FOld = SrcMgr.getFileEntryForID(FOldDecLoc.first);
+  auto &HSI = PP.getHeaderSearchInfo();
+  StringRef HdrFilename = SrcMgr.getFilename(SrcMgr.getSpellingLoc(Old));
+
+  auto noteFromModuleOrInclude = [&](SourceLocation &Loc,
+                                     SourceLocation &IncLoc) -> bool {
+    Module *Mod = nullptr;
+    // Redefinition errors with modules are common with non modular mapped
+    // headers, example: a non-modular header H in module A that also gets
+    // included directly in a TU. Pointing twice to the same header/definition
+    // is confusing, try to get better diagnostics when modules is on.
+    if (getLangOpts().Modules) {
+      auto ModLoc = SrcMgr.getModuleImportLoc(Old);
+      if (!ModLoc.first.isInvalid())
+        Mod = HSI.getModuleMap().inferModuleFromLocation(
+            FullSourceLoc(Loc, SrcMgr));
+    }
+
+    if (!IncLoc.isInvalid()) {
+      if (Mod) {
+        Diag(IncLoc, diag::note_redefinition_modules_same_file)
+            << HdrFilename.str() << Mod->getFullModuleName();
+        if (!Mod->DefinitionLoc.isInvalid())
+          Diag(Mod->DefinitionLoc, diag::note_defined_here)
+              << Mod->getFullModuleName();
+      } else {
+        Diag(IncLoc, diag::note_redefinition_include_same_file)
+            << HdrFilename.str();
+      }
+      return true;
+    }
+
+    return false;
+  };
+
+  // Is it the same file and same offset? Provide more information on why
+  // this leads to a redefinition error.
+  bool EmittedDiag = false;
+  if (FOld && FNew == FOld && FNewDecLoc.second == FOldDecLoc.second) {
+    SourceLocation OldIncLoc = SrcMgr.getIncludeLoc(FOldDecLoc.first);
+    SourceLocation NewIncLoc = SrcMgr.getIncludeLoc(FNewDecLoc.first);
+    EmittedDiag = noteFromModuleOrInclude(Old, OldIncLoc);
+    EmittedDiag |= noteFromModuleOrInclude(New, NewIncLoc);
+
+    // If the header has no guards, emit a note suggesting one.
+    if (!HSI.isFileMultipleIncludeGuarded(FOld))
+      Diag(Old, diag::note_use_ifdef_guards);
+
+    if (EmittedDiag)
+      return;
+  }
+
+  // Redefinition coming from different files or couldn't do better above.
+  Diag(Old, diag::note_previous_definition);
+}
+
 /// We've just determined that \p Old and \p New both appear to be definitions
 /// of the same variable. Either diagnose or fix the problem.
 bool Sema::checkVarDeclRedefinition(VarDecl *Old, VarDecl *New) {
@@ -3748,7 +3821,7 @@
     return false;
   } else {
     Diag(New->getLocation(), diag::err_redefinition) << New;
-    Diag(Old->getLocation(), diag::note_previous_definition);
+    notePreviousDefinition(Old->getLocation(), New->getLocation());
     New->setInvalidDecl();
     return true;
   }
@@ -7273,6 +7346,10 @@
 
 } // end anonymous namespace
 
+void Sema::MarkTypoCorrectedFunctionDefinition(const NamedDecl *F) {
+  TypoCorrectedFunctionDefinitions.insert(F);
+}
+
 /// \brief Generate diagnostics for an invalid function redeclaration.
 ///
 /// This routine handles generating the diagnostic messages for an invalid
@@ -7370,6 +7447,8 @@
         if ((*I)->getCanonicalDecl() == Canonical)
           Correction.setCorrectionDecl(*I);
 
+      // Let Sema know about the correction.
+      SemaRef.MarkTypoCorrectedFunctionDefinition(Result);
       SemaRef.diagnoseTypo(
           Correction,
           SemaRef.PDiag(IsLocalFriend
@@ -7472,11 +7551,12 @@
     // Determine whether the function was written with a
     // prototype. This true when:
     //   - there is a prototype in the declarator, or
-    //   - the type R of the function is some kind of typedef or other reference
-    //     to a type name (which eventually refers to a function type).
+    //   - the type R of the function is some kind of typedef or other non-
+    //     attributed reference to a type name (which eventually refers to a
+    //     function type).
     bool HasPrototype =
       (D.isFunctionDeclarator() && D.getFunctionTypeInfo().hasPrototype) ||
-      (!isa<FunctionType>(R.getTypePtr()) && R->isFunctionProtoType());
+      (!R->getAsAdjusted<FunctionType>() && R->isFunctionProtoType());
 
     NewFD = FunctionDecl::Create(SemaRef.Context, DC,
                                  D.getLocStart(), NameInfo, R,
@@ -10047,7 +10127,8 @@
     // we do not warn to warn spuriously when 'x' and 'y' are on separate
     // paths through the function. This should be revisited if
     // -Wrepeated-use-of-weak is made flow-sensitive.
-    if (VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong &&
+    if ((VDecl->getType().getObjCLifetime() == Qualifiers::OCL_Strong ||
+         VDecl->getType().isNonWeakInMRRWithObjCWeak(Context)) &&
         !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
                          Init->getLocStart()))
       getCurFunction()->markSafeWeakUse(Init);
@@ -11370,10 +11451,8 @@
   }
 }
 
-ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
-                                  SourceLocation NameLoc, IdentifierInfo *Name,
-                                  QualType T, TypeSourceInfo *TSInfo,
-                                  StorageClass SC) {
+QualType Sema::adjustParameterTypeForObjCAutoRefCount(QualType T,
+                                                      SourceLocation Loc) {
   // In ARC, infer a lifetime qualifier for appropriate parameter types.
   if (getLangOpts().ObjCAutoRefCount &&
       T.getObjCLifetime() == Qualifiers::OCL_None &&
@@ -11388,7 +11467,7 @@
       if (!T.isConstQualified()) {
         DelayedDiagnostics.add(
             sema::DelayedDiagnostic::makeForbiddenType(
-            NameLoc, diag::err_arc_array_param_no_ownership, T, false));
+            Loc, diag::err_arc_array_param_no_ownership, T, false));
       }
       lifetime = Qualifiers::OCL_ExplicitNone;
     } else {
@@ -11397,6 +11476,16 @@
     T = Context.getLifetimeQualifiedType(T, lifetime);
   }
 
+  return T;
+}
+
+ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
+                                  SourceLocation NameLoc, IdentifierInfo *Name,
+                                  QualType T, TypeSourceInfo *TSInfo,
+                                  StorageClass SC) {
+  // Perform Objective-C ARC adjustments.
+  T = adjustParameterTypeForObjCAutoRefCount(T, NameLoc);
+
   ParmVarDecl *New = ParmVarDecl::Create(Context, DC, StartLoc, NameLoc, Name,
                                          Context.getAdjustedParameterType(T),
                                          TSInfo, SC, nullptr);
@@ -11559,6 +11648,11 @@
   if (canRedefineFunction(Definition, getLangOpts()))
     return;
 
+  // Don't emit an error when this is redifinition of a typo-corrected
+  // definition.
+  if (TypoCorrectedFunctionDefinitions.count(Definition))
+    return;
+
   // If we don't have a visible definition of the function, and it's inline or
   // a template, skip the new definition.
   if (SkipBody && !hasVisibleDefinition(Definition) &&
@@ -11962,7 +12056,7 @@
           !LangOpts.CPlusPlus) {
         TypeSourceInfo *TI = FD->getTypeSourceInfo();
         TypeLoc TL = TI->getTypeLoc();
-        FunctionTypeLoc FTL = TL.castAs<FunctionTypeLoc>();
+        FunctionTypeLoc FTL = TL.getAsAdjusted<FunctionTypeLoc>();
         Diag(FTL.getLParenLoc(), diag::warn_strict_prototypes) << 1;
       }
     }
@@ -12149,7 +12243,9 @@
   // Always attach attributes to the underlying decl.
   if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
     D = TD->getTemplatedDecl();
-  ProcessDeclAttributeList(S, D, Attrs.getList());
+
+  ProcessDeclAttributeList(S, D, Attrs.getList());  
+  ProcessAPINotes(D);
 
   if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(D))
     if (Method->isStatic())
@@ -13224,7 +13320,8 @@
                   Diag(NameLoc, diag::warn_redefinition_in_param_list) << Name;
                 else
                   Diag(NameLoc, diag::err_redefinition) << Name;
-                Diag(Def->getLocation(), diag::note_previous_definition);
+                notePreviousDefinition(Def->getLocation(),
+                                       NameLoc.isValid() ? NameLoc : KWLoc);
                 // If this is a redefinition, recover by making this
                 // struct be anonymous, which will make any later
                 // references get the previous definition.
@@ -13314,7 +13411,7 @@
         // The tag name clashes with something else in the target scope,
         // issue an error and recover by making this tag be anonymous.
         Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
-        Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+        notePreviousDefinition(PrevDecl->getLocation(), NameLoc);
         Name = nullptr;
         Invalid = true;
       }
@@ -13491,6 +13588,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, New, Attr);
+  AddPragmaAttributes(S, New);
 
   // Set the lexical context. If the tag has a C++ scope specifier, the
   // lexical context will be different from the semantic context.
@@ -14340,7 +14438,7 @@
   // Verify that all the fields are okay.
   SmallVector<FieldDecl*, 32> RecFields;
 
-  bool ARCErrReported = false;
+  bool ObjCFieldLifetimeErrReported = false;
   for (ArrayRef<Decl *>::iterator i = Fields.begin(), end = Fields.end();
        i != end; ++i) {
     FieldDecl *FD = cast<FieldDecl>(*i);
@@ -14475,16 +14573,16 @@
         << FixItHint::CreateInsertion(FD->getLocation(), "*");
       QualType T = Context.getObjCObjectPointerType(FD->getType());
       FD->setType(T);
-    } else if (getLangOpts().ObjCAutoRefCount && Record && !ARCErrReported &&
+    } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
+               Record && !ObjCFieldLifetimeErrReported &&
                (!getLangOpts().CPlusPlus || Record->isUnion())) {
-      // It's an error in ARC if a field has lifetime.
+      // It's an error in ARC or Weak if a field has lifetime.
       // We don't want to report this in a system header, though,
       // so we just make the field unavailable.
       // FIXME: that's really not sufficient; we need to make the type
       // itself invalid to, say, initialize or copy.
       QualType T = FD->getType();
-      Qualifiers::ObjCLifetime lifetime = T.getObjCLifetime();
-      if (lifetime && lifetime != Qualifiers::OCL_ExplicitNone) {
+      if (T.hasNonTrivialObjCLifetime()) {
         SourceLocation loc = FD->getLocation();
         if (getSourceManager().isInSystemHeader(loc)) {
           if (!FD->hasAttr<UnavailableAttr>()) {
@@ -14495,7 +14593,7 @@
           Diag(FD->getLocation(), diag::err_arc_objc_object_in_tag)
             << T->isBlockPointerType() << Record->getTagKind();
         }
-        ARCErrReported = true;
+        ObjCFieldLifetimeErrReported = true;
       }
     } else if (getLangOpts().ObjC1 &&
                getLangOpts().getGC() != LangOptions::NonGC &&
@@ -14721,6 +14819,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Record, Attr);
+  ProcessAPINotes(Record);
 }
 
 /// \brief Determine whether the given integral value is representable within
@@ -15012,13 +15111,16 @@
         Diag(IdLoc, diag::err_redefinition_of_enumerator) << Id;
       else
         Diag(IdLoc, diag::err_redefinition) << Id;
-      Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+      notePreviousDefinition(PrevDecl->getLocation(), IdLoc);
       return nullptr;
     }
   }
 
   // Process attributes.
   if (Attr) ProcessDeclAttributeList(S, New, Attr);
+  AddPragmaAttributes(S, New);
+
+  ProcessAPINotes(New);
 
   // Register this decl in the current scope stack.
   New->setAccess(TheEnumDecl->getAccess());
@@ -15207,7 +15309,7 @@
 
 bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
                              bool AllowMask) const {
-  assert(ED->hasAttr<FlagEnumAttr>() && "looking for value in non-flag enum");
+  assert(ED->isClosedFlag() && "looking for value in non-flag or open enum");
   assert(ED->isCompleteDefinition() && "expected enum definition");
 
   auto R = FlagBitsCache.insert(std::make_pair(ED, llvm::APInt()));
@@ -15243,6 +15345,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Enum, Attr);
+  ProcessAPINotes(Enum);
 
   if (Enum->isDependentType()) {
     for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
@@ -15452,7 +15555,7 @@
 
   CheckForDuplicateEnumValues(*this, Elements, Enum, EnumType);
 
-  if (Enum->hasAttr<FlagEnumAttr>()) {
+  if (Enum->isClosedFlag()) {
     for (Decl *D : Elements) {
       EnumConstantDecl *ECD = cast_or_null<EnumConstantDecl>(D);
       if (!ECD) continue;  // Already issued a diagnostic.
@@ -15717,7 +15820,8 @@
 void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc,
                                                       Module *Mod) {
   // Bail if we're not allowed to implicitly import a module here.
-  if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery)
+  if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery ||
+      VisibleModules.isVisible(Mod))
     return;
 
   // Create the implicit import declaration.
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index c6a5bc7..bc196d8 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -909,7 +909,7 @@
     Msg = "<no message provided>";
 
   SmallVector<PartialDiagnosticAt, 8> Diags;
-  if (!Cond->isValueDependent() &&
+  if (isa<FunctionDecl>(D) && !Cond->isValueDependent() &&
       !Expr::isPotentialConstantExprUnevaluated(Cond, cast<FunctionDecl>(D),
                                                 Diags)) {
     S.Diag(Attr.getLoc(), diag::err_attr_cond_never_constant_expr)
@@ -997,10 +997,11 @@
     return;
   }
 
-  auto *FD = cast<FunctionDecl>(D);
-  bool ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
+  bool ArgDependent = false;
+  if (const auto *FD = dyn_cast<FunctionDecl>(D))
+    ArgDependent = ArgumentDependenceChecker(FD).referencesArgs(Cond);
   D->addAttr(::new (S.Context) DiagnoseIfAttr(
-      Attr.getRange(), S.Context, Cond, Msg, DiagType, ArgDependent, FD,
+      Attr.getRange(), S.Context, Cond, Msg, DiagType, ArgDependent, cast<NamedDecl>(D),
       Attr.getAttributeSpellingListIndex()));
 }
 
@@ -1476,6 +1477,26 @@
                                Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleNoEscapeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D);
+  if (!PD)
+    return;
+
+  // noescape only applies to pointer types.
+  QualType T = PD->getType();
+  if (!T->isAnyPointerType() && !T->isBlockPointerType() && 
+      !T->isReferenceType() && !T->isArrayType() && 
+      !T->isMemberPointerType()) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_noescape_non_pointer)
+      << T;
+    return;
+  }
+
+  D->addAttr(::new (S.Context) NoEscapeAttr(
+                                 Attr.getRange(), S.Context,
+                                 Attr.getAttributeSpellingListIndex()));
+}
+
 static void handleAssumeAlignedAttr(Sema &S, Decl *D,
                                     const AttributeList &Attr) {
   Expr *E = Attr.getArgAsExpr(0),
@@ -2303,10 +2324,8 @@
       << Platform->Ident;
 
   NamedDecl *ND = dyn_cast<NamedDecl>(D);
-  if (!ND) {
-    S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
+  if (!ND) // We warned about this already, so just return.
     return;
-  }
 
   AvailabilityChange Introduced = Attr.getAvailabilityIntroduced();
   AvailabilityChange Deprecated = Attr.getAvailabilityDeprecated();
@@ -2322,6 +2341,15 @@
           dyn_cast_or_null<StringLiteral>(Attr.getReplacementExpr()))
     Replacement = SE->getString();
 
+  if (II->getName() == "swift") {
+    if (Introduced.isValid() || Obsoleted.isValid() ||
+        (!IsUnavailable && !Deprecated.isValid())) {
+      S.Diag(Attr.getLoc(),
+             diag::warn_availability_swift_unavailable_deprecated_only);
+      return;
+    }
+  }
+
   AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(ND, Attr.getRange(), II,
                                                       false/*Implicit*/,
                                                       Introduced.Version,
@@ -2409,6 +2437,26 @@
   }
 }
 
+static void handleExternalSourceSymbolAttr(Sema &S, Decl *D,
+                                           const AttributeList &Attr) {
+  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
+    return;
+  assert(checkAttributeAtMostNumArgs(S, Attr, 3) &&
+         "Invalid number of arguments in an external_source_symbol attribute");
+
+  StringRef Language;
+  if (const auto *SE = dyn_cast_or_null<StringLiteral>(Attr.getArgAsExpr(0)))
+    Language = SE->getString();
+  StringRef DefinedIn;
+  if (const auto *SE = dyn_cast_or_null<StringLiteral>(Attr.getArgAsExpr(1)))
+    DefinedIn = SE->getString();
+  bool IsGeneratedDeclaration = Attr.getArgAsIdent(2) != nullptr;
+
+  D->addAttr(::new (S.Context) ExternalSourceSymbolAttr(
+      Attr.getRange(), S.Context, Language, DefinedIn, IsGeneratedDeclaration,
+      Attr.getAttributeSpellingListIndex()));
+}
+
 template <class T>
 static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range,
                               typename T::VisibilityType value,
@@ -2917,6 +2965,28 @@
                          Attr.getAttributeSpellingListIndex()));
 }
 
+static void handleEnumExtensibilityAttr(Sema &S, Decl *D,
+                                        const AttributeList &Attr) {
+  if (!Attr.isArgIdent(0)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_type)
+        << Attr.getName() << 0 << AANT_ArgumentIdentifier;
+    return;
+  }
+
+  EnumExtensibilityAttr::Kind ExtensibilityKind;
+  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
+  if (!EnumExtensibilityAttr::ConvertStrToKind(II->getName(),
+                                               ExtensibilityKind)) {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
+        << Attr.getName() << II;
+    return;
+  }
+
+  D->addAttr(::new (S.Context) EnumExtensibilityAttr(
+      Attr.getRange(), S.Context, ExtensibilityKind,
+      Attr.getAttributeSpellingListIndex()));
+}
+
 /// Handle __attribute__((format_arg((idx)))) attribute based on
 /// http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
 static void handleFormatArgAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3845,6 +3915,27 @@
                                           AttrSpellingListIndex);
 }
 
+SwiftNameAttr *Sema::mergeSwiftNameAttr(Decl *D, SourceRange Range,
+                                        StringRef Name, bool Override,
+                                        unsigned AttrSpellingListIndex) {
+  if (SwiftNameAttr *Inline = D->getAttr<SwiftNameAttr>()) {
+    if (Override) {
+      // FIXME: Warn about an incompatible override.
+      return nullptr;
+    }
+
+    if (Inline->getName() != Name && !Inline->isImplicit()) {
+      Diag(Inline->getLocation(), diag::warn_attribute_ignored) << Inline;
+      Diag(Range.getBegin(), diag::note_conflicting_attribute);
+    }
+
+    D->dropAttr<SwiftNameAttr>();
+  }
+
+  return ::new (Context) SwiftNameAttr(Range, Context, Name,
+                                       AttrSpellingListIndex);
+}
+
 static void handleAlwaysInlineAttr(Sema &S, Decl *D,
                                    const AttributeList &Attr) {
   if (checkAttrMutualExclusion<NotTailCalledAttr>(S, D, Attr.getRange(),
@@ -4622,6 +4713,40 @@
                                         attr.getAttributeSpellingListIndex()));
 }
 
+static void handleNSErrorDomain(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (!isa<TagDecl>(D)) {
+    S.Diag(D->getLocStart(), diag::err_nserrordomain_not_tagdecl)
+        << S.getLangOpts().CPlusPlus;
+    return;
+  }
+  IdentifierLoc *identLoc =
+      Attr.isArgIdent(0) ? Attr.getArgAsIdent(0) : nullptr;
+  if (!identLoc || !identLoc->Ident) {
+    // Try to locate the argument directly
+    SourceLocation loc = Attr.getLoc();
+    if (Attr.isArgExpr(0) && Attr.getArgAsExpr(0))
+      loc = Attr.getArgAsExpr(0)->getLocStart();
+
+    S.Diag(loc, diag::err_nserrordomain_requires_identifier);
+    return;
+  }
+
+  // Verify that the identifier is a valid decl in the C decl namespace
+  LookupResult lookupResult(S, DeclarationName(identLoc->Ident),
+                            SourceLocation(),
+                            Sema::LookupNameKind::LookupOrdinaryName);
+  if (!S.LookupName(lookupResult, S.TUScope) ||
+      !lookupResult.getAsSingle<VarDecl>()) {
+    S.Diag(identLoc->Loc, diag::err_nserrordomain_invalid_decl)
+        << identLoc->Ident;
+    return;
+  }
+
+  D->addAttr(::new (S.Context)
+                 NSErrorDomainAttr(Attr.getRange(), S.Context, identLoc->Ident,
+                                   Attr.getAttributeSpellingListIndex()));
+}
+
 static void handleCFAuditedTransferAttr(Sema &S, Decl *D,
                                         const AttributeList &Attr) {
   if (checkAttrMutualExclusion<CFUnknownTransferAttr>(S, D, Attr.getRange(),
@@ -4811,6 +4936,421 @@
                                      Attr.getAttributeSpellingListIndex()));
 }
 
+static Optional<unsigned>
+validateSwiftFunctionName(StringRef Name,
+                          unsigned &SwiftParamCount,
+                          bool &IsSingleParamInit) {
+  SwiftParamCount = 0;
+
+  // Check whether this will be mapped to a getter or setter of a
+  // property.
+  bool isGetter = false;
+  bool isSetter = false;
+  if (Name.startswith("getter:")) {
+    isGetter = true;
+    Name = Name.substr(7);
+  } else if (Name.startswith("setter:")) {
+    isSetter = true;
+    Name = Name.substr(7);
+  }
+
+  if (Name.back() != ')')
+    return diag::warn_attr_swift_name_function;
+
+  StringRef BaseName, Parameters;
+  std::tie(BaseName, Parameters) = Name.split('(');
+
+  // Split at the first '.', if it exists, which separates the context
+  // name from the base name.
+  StringRef ContextName;
+  bool IsMember = false;
+  std::tie(ContextName, BaseName) = BaseName.split('.');
+  if (BaseName.empty()) {
+    BaseName = ContextName;
+    ContextName = StringRef();
+  } else if (ContextName.empty() || !isValidIdentifier(ContextName)) {
+    return diag::warn_attr_swift_name_context_name_invalid_identifier;
+  } else {
+    IsMember = true;
+  }
+
+  if (!isValidIdentifier(BaseName) || BaseName == "_")
+    return diag::warn_attr_swift_name_basename_invalid_identifier;
+
+  bool IsSubscript = BaseName == "subscript";
+  // A subscript accessor must be a getter or setter.
+  if (IsSubscript && !isGetter && !isSetter)
+    return diag::warn_attr_swift_name_subscript_not_accessor;
+  
+  if (Parameters.empty())
+    return diag::warn_attr_swift_name_missing_parameters;
+  Parameters = Parameters.drop_back(); // ')'
+
+  if (Parameters.empty()) {
+    // Setters and subscripts must have at least one parameter.
+    if (IsSubscript)
+      return diag::warn_attr_swift_name_subscript_no_parameter;
+    if (isSetter)
+      return diag::warn_attr_swift_name_setter_parameters;
+    
+    return None;
+  }
+
+  if (Parameters.back() != ':')
+    return diag::warn_attr_swift_name_function;
+
+  Optional<unsigned> SelfLocation;
+  Optional<unsigned> NewValueLocation;
+  unsigned NewValueCount = 0;
+  StringRef NextParam;
+  do {
+    std::tie(NextParam, Parameters) = Parameters.split(':');
+
+    if (!isValidIdentifier(NextParam))
+      return diag::warn_attr_swift_name_parameter_invalid_identifier;
+
+    // "self" indicates the "self" argument for a member.
+    if (IsMember && NextParam == "self") {
+      // More than one "self"?
+      if (SelfLocation) return diag::warn_attr_swift_name_multiple_selfs;
+
+      // The "self" location is the current parameter.
+      SelfLocation = SwiftParamCount;
+    }
+    
+    // "newValue" indicates the "newValue" argument for a setter.
+    if (NextParam == "newValue") {
+      // There should only be one 'newValue', but it's only significant for
+      // subscript accessors, so don't error right away.
+      ++NewValueCount;
+      
+      NewValueLocation = SwiftParamCount;
+    }
+    ++SwiftParamCount;
+  } while (!Parameters.empty());
+
+  // Only instance subscripts are currently supported.
+  if (IsSubscript && !SelfLocation)
+    return diag::warn_attr_swift_name_static_subscript;
+
+  IsSingleParamInit =
+      (SwiftParamCount == 1 && BaseName == "init" && NextParam != "_");
+
+  // Check the number of parameters for a getter/setter.
+  if (isGetter || isSetter) {
+    // Setters have one parameter for the new value.
+    unsigned NumExpectedParams;
+    unsigned ParamDiag;
+    
+    if (isSetter) {
+      NumExpectedParams = 1;
+      ParamDiag = diag::warn_attr_swift_name_setter_parameters;
+    } else {
+      NumExpectedParams = 0;
+      ParamDiag = diag::warn_attr_swift_name_getter_parameters;
+    }
+
+    // Instance methods have one parameter for "self".
+    if (SelfLocation) ++NumExpectedParams;
+    
+    // Subscripts may have additional parameters beyond the expected params for
+    // the index.
+    if (IsSubscript) {
+      if (SwiftParamCount < NumExpectedParams)
+        return ParamDiag;
+      // A subscript setter must explicitly label its newValue parameter to
+      // distinguish it from index parameters.
+      if (isSetter) {
+        if (!NewValueLocation)
+          return diag::warn_attr_swift_name_subscript_setter_no_newValue;
+        // There can only be one.
+        if (NewValueCount > 1)
+          return diag::warn_attr_swift_name_subscript_setter_multiple_newValues;
+      } else {
+        // Subscript getters should have no 'newValue:' parameter.
+        if (NewValueLocation)
+          return diag::warn_attr_swift_name_subscript_getter_newValue;
+      }
+    } else {
+      // Property accessors must have exactly the number of expected params.
+      if (SwiftParamCount != NumExpectedParams)
+        return ParamDiag;
+    }
+  }
+  
+  return None;
+}
+
+/// Do a check to make sure \p Name looks like a legal swift_name
+/// attribute for the decl \p D. Raise a diagnostic if the name is invalid
+/// for the given declaration.
+///
+/// For a function, this will validate a compound Swift name,
+/// e.g. <code>init(foo:bar:baz:)</code> or <code>controllerForName(_:)</code>,
+/// and the function will output the number of parameter names, and whether this
+/// is a single-arg initializer.
+///
+/// For a type, enum constant, property, or variable declaration, this will
+/// validate either a simple identifier, or a qualified
+/// <code>context.identifier</code> name.
+///
+/// \returns true if the name is a valid swift name for \p D, false otherwise.
+bool Sema::DiagnoseSwiftName(Decl *D, StringRef Name,
+                             SourceLocation ArgLoc,
+                             IdentifierInfo *AttrName) {
+  if (isa<ObjCMethodDecl>(D) || isa<FunctionDecl>(D)) {
+    ArrayRef<ParmVarDecl*> Params;
+    unsigned ParamCount;
+
+    if (const auto *Method = dyn_cast<ObjCMethodDecl>(D)) {
+      ParamCount = Method->getSelector().getNumArgs();
+      Params = Method->parameters().slice(0, ParamCount);
+    } else {
+      const auto *Function = cast<FunctionDecl>(D);
+      ParamCount = Function->getNumParams();
+      Params = Function->parameters();
+      
+      if (!Function->hasWrittenPrototype()) {
+        Diag(ArgLoc, diag::warn_attr_swift_name_function_no_prototype)
+          << AttrName;
+        return false;
+      }
+    }
+
+    unsigned SwiftParamCount;
+    bool IsSingleParamInit;
+    if (auto diagID = validateSwiftFunctionName(Name, SwiftParamCount,
+                                                IsSingleParamInit)) {
+      Diag(ArgLoc, *diagID) << AttrName;
+      return false;
+    }
+  
+    bool ParamsOK;
+    if (SwiftParamCount == ParamCount) {
+      ParamsOK = true;
+    } else if (SwiftParamCount > ParamCount) {
+      ParamsOK = IsSingleParamInit && ParamCount == 0;
+    } else {
+      // We have fewer Swift parameters than Objective-C parameters, but that
+      // might be because we've transformed some of them. Check for potential
+      // "out" parameters and err on the side of not warning.
+      unsigned MaybeOutParamCount =
+          std::count_if(Params.begin(), Params.end(),
+                        [](const ParmVarDecl *Param) -> bool {
+        QualType ParamTy = Param->getType();
+        if (ParamTy->isReferenceType() || ParamTy->isPointerType())
+          return !ParamTy->getPointeeType().isConstQualified();
+        return false;
+      });
+      ParamsOK = (SwiftParamCount + MaybeOutParamCount >= ParamCount);
+    }
+
+    if (!ParamsOK) {
+      Diag(ArgLoc, diag::warn_attr_swift_name_num_params)
+          << (SwiftParamCount > ParamCount) << AttrName
+          << ParamCount << SwiftParamCount;
+      return false;
+    }
+
+  } else if (isa<EnumConstantDecl>(D) || isa<ObjCProtocolDecl>(D) ||
+             isa<ObjCInterfaceDecl>(D) || isa<ObjCPropertyDecl>(D) ||
+             isa<VarDecl>(D) || isa<TypedefNameDecl>(D) || isa<TagDecl>(D) ||
+             isa<IndirectFieldDecl>(D) || isa<FieldDecl>(D)) {
+    StringRef ContextName, BaseName;
+    std::tie(ContextName, BaseName) = Name.split('.');
+    if (BaseName.empty()) {
+      BaseName = ContextName;
+      ContextName = StringRef();
+    } else if (!isValidIdentifier(ContextName)) {
+      Diag(ArgLoc, diag::warn_attr_swift_name_context_name_invalid_identifier)
+        << AttrName;
+      return false;
+    }
+
+    if (!isValidIdentifier(BaseName)) {
+      Diag(ArgLoc, diag::warn_attr_swift_name_basename_invalid_identifier)
+        << AttrName;
+      return false;
+    }
+
+  } else {
+    Diag(ArgLoc, diag::warn_attr_swift_name_decl_kind) << AttrName;
+    return false;
+  }
+  return true;
+}
+
+static void handleSwiftName(Sema &S, Decl *D, const AttributeList &Attr) {
+  StringRef Name;
+  SourceLocation ArgLoc;
+  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Name, &ArgLoc))
+    return;
+
+  if (!S.DiagnoseSwiftName(D, Name, ArgLoc, Attr.getName()))
+    return;
+
+  D->addAttr(::new (S.Context) SwiftNameAttr(Attr.getRange(), S.Context, Name,
+                                         Attr.getAttributeSpellingListIndex()));
+}
+
+static bool isErrorParameter(Sema &S, QualType paramType) {
+  if (auto ptr = paramType->getAs<PointerType>()) {
+    auto outerPointee = ptr->getPointeeType();
+
+    // NSError**.
+    if (auto objcPtr = outerPointee->getAs<ObjCObjectPointerType>()) {
+      if (auto iface = objcPtr->getInterfaceDecl())
+        if (iface->getIdentifier() == S.getNSErrorIdent())
+          return true;
+    }
+
+    // CFErrorRef*.
+    if (auto cPtr = outerPointee->getAs<PointerType>()) {
+      auto innerPointee = cPtr->getPointeeType();
+      if (auto recordType = innerPointee->getAs<RecordType>()) {
+        if (S.isCFError(recordType->getDecl()))
+          return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+static void handleSwiftError(Sema &S, Decl *D, const AttributeList &attr) {
+  SwiftErrorAttr::ConventionKind convention;
+  IdentifierLoc *conventionLoc = attr.getArgAsIdent(0);
+  StringRef conventionStr = conventionLoc->Ident->getName();
+  if (!SwiftErrorAttr::ConvertStrToConventionKind(conventionStr, convention)) {
+    S.Diag(attr.getLoc(), diag::warn_attribute_type_not_supported)
+      << attr.getName() << conventionLoc->Ident;
+    return;
+  }
+
+  auto requireErrorParameter = [&]() -> bool {
+    if (D->isInvalidDecl()) return true;
+
+    for (unsigned i = 0, e = getFunctionOrMethodNumParams(D); i != e; ++i) {
+      if (isErrorParameter(S, getFunctionOrMethodParamType(D, i)))
+        return true;
+    }
+
+    S.Diag(attr.getLoc(), diag::err_attr_swift_error_no_error_parameter)
+      << attr.getName() << isa<ObjCMethodDecl>(D);
+    return false;
+  };
+
+  auto requirePointerResult = [&] {
+    if (D->isInvalidDecl()) return true;
+
+    // C, ObjC, and block pointers are definitely okay.
+    // References are definitely not okay.
+    // nullptr_t is weird but acceptable.
+    QualType returnType = getFunctionOrMethodResultType(D);
+    if (returnType->hasPointerRepresentation() &&
+        !returnType->isReferenceType()) return true;
+
+    S.Diag(attr.getLoc(), diag::err_attr_swift_error_return_type)
+      << attr.getName() << conventionStr
+      << isa<ObjCMethodDecl>(D) << /*pointer*/ 1;
+    return false;
+  };
+
+  auto requireIntegerResult = [&] {
+    if (D->isInvalidDecl()) return true;
+
+    QualType returnType = getFunctionOrMethodResultType(D);
+    if (returnType->isIntegralType(S.Context)) return true;
+
+    S.Diag(attr.getLoc(), diag::err_attr_swift_error_return_type)
+      << attr.getName() << conventionStr
+      << isa<ObjCMethodDecl>(D) << /*integral*/ 0;
+    return false;
+  };
+
+  switch (convention) {
+  case SwiftErrorAttr::None:
+    // No additional validation required.
+    break;
+
+  case SwiftErrorAttr::NonNullError:
+    if (!requireErrorParameter()) return;
+    break;
+
+  case SwiftErrorAttr::NullResult:
+    if (!requireErrorParameter()) return;
+    if (!requirePointerResult()) return;
+    break;
+
+  case SwiftErrorAttr::NonZeroResult:
+  case SwiftErrorAttr::ZeroResult:
+    if (!requireErrorParameter()) return;
+    if (!requireIntegerResult()) return;
+    break;
+  }
+
+  D->addAttr(::new (S.Context)
+             SwiftErrorAttr(attr.getRange(), S.Context, convention,
+                            attr.getAttributeSpellingListIndex()));
+}
+
+static void handleSwiftBridgeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  // Make sure that there is a string literal as the annotation's single
+  // argument.
+  StringRef Str;
+  if (!S.checkStringLiteralArgumentAttr(Attr, 0, Str))
+    return;
+
+  // Don't duplicate annotations that are already set.
+  if (D->hasAttr<SwiftBridgeAttr>()) {
+    S.Diag(Attr.getLoc(), diag::warn_duplicate_attribute) << Attr.getName();
+    return;
+  }
+
+  D->addAttr(::new (S.Context)
+             SwiftBridgeAttr(Attr.getRange(), S.Context, Str,
+                             Attr.getAttributeSpellingListIndex()));
+}
+
+static void handleSwiftNewtypeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  // Make sure that there is an identifier as the annotation's single
+  // argument.
+  if (Attr.getNumArgs() != 1) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments)
+      << Attr.getName() << 1;
+    Attr.setInvalid();
+    return;
+  }
+  if (!Attr.isArgIdent(0)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_argument_type)
+      << Attr.getName() << AANT_ArgumentIdentifier;
+    Attr.setInvalid();
+    return;
+  }
+
+  IdentifierInfo *II = Attr.getArgAsIdent(0)->Ident;
+  SwiftNewtypeAttr::NewtypeKind Kind;
+  if (II->isStr("struct"))
+    Kind = SwiftNewtypeAttr::NK_Struct;
+  else if (II->isStr("enum"))
+    Kind = SwiftNewtypeAttr::NK_Enum;
+  else {
+    S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported)
+      << Attr.getName() << II;
+    Attr.setInvalid();
+    return;
+  }
+
+  if (!isa<TypedefNameDecl>(D)) {
+    S.Diag(Attr.getLoc(), diag::warn_swift_newtype_attribute_non_typedef);
+    return;
+  }
+
+  D->addAttr(::new (S.Context)
+             SwiftNewtypeAttr(Attr.getRange(), S.Context, Kind,
+                              Attr.getAttributeSpellingListIndex()));
+}
+
 //===----------------------------------------------------------------------===//
 // Microsoft specific attribute handlers.
 //===----------------------------------------------------------------------===//
@@ -5559,18 +6099,21 @@
 static bool handleCommonAttributeFeatures(Sema &S, Scope *scope, Decl *D,
                                           const AttributeList &Attr) {
   // Several attributes carry different semantics than the parsing requires, so
-  // those are opted out of the common handling.
+  // those are opted out of the common argument checks.
   //
   // We also bail on unknown and ignored attributes because those are handled
   // as part of the target-specific handling logic.
-  if (Attr.hasCustomParsing() ||
-      Attr.getKind() == AttributeList::UnknownAttribute)
+  if (Attr.getKind() == AttributeList::UnknownAttribute)
     return false;
-
   // Check whether the attribute requires specific language extensions to be
   // enabled.
   if (!Attr.diagnoseLangOpts(S))
     return true;
+  // Check whether the attribute appertains to the given subject.
+  if (!Attr.diagnoseAppertainsTo(S, D))
+    return true;
+  if (Attr.hasCustomParsing())
+    return false;
 
   if (Attr.getMinArgs() == Attr.getMaxArgs()) {
     // If there are no optional arguments, then checking for the argument count
@@ -5587,10 +6130,6 @@
       return true;
   }
 
-  // Check whether the attribute appertains to the given subject.
-  if (!Attr.diagnoseAppertainsTo(S, D))
-    return true;
-
   return false;
 }
 
@@ -5772,6 +6311,9 @@
   case AttributeList::AT_ExtVectorType:
     handleExtVectorTypeAttr(S, scope, D, Attr);
     break;
+  case AttributeList::AT_ExternalSourceSymbol:
+    handleExternalSourceSymbolAttr(S, D, Attr);
+    break;
   case AttributeList::AT_MinSize:
     handleMinSizeAttr(S, D, Attr);
     break;
@@ -5781,6 +6323,9 @@
   case AttributeList::AT_FlagEnum:
     handleSimpleAttribute<FlagEnumAttr>(S, D, Attr);
     break;
+  case AttributeList::AT_EnumExtensibility:
+    handleEnumExtensibilityAttr(S, D, Attr);
+    break;
   case AttributeList::AT_Flatten:
     handleSimpleAttribute<FlattenAttr>(S, D, Attr);
     break;
@@ -5834,6 +6379,9 @@
   case AttributeList::AT_ReturnsNonNull:
     handleReturnsNonNullAttr(S, D, Attr);
     break;
+  case AttributeList::AT_NoEscape:
+    handleNoEscapeAttr(S, D, Attr);
+    break;
   case AttributeList::AT_AssumeAligned:
     handleAssumeAlignedAttr(S, D, Attr);
     break;
@@ -5897,6 +6445,9 @@
   case AttributeList::AT_ObjCBoxable:
     handleObjCBoxable(S, D, Attr);
     break;
+  case AttributeList::AT_NSErrorDomain:
+    handleNSErrorDomain(S, D, Attr);
+    break;
   case AttributeList::AT_CFAuditedTransfer:
     handleCFAuditedTransferAttr(S, D, Attr);
     break;
@@ -5953,6 +6504,9 @@
   case AttributeList::AT_ObjCSubclassingRestricted:
     handleSimpleAttribute<ObjCSubclassingRestrictedAttr>(S, D, Attr);
     break;
+  case AttributeList::AT_ObjCCompleteDefinition:
+    handleSimpleAttribute<ObjCCompleteDefinitionAttr>(S, D, Attr);
+    break;
   case AttributeList::AT_ObjCExplicitProtocolImpl:
     handleObjCSuppresProtocolAttr(S, D, Attr);
     break;
@@ -6219,6 +6773,25 @@
   case AttributeList::AT_RenderScriptKernel:
     handleSimpleAttribute<RenderScriptKernelAttr>(S, D, Attr);
     break;
+  // Swift attributes.
+  case AttributeList::AT_SwiftPrivate:
+    handleSimpleAttribute<SwiftPrivateAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_SwiftName:
+    handleSwiftName(S, D, Attr);
+    break;
+  case AttributeList::AT_SwiftError:
+    handleSwiftError(S, D, Attr);
+    break;
+  case AttributeList::AT_SwiftBridge:
+    handleSwiftBridgeAttr(S, D, Attr);
+    break;
+  case AttributeList::AT_SwiftObjCMembers:
+    handleSimpleAttribute<SwiftObjCMembersAttr>(S, D, Attr);
+    break;
+  case AttributeList::AT_SwiftNewtype:
+    handleSwiftNewtypeAttr(S, D, Attr);
+    break;
   // XRay attributes.
   case AttributeList::AT_XRayInstrument:
     handleSimpleAttribute<XRayInstrumentAttr>(S, D, Attr);
@@ -6443,6 +7016,11 @@
   // Finally, apply any attributes on the decl itself.
   if (const AttributeList *Attrs = PD.getAttributes())
     ProcessDeclAttributeList(S, D, Attrs);
+
+  // Look for API notes that map to attributes.
+  ProcessAPINotes(D);
+  // Apply additional attributes specified by '#pragma clang attribute'.
+  AddPragmaAttributes(S, D);
 }
 
 /// Is the given declaration allowed to use a forbidden type?
@@ -6611,6 +7189,7 @@
   // Diagnostics for deprecated or unavailable.
   unsigned diag, diag_message, diag_fwdclass_message;
   unsigned diag_available_here = diag::note_availability_specified_here;
+  SourceLocation NoteLocation = D->getLocation();
 
   // Matches 'diag::note_property_attribute' options.
   unsigned property_note_select;
@@ -6633,6 +7212,8 @@
     diag_fwdclass_message = diag::warn_deprecated_fwdclass_message;
     property_note_select = /* deprecated */ 0;
     available_here_select_kind = /* deprecated */ 2;
+    if (const auto *attr = D->getAttr<DeprecatedAttr>())
+      NoteLocation = attr->getLocation();
     break;
 
   case AR_Unavailable:
@@ -6751,7 +7332,7 @@
     }
   }
   else
-    S.Diag(D->getLocation(), diag_available_here)
+    S.Diag(NoteLocation, diag_available_here)
         << D << available_here_select_kind;
 
   if (K == AR_NotYetIntroduced)
@@ -6846,6 +7427,69 @@
 
 namespace {
 
+/// Returns true if the given statement can be a body-like child of \p Parent.
+bool isBodyLikeChildStmt(const Stmt *S, const Stmt *Parent) {
+  switch (Parent->getStmtClass()) {
+  case Stmt::IfStmtClass:
+    return cast<IfStmt>(Parent)->getThen() == S ||
+           cast<IfStmt>(Parent)->getElse() == S;
+  case Stmt::WhileStmtClass:
+    return cast<WhileStmt>(Parent)->getBody() == S;
+  case Stmt::DoStmtClass:
+    return cast<DoStmt>(Parent)->getBody() == S;
+  case Stmt::ForStmtClass:
+    return cast<ForStmt>(Parent)->getBody() == S;
+  case Stmt::CXXForRangeStmtClass:
+    return cast<CXXForRangeStmt>(Parent)->getBody() == S;
+  case Stmt::ObjCForCollectionStmtClass:
+    return cast<ObjCForCollectionStmt>(Parent)->getBody() == S;
+  case Stmt::CaseStmtClass:
+  case Stmt::DefaultStmtClass:
+    return cast<SwitchCase>(Parent)->getSubStmt() == S;
+  default:
+    return false;
+  }
+}
+
+class StmtUSEFinder : public RecursiveASTVisitor<StmtUSEFinder> {
+  const Stmt *Target;
+
+public:
+  bool VisitStmt(Stmt *S) { return S != Target; }
+
+  /// Returns true if the given statement is present in the given declaration.
+  static bool isContained(const Stmt *Target, const Decl *D) {
+    StmtUSEFinder Visitor;
+    Visitor.Target = Target;
+    return !Visitor.TraverseDecl(const_cast<Decl *>(D));
+  }
+};
+
+/// Traverses the AST and finds the last statement that used a given
+/// declaration.
+class LastDeclUSEFinder : public RecursiveASTVisitor<LastDeclUSEFinder> {
+  const Decl *D;
+
+public:
+  bool VisitDeclRefExpr(DeclRefExpr *DRE) {
+    if (DRE->getDecl() == D)
+      return false;
+    return true;
+  }
+
+  static const Stmt *findLastStmtThatUsesDecl(const Decl *D,
+                                              const CompoundStmt *Scope) {
+    LastDeclUSEFinder Visitor;
+    Visitor.D = D;
+    for (auto I = Scope->body_rbegin(), E = Scope->body_rend(); I != E; ++I) {
+      const Stmt *S = *I;
+      if (!Visitor.TraverseStmt(const_cast<Stmt *>(S)))
+        return S;
+    }
+    return nullptr;
+  }
+};
+
 /// \brief This class implements -Wunguarded-availability.
 ///
 /// This is done with a traversal of the AST of a function that makes reference
@@ -6861,6 +7505,7 @@
 
   /// Stack of potentially nested 'if (@available(...))'s.
   SmallVector<VersionTuple, 8> AvailabilityStack;
+  SmallVector<const Stmt *, 16> StmtStack;
 
   void DiagnoseDeclAvailability(NamedDecl *D, SourceRange Range);
 
@@ -6871,10 +7516,34 @@
         SemaRef.Context.getTargetInfo().getPlatformMinVersion());
   }
 
+  bool TraverseDecl(Decl *D) {
+    // Avoid visiting nested functions to prevent duplicate warnings.
+    if (!D || isa<FunctionDecl>(D))
+      return true;
+    return Base::TraverseDecl(D);
+  }
+
+  bool TraverseStmt(Stmt *S) {
+    if (!S)
+      return true;
+    StmtStack.push_back(S);
+    bool Result = Base::TraverseStmt(S);
+    StmtStack.pop_back();
+    return Result;
+  }
+
   void IssueDiagnostics(Stmt *S) { TraverseStmt(S); }
 
   bool TraverseIfStmt(IfStmt *If);
 
+  bool TraverseLambdaExpr(LambdaExpr *E) { return true; }
+
+  bool VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *PRE) {
+    if (PRE->isClassReceiver())
+      DiagnoseDeclAvailability(PRE->getClassReceiver(), PRE->getReceiverLocation());
+    return true;
+  }
+
   bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
     if (ObjCMethodDecl *D = Msg->getMethodDecl())
       DiagnoseDeclAvailability(
@@ -6894,6 +7563,12 @@
     return true;
   }
 
+  bool VisitObjCAvailabilityCheckExpr(ObjCAvailabilityCheckExpr *E) {
+    SemaRef.Diag(E->getLocStart(), diag::warn_at_available_unchecked_use)
+        << (!SemaRef.getLangOpts().ObjC1);
+    return true;
+  }
+
   bool VisitTypeLoc(TypeLoc Ty);
 };
 
@@ -6928,9 +7603,75 @@
     SemaRef.Diag(D->getLocation(), diag::note_availability_specified_here)
         << D << /* partial */ 3;
 
-    // FIXME: Replace this with a fixit diagnostic.
-    SemaRef.Diag(Range.getBegin(), diag::note_unguarded_available_silence)
-        << Range << D;
+    auto FixitDiag =
+        SemaRef.Diag(Range.getBegin(), diag::note_unguarded_available_silence)
+        << Range << D
+        << (SemaRef.getLangOpts().ObjC1 ? /*@available*/ 0
+                                        : /*__builtin_available*/ 1);
+
+    // Find the statement which should be enclosed in the if @available check.
+    if (StmtStack.empty())
+      return;
+    const Stmt *StmtOfUse = StmtStack.back();
+    const CompoundStmt *Scope = nullptr;
+    for (const Stmt *S : llvm::reverse(StmtStack)) {
+      if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
+        Scope = CS;
+        break;
+      }
+      if (isBodyLikeChildStmt(StmtOfUse, S)) {
+        // The declaration won't be seen outside of the statement, so we don't
+        // have to wrap the uses of any declared variables in if (@available).
+        // Therefore we can avoid setting Scope here.
+        break;
+      }
+      StmtOfUse = S;
+    }
+    const Stmt *LastStmtOfUse = nullptr;
+    if (isa<DeclStmt>(StmtOfUse) && Scope) {
+      for (const Decl *D : cast<DeclStmt>(StmtOfUse)->decls()) {
+        if (StmtUSEFinder::isContained(StmtStack.back(), D)) {
+          LastStmtOfUse = LastDeclUSEFinder::findLastStmtThatUsesDecl(D, Scope);
+          break;
+        }
+      }
+    }
+
+    const SourceManager &SM = SemaRef.getSourceManager();
+    SourceLocation IfInsertionLoc =
+        SM.getExpansionLoc(StmtOfUse->getLocStart());
+    SourceLocation StmtEndLoc =
+        SM.getExpansionRange(
+              (LastStmtOfUse ? LastStmtOfUse : StmtOfUse)->getLocEnd())
+            .second;
+    if (SM.getFileID(IfInsertionLoc) != SM.getFileID(StmtEndLoc))
+      return;
+
+    StringRef Indentation = Lexer::getIndentationForLine(IfInsertionLoc, SM);
+    const char *ExtraIndentation = "    ";
+    std::string FixItString;
+    llvm::raw_string_ostream FixItOS(FixItString);
+    FixItOS << "if (" << (SemaRef.getLangOpts().ObjC1 ? "@available"
+                                                      : "__builtin_available")
+            << "("
+            << AvailabilityAttr::getPlatformNameSourceSpelling(
+                   SemaRef.getASTContext().getTargetInfo().getPlatformName())
+            << " " << Introduced.getAsString() << ", *)) {\n"
+            << Indentation << ExtraIndentation;
+    FixitDiag << FixItHint::CreateInsertion(IfInsertionLoc, FixItOS.str());
+    SourceLocation ElseInsertionLoc = Lexer::findLocationAfterToken(
+        StmtEndLoc, tok::semi, SM, SemaRef.getLangOpts(),
+        /*SkipTrailingWhitespaceAndNewLine=*/false);
+    if (ElseInsertionLoc.isInvalid())
+      ElseInsertionLoc =
+          Lexer::getLocForEndOfToken(StmtEndLoc, 0, SM, SemaRef.getLangOpts());
+    FixItOS.str().clear();
+    FixItOS << "\n"
+            << Indentation << "} else {\n"
+            << Indentation << ExtraIndentation
+            << "// Fallback on earlier versions\n"
+            << Indentation << "}";
+    FixitDiag << FixItHint::CreateInsertion(ElseInsertionLoc, FixItOS.str());
   }
 }
 
@@ -6938,6 +7679,9 @@
   const Type *TyPtr = Ty.getTypePtr();
   SourceRange Range{Ty.getBeginLoc(), Ty.getEndLoc()};
 
+  if (Range.isInvalid())
+    return true;
+
   if (const TagType *TT = dyn_cast<TagType>(TyPtr)) {
     TagDecl *TD = TT->getDecl();
     DiagnoseDeclAvailability(TD, Range);
@@ -6990,6 +7734,8 @@
     Body = FD->getBody();
   } else if (auto *MD = dyn_cast<ObjCMethodDecl>(D))
     Body = MD->getBody();
+  else if (auto *BD = dyn_cast<BlockDecl>(D))
+    Body = BD->getBody();
 
   assert(Body && "Need a body here!");
 
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index f265f4c..fabc580 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -4332,11 +4332,8 @@
     }
   }
   
-  if (SemaRef.getLangOpts().ObjCAutoRefCount &&
-      FieldBaseElementType->isObjCRetainableType() &&
-      FieldBaseElementType.getObjCLifetime() != Qualifiers::OCL_None &&
-      FieldBaseElementType.getObjCLifetime() != Qualifiers::OCL_ExplicitNone) {
-    // ARC:
+  if (FieldBaseElementType.hasNonTrivialObjCLifetime()) {
+    // ARC and Weak:
     //   Default-initialize Objective-C pointers to NULL.
     CXXMemberInit
       = new (SemaRef.Context) CXXCtorInitializer(SemaRef.Context, Field, 
@@ -7009,8 +7006,7 @@
     //   [...] nontrivally ownership-qualified types are [...] not trivially
     //   default constructible, copy constructible, move constructible, copy
     //   assignable, move assignable, or destructible [...]
-    if (S.getLangOpts().ObjCAutoRefCount &&
-        FieldType.hasNonTrivialObjCLifetime()) {
+    if (FieldType.hasNonTrivialObjCLifetime()) {
       if (Diagnose)
         S.Diag(FI->getLocation(), diag::note_nontrivial_objc_ownership)
           << RD << FieldType.getObjCLifetime();
@@ -8161,6 +8157,8 @@
     Namespc->setInvalidDecl();
   
   ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
+  ProcessAPINotes(Namespc);
+  AddPragmaAttributes(DeclRegionScope, Namespc);
 
   // FIXME: Should we be merging attributes?
   if (const VisibilityAttr *Attr = Namespc->getAttr<VisibilityAttr>())
@@ -8550,6 +8548,7 @@
 
   if (UDir)
     ProcessDeclAttributeList(S, UDir, AttrList);
+  ProcessAPINotes(UDir);
 
   return UDir;
 }
@@ -9641,6 +9640,8 @@
     NewTD->setInvalidDecl();
 
   ProcessDeclAttributeList(S, NewTD, AttrList);
+  ProcessAPINotes(NewTD);
+  AddPragmaAttributes(S, NewTD);
 
   CheckTypedefForVariablyModifiedType(S, NewTD);
   Invalid |= NewTD->isInvalidDecl();
@@ -10852,7 +10853,7 @@
     = new (S.Context) BinaryOperator(IterationVarRefRVal.build(S, Loc),
                      IntegerLiteral::Create(S.Context, Upper, SizeType, Loc),
                                      BO_NE, S.Context.BoolTy,
-                                     VK_RValue, OK_Ordinary, Loc, false);
+                                     VK_RValue, OK_Ordinary, Loc, FPOptions());
 
   // Create the pre-increment of the iteration variable.
   Expr *Increment
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index b43e5b9..0bcd59b 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -258,7 +258,8 @@
       S.Diag(ND->getLocation(), diag::note_method_declared_at)
         << ND->getDeclName();
     else
-      S.Diag(ND->getLocation(), diag::note_previous_decl) << "class";
+      S.Diag(ND->getLocation(), diag::note_previous_decl)
+          << (isa<ObjCCategoryDecl>(ND) ? "category" : "class");
   }
 }
 
@@ -980,6 +981,11 @@
   ObjCInterfaceDecl *IDecl
     = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
                                 typeParamList, PrevIDecl, ClassLoc);
+  if (AttrList)
+    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+  ProcessAPINotes(IDecl);
+  AddPragmaAttributes(TUScope, IDecl);
+
   if (PrevIDecl) {
     // Class already seen. Was it a definition?
     if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
@@ -990,8 +996,6 @@
     }
   }
   
-  if (AttrList)
-    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
   PushOnScopeChains(IDecl, TUScope);
 
   // Start the definition of this class. If we're in a redefinition case, there 
@@ -1175,7 +1179,9 @@
   
   if (AttrList)
     ProcessDeclAttributeList(TUScope, PDecl, AttrList);
-  
+  ProcessAPINotes(PDecl);
+  AddPragmaAttributes(TUScope, PDecl);
+
   // Merge attributes from previous declarations.
   if (PrevDecl)
     mergeDeclAttributes(PDecl, PrevDecl);
@@ -1699,13 +1705,16 @@
       = ObjCProtocolDecl::Create(Context, CurContext, Ident, 
                                  IdentPair.second, AtProtocolLoc,
                                  PrevDecl);
-        
+    ProcessAPINotes(PDecl);
+
     PushOnScopeChains(PDecl, TUScope);
     CheckObjCDeclScope(PDecl);
     
     if (attrList)
       ProcessDeclAttributeList(TUScope, PDecl, attrList);
-    
+    ProcessAPINotes(PDecl);
+    AddPragmaAttributes(TUScope, PDecl);
+
     if (PrevDecl)
       mergeDeclAttributes(PDecl, PrevDecl);
 
@@ -1724,7 +1733,8 @@
                             Decl * const *ProtoRefs,
                             unsigned NumProtoRefs,
                             const SourceLocation *ProtoLocs,
-                            SourceLocation EndProtoLoc) {
+                            SourceLocation EndProtoLoc,
+                            AttributeList *AttrList) {
   ObjCCategoryDecl *CDecl;
   ObjCInterfaceDecl *IDecl = getObjCInterfaceDecl(ClassName, ClassLoc, true);
 
@@ -1801,6 +1811,10 @@
                                             NumProtoRefs, Context); 
   }
 
+  if (AttrList)
+    ProcessDeclAttributeList(TUScope, CDecl, AttrList);
+  AddPragmaAttributes(TUScope, CDecl);
+
   CheckObjCDeclScope(CDecl);
   return ActOnObjCContainerStartDefinition(CDecl);
 }
@@ -1865,9 +1879,10 @@
       CatIDecl->setImplementation(CDecl);
       // Warn on implementating category of deprecated class under 
       // -Wdeprecated-implementations flag.
-      DiagnoseObjCImplementedDeprecations(*this, 
-                                          dyn_cast<NamedDecl>(IDecl), 
-                                          CDecl->getLocation(), 2);
+      DiagnoseObjCImplementedDeprecations(
+          *this,
+          CatIDecl->isDeprecated() ? CatIDecl : dyn_cast<NamedDecl>(IDecl),
+          CDecl->getLocation(), 2);
     }
   }
 
@@ -1948,6 +1963,7 @@
                                       ClassName, /*typeParamList=*/nullptr,
                                       /*PrevDecl=*/nullptr, ClassLoc,
                                       true);
+    AddPragmaAttributes(TUScope, IDecl);
     IDecl->startDefinition();
     if (SDecl) {
       IDecl->setSuperClass(Context.getTrivialTypeSourceInfo(
@@ -3037,7 +3053,8 @@
                                   ClassName, TypeParams, PrevIDecl,
                                   IdentLocs[i]);
     IDecl->setAtEndRange(IdentLocs[i]);
-    
+    ProcessAPINotes(IDecl);
+
     PushOnScopeChains(IDecl, TUScope);
     CheckObjCDeclScope(IDecl);
     DeclsInGroup.push_back(IDecl);
@@ -3837,7 +3854,7 @@
       if (IDecl->getSuperClass() == nullptr) {
         // This class has no superclass, so check that it has been marked with
         // __attribute((objc_root_class)).
-        if (!HasRootClassAttr) {
+        if (!HasRootClassAttr && !IDecl->hasAttr<ObjCCompleteDefinitionAttr>()) {
           SourceLocation DeclLoc(IDecl->getLocation());
           SourceLocation SuperClassLoc(getLocForEndOfToken(DeclLoc));
           Diag(DeclLoc, diag::warn_objc_root_class_missing)
@@ -3932,12 +3949,10 @@
   return (Decl::ObjCDeclQualifier) (unsigned) PQTVal;
 }
 
-/// \brief Check whether the declared result type of the given Objective-C
-/// method declaration is compatible with the method's class.
-///
-static Sema::ResultTypeCompatibilityKind 
-CheckRelatedResultTypeCompatibility(Sema &S, ObjCMethodDecl *Method,
-                                    ObjCInterfaceDecl *CurrentClass) {
+Sema::ResultTypeCompatibilityKind
+Sema::checkRelatedResultTypeCompatibility(
+    const ObjCMethodDecl *Method,
+    const ObjCInterfaceDecl *CurrentClass) {
   QualType ResultType = Method->getReturnType();
 
   // If an Objective-C method inherits its related result type, then its 
@@ -4302,6 +4317,49 @@
   }
 }
 
+/// Verify that the method parameters/return value have types that are supported
+/// by the x86 target.
+static void checkObjCMethodX86VectorTypes(Sema &SemaRef,
+                                          const ObjCMethodDecl *Method) {
+  assert(SemaRef.getASTContext().getTargetInfo().getTriple().getArch() ==
+             llvm::Triple::x86 &&
+         "x86-specific check invoked for a different target");
+  SourceLocation Loc;
+  QualType T;
+  for (const ParmVarDecl *P : Method->parameters()) {
+    if (P->getType()->isVectorType()) {
+      Loc = P->getLocStart();
+      T = P->getType();
+      break;
+    }
+  }
+  if (Loc.isInvalid()) {
+    if (Method->getReturnType()->isVectorType()) {
+      Loc = Method->getReturnTypeSourceRange().getBegin();
+      T = Method->getReturnType();
+    } else
+      return;
+  }
+
+  // Vector parameters/return values are not supported by objc_msgSend on x86 in
+  // iOS < 9 and macOS < 10.11.
+  const auto &Triple = SemaRef.getASTContext().getTargetInfo().getTriple();
+  VersionTuple AcceptedInVersion;
+  if (Triple.getOS() == llvm::Triple::IOS)
+    AcceptedInVersion = VersionTuple(/*Major=*/9);
+  else if (Triple.isMacOSX())
+    AcceptedInVersion = VersionTuple(/*Major=*/10, /*Minor=*/11);
+  else
+    return;
+  if (SemaRef.getASTContext().getTargetInfo().getPlatformMinVersion() >=
+      AcceptedInVersion)
+    return;
+  SemaRef.Diag(Loc, diag::err_objc_method_unsupported_param_ret_type)
+      << T << (Method->getReturnType()->isVectorType() ? /*return value*/ 1
+                                                       : /*parameter*/ 0)
+      << (Triple.isMacOSX() ? "macOS 10.11" : "iOS 9");
+}
+
 Decl *Sema::ActOnMethodDeclaration(
     Scope *S,
     SourceLocation MethodLoc, SourceLocation EndLoc,
@@ -4393,6 +4451,8 @@
 
     // Apply the attributes to the parameter.
     ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
+    ProcessAPINotes(Param);
+    AddPragmaAttributes(TUScope, Param);
 
     if (Param->hasAttr<BlocksAttr>()) {
       Diag(Param->getLocation(), diag::err_block_on_nonlocal);
@@ -4423,6 +4483,8 @@
 
   if (AttrList)
     ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
+  ProcessAPINotes(ObjCMethod);
+  AddPragmaAttributes(TUScope, ObjCMethod);
 
   // Add the method now.
   const ObjCMethodDecl *PrevMethod = nullptr;
@@ -4478,7 +4540,7 @@
   }
 
   ResultTypeCompatibilityKind RTC
-    = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass);
+    = checkRelatedResultTypeCompatibility(ObjCMethod, CurrentClass);
 
   CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC);
 
@@ -4521,6 +4583,10 @@
       ObjCMethod->SetRelatedResultType();
   }
 
+  if (MethodDefinition &&
+      Context.getTargetInfo().getTriple().getArch() == llvm::Triple::x86)
+    checkObjCMethodX86VectorTypes(*this, ObjCMethod);
+
   ActOnDocumentableDecl(ObjCMethod);
 
   return ObjCMethod;
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index de7739b..31c5150 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -171,9 +171,14 @@
   if (AvailabilityResult Result =
           S.ShouldDiagnoseAvailabilityOfDecl(D, &Message)) {
 
-    if (Result == AR_NotYetIntroduced && S.getCurFunctionOrMethodDecl()) {
-      S.getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
-      return;
+    if (Result == AR_NotYetIntroduced) {
+      if (S.getCurFunctionOrMethodDecl()) {
+        S.getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
+        return;
+      } else if (S.getCurBlock() || S.getCurLambda()) {
+        S.getCurFunction()->HasPotentialAvailabilityViolations = true;
+        return;
+      }
     }
 
     const ObjCPropertyDecl *ObjCPDecl = nullptr;
@@ -363,8 +368,18 @@
 
     if (getLangOpts().CUDA && !CheckCUDACall(Loc, FD))
       return true;
+  }
 
-    if (diagnoseArgIndependentDiagnoseIfAttrs(FD, Loc))
+  auto getReferencedObjCProp = [](const NamedDecl *D) ->
+                                      const ObjCPropertyDecl * {
+    if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
+      return MD->findPropertyDecl();
+    return nullptr;
+  };
+  if (const ObjCPropertyDecl *ObjCPDecl = getReferencedObjCProp(D)) {
+    if (diagnoseArgIndependentDiagnoseIfAttrs(ObjCPDecl, Loc))
+      return true;
+  } else if (diagnoseArgIndependentDiagnoseIfAttrs(D, Loc)) {
       return true;
   }
 
@@ -706,8 +721,7 @@
   
   // Loading a __weak object implicitly retains the value, so we need a cleanup to 
   // balance that.
-  if (getLangOpts().ObjCAutoRefCount &&
-      E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
+  if (E->getType().getObjCLifetime() == Qualifiers::OCL_Weak)
     Cleanup.setExprNeedsCleanups(true);
 
   ExprResult Res = ImplicitCastExpr::Create(Context, T, CK_LValueToRValue, E,
@@ -2127,6 +2141,12 @@
   IdentifierInfo *II = Name.getAsIdentifierInfo();
   SourceLocation NameLoc = NameInfo.getLoc();
 
+  if (II && II->isEditorPlaceholder()) {
+    // FIXME: When typed placeholders are supported we can create a typed
+    // placeholder expression node.
+    return ExprError();
+  }
+
   // C++ [temp.dep.expr]p3:
   //   An id-expression is type-dependent if it contains:
   //     -- an identifier that was declared with a dependent type,
@@ -2510,11 +2530,11 @@
           ObjCIvarRefExpr(IV, IV->getUsageType(SelfExpr.get()->getType()), Loc,
                           IV->getLocation(), SelfExpr.get(), true, true);
 
+      if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
+        if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
+          recordUseOfEvaluatedWeak(Result);
+      }
       if (getLangOpts().ObjCAutoRefCount) {
-        if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
-          if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, Loc))
-            recordUseOfEvaluatedWeak(Result);
-        }
         if (CurContext->isClosure())
           Diag(Loc, diag::warn_implicitly_retains_self)
             << FixItHint::CreateInsertion(Loc, "self->");
@@ -7531,22 +7551,6 @@
         return IncompatibleVectors;
       }
     }
-
-    // When the RHS comes from another lax conversion (e.g. binops between
-    // scalars and vectors) the result is canonicalized as a vector. When the
-    // LHS is also a vector, the lax is allowed by the condition above. Handle
-    // the case where LHS is a scalar.
-    if (LHSType->isScalarType()) {
-      const VectorType *VecType = RHSType->getAs<VectorType>();
-      if (VecType && VecType->getNumElements() == 1 &&
-          isLaxVectorConversion(RHSType, LHSType)) {
-        ExprResult *VecExpr = &RHS;
-        *VecExpr = ImpCastExprToType(VecExpr->get(), LHSType, CK_BitCast);
-        Kind = CK_BitCast;
-        return Compatible;
-      }
-    }
-
     return Incompatible;
   }
 
@@ -7648,7 +7652,7 @@
       Kind = CK_BitCast;
       Sema::AssignConvertType result = 
         checkObjCPointerTypesForAssignment(*this, LHSType, RHSType);
-      if (getLangOpts().ObjCAutoRefCount &&
+      if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
           result == Compatible && 
           !CheckObjCARCUnavailableWeakConversion(OrigLHSType, RHSType))
         result = IncompatibleObjCWeakRef;
@@ -7855,7 +7859,7 @@
       if (RHS.isInvalid())
         return Incompatible;
       Sema::AssignConvertType result = Compatible;
-      if (getLangOpts().ObjCAutoRefCount &&
+      if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
           !CheckObjCARCUnavailableWeakConversion(LHSType, RHSType))
         result = IncompatibleObjCWeakRef;
       return result;
@@ -7932,9 +7936,9 @@
     // Check for various Objective-C errors. If we are not reporting
     // diagnostics and just checking for errors, e.g., during overload
     // resolution, return Incompatible to indicate the failure.
-    if (getLangOpts().ObjCAutoRefCount &&
-        CheckObjCARCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
-                               Diagnose, DiagnoseCFAudited) != ACR_okay) {
+    if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
+        CheckObjCConversion(SourceRange(), Ty, E, CCK_ImplicitConversion,
+                            Diagnose, DiagnoseCFAudited) != ACR_okay) {
       if (!Diagnose)
         return Incompatible;
     }
@@ -8081,7 +8085,6 @@
 
   // If there's an ext-vector type and a scalar, try to convert the scalar to
   // the vector element type and splat.
-  // FIXME: this should also work for regular vector types as supported in GCC.
   if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
     if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
                                   LHSVecType->getElementType(), LHSType))
@@ -8094,31 +8097,14 @@
       return RHSType;
   }
 
-  // FIXME: The code below also handles convertion between vectors and
-  // non-scalars, we should break this down into fine grained specific checks
-  // and emit proper diagnostics.
-  QualType VecType = LHSVecType ? LHSType : RHSType;
-  const VectorType *VT = LHSVecType ? LHSVecType : RHSVecType;
-  QualType OtherType = LHSVecType ? RHSType : LHSType;
-  ExprResult *OtherExpr = LHSVecType ? &RHS : &LHS;
-  if (isLaxVectorConversion(OtherType, VecType)) {
-    // If we're allowing lax vector conversions, only the total (data) size
-    // needs to be the same. For non compound assignment, if one of the types is
-    // scalar, the result is always the vector type.
-    if (!IsCompAssign) {
-      *OtherExpr = ImpCastExprToType(OtherExpr->get(), VecType, CK_BitCast);
-      return VecType;
-    // In a compound assignment, lhs += rhs, 'lhs' is a lvalue src, forbidding
-    // any implicit cast. Here, the 'rhs' should be implicit casted to 'lhs'
-    // type. Note that this is already done by non-compound assignments in
-    // CheckAssignmentConstraints. If it's a scalar type, only bitcast for
-    // <1 x T> -> T. The result is also a vector type.
-    } else if (OtherType->isExtVectorType() ||
-               (OtherType->isScalarType() && VT->getNumElements() == 1)) {
-      ExprResult *RHSExpr = &RHS;
-      *RHSExpr = ImpCastExprToType(RHSExpr->get(), LHSType, CK_BitCast);
-      return VecType;
-    }
+  // If we're allowing lax vector conversions, only the total (data) size
+  // needs to be the same.
+  // FIXME: Should we really be allowing this?
+  // FIXME: We really just pick the LHS type arbitrarily?
+  if (isLaxVectorConversion(RHSType, LHSType)) {
+    QualType resultType = LHSType;
+    RHS = ImpCastExprToType(RHS.get(), resultType, CK_BitCast);
+    return resultType;
   }
 
   // Okay, the expression is invalid.
@@ -9374,7 +9360,10 @@
     //   If both operands are pointers, [...] bring them to their composite
     //   pointer type.
     if ((int)LHSType->isPointerType() + (int)RHSType->isPointerType() >=
-        (IsRelational ? 2 : 1)) {
+            (IsRelational ? 2 : 1) &&
+        (!LangOpts.ObjCAutoRefCount ||
+         !(LHSType->isObjCObjectPointerType() ||
+           RHSType->isObjCObjectPointerType()))) {
       if (convertPointersToCompositeType(*this, Loc, LHS, RHS))
         return QualType();
       else
@@ -9560,16 +9549,17 @@
       if (LHSIsNull && !RHSIsNull) {
         Expr *E = LHS.get();
         if (getLangOpts().ObjCAutoRefCount)
-          CheckObjCARCConversion(SourceRange(), RHSType, E, CCK_ImplicitConversion);
+          CheckObjCConversion(SourceRange(), RHSType, E,
+                              CCK_ImplicitConversion);
         LHS = ImpCastExprToType(E, RHSType,
                                 RPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
       }
       else {
         Expr *E = RHS.get();
         if (getLangOpts().ObjCAutoRefCount)
-          CheckObjCARCConversion(SourceRange(), LHSType, E,
-                                 CCK_ImplicitConversion, /*Diagnose=*/true,
-                                 /*DiagnoseCFAudited=*/false, Opc);
+          CheckObjCConversion(SourceRange(), LHSType, E, CCK_ImplicitConversion,
+                              /*Diagnose=*/true,
+                              /*DiagnoseCFAudited=*/false, Opc);
         RHS = ImpCastExprToType(E, LHSType,
                                 LPT ? CK_BitCast :CK_CPointerToObjCPointerCast);
       }
@@ -9724,7 +9714,7 @@
   }
   
   // Return a signed type for the vector.
-  return GetSignedVectorType(vType);
+  return GetSignedVectorType(LHSType);
 }
 
 QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
@@ -10268,7 +10258,10 @@
         const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(InnerLHS);
         if (!DRE || DRE->getDecl()->hasAttr<BlocksAttr>())
           checkRetainCycles(LHSExpr, RHS.get());
+      }
 
+      if (LHSType.getObjCLifetime() == Qualifiers::OCL_Strong ||
+          LHSType.isNonWeakInMRRWithObjCWeak(Context)) {
         // It is safe to assign a weak reference into a strong variable.
         // Although this code can still have problems:
         //   id x = self.weakProp;
@@ -10276,11 +10269,13 @@
         // we do not warn to warn spuriously when 'x' and 'y' are on separate
         // paths through the function. This should be revisited if
         // -Wrepeated-use-of-weak is made flow-sensitive.
+        // For ObjCWeak only, we do not warn if the assign is to a non-weak
+        // variable, which will be valid for the current autorelease scope.
         if (!Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
                              RHS.get()->getLocStart()))
           getCurFunction()->markSafeWeakUse(RHS.get());
 
-      } else if (getLangOpts().ObjCAutoRefCount) {
+      } else if (getLangOpts().ObjCAutoRefCount || getLangOpts().ObjCWeak) {
         checkUnsafeExprAssigns(Loc, LHSExpr, RHS.get());
       }
     }
@@ -11212,7 +11207,7 @@
   
   if (CompResultTy.isNull())
     return new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, ResultTy, VK,
-                                        OK, OpLoc, FPFeatures.fp_contract);
+                                        OK, OpLoc, FPFeatures);
   if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() !=
       OK_ObjCProperty) {
     VK = VK_LValue;
@@ -11220,7 +11215,7 @@
   }
   return new (Context) CompoundAssignOperator(
       LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, CompLHSTy, CompResultTy,
-      OpLoc, FPFeatures.fp_contract);
+      OpLoc, FPFeatures);
 }
 
 /// DiagnoseBitwisePrecedence - Emit a warning when bitwise and comparison
@@ -12409,6 +12404,9 @@
 
   BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
 
+  if (Body && getCurFunction()->HasPotentialAvailabilityViolations)
+    DiagnoseUnguardedAvailabilityViolations(BSI->TheDecl);
+
   // Try to apply the named return value optimization. We have to check again
   // if we can do this, though, because blocks keep return statements around
   // to deduce an implicit return type.
@@ -13577,16 +13575,55 @@
   }
 
   // Warn about implicitly autoreleasing indirect parameters captured by blocks.
-  if (auto *PT = dyn_cast<PointerType>(CaptureType)) {
+  if (const auto *PT = CaptureType->getAs<PointerType>()) {
+    // This function finds out whether there is an AttributedType of kind
+    // attr_objc_ownership in Ty. The existence of AttributedType of kind
+    // attr_objc_ownership implies __autoreleasing was explicitly specified
+    // rather than being added implicitly by the compiler.
+    auto IsObjCOwnershipAttributedType = [](QualType Ty) {
+      while (const auto *AttrTy = Ty->getAs<AttributedType>()) {
+        if (AttrTy->getAttrKind() == AttributedType::attr_objc_ownership)
+          return true;
+
+        // Peel off AttributedTypes that are not of kind objc_ownership.
+        Ty = AttrTy->getModifiedType();
+      }
+
+      return false;
+    };
+
     QualType PointeeTy = PT->getPointeeType();
-    if (isa<ObjCObjectPointerType>(PointeeTy.getCanonicalType()) &&
+
+    if (PointeeTy->getAs<ObjCObjectPointerType>() &&
         PointeeTy.getObjCLifetime() == Qualifiers::OCL_Autoreleasing &&
-        !isa<AttributedType>(PointeeTy)) {
+        !IsObjCOwnershipAttributedType(PointeeTy)) {
       if (BuildAndDiagnose) {
         SourceLocation VarLoc = Var->getLocation();
         S.Diag(Loc, diag::warn_block_capture_autoreleasing);
-        S.Diag(VarLoc, diag::note_declare_parameter_autoreleasing) <<
-            FixItHint::CreateInsertion(VarLoc, "__autoreleasing");
+        {
+          auto AddAutoreleaseNote =
+              S.Diag(VarLoc, diag::note_declare_parameter_autoreleasing);
+          // Provide a fix-it for the '__autoreleasing' keyword at the
+          // appropriate location in the variable's type.
+          if (const auto *TSI = Var->getTypeSourceInfo()) {
+            PointerTypeLoc PTL =
+                TSI->getTypeLoc().getAsAdjusted<PointerTypeLoc>();
+            if (PTL) {
+              SourceLocation Loc = PTL.getPointeeLoc().getEndLoc();
+              Loc = Lexer::getLocForEndOfToken(Loc, 0, S.getSourceManager(),
+                                               S.getLangOpts());
+              if (Loc.isValid()) {
+                StringRef CharAtLoc = Lexer::getSourceText(
+                    CharSourceRange::getCharRange(Loc, Loc.getLocWithOffset(1)),
+                    S.getSourceManager(), S.getLangOpts());
+                AddAutoreleaseNote << FixItHint::CreateInsertion(
+                    Loc, CharAtLoc.empty() || !isWhitespace(CharAtLoc[0])
+                             ? " __autoreleasing "
+                             : " __autoreleasing");
+              }
+            }
+          }
+        }
         S.Diag(VarLoc, diag::note_declare_parameter_strong);
       }
     }
@@ -14227,8 +14264,9 @@
         (SemaRef.CurContext != Var->getDeclContext() &&
          Var->getDeclContext()->isFunctionOrMethod() && Var->hasLocalStorage());
     if (RefersToEnclosingScope) {
-      if (LambdaScopeInfo *const LSI =
-              SemaRef.getCurLambda(/*IgnoreCapturedRegions=*/true)) {
+      LambdaScopeInfo *const LSI =
+          SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true);
+      if (LSI && !LSI->CallOperator->Encloses(Var->getDeclContext())) {
         // If a variable could potentially be odr-used, defer marking it so
         // until we finish analyzing the full expression for any
         // lvalue-to-rvalue
@@ -15374,6 +15412,13 @@
   if (Spec != AvailSpecs.end())
     Version = Spec->getVersion();
 
+  // The use of `@available` in the enclosing function should be analyzed to
+  // warn when it's used inappropriately (i.e. not if(@available)).
+  if (getCurFunctionOrMethodDecl())
+    getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
+  else if (getCurBlock() || getCurLambda())
+    getCurFunction()->HasPotentialAvailabilityViolations = true;
+
   return new (Context)
       ObjCAvailabilityCheckExpr(Version, AtLoc, RParen, Context.BoolTy);
 }
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 3afa95f..ff0d593 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -3703,10 +3703,9 @@
       if (From->getType()->isObjCObjectPointerType() &&
           ToType->isObjCObjectPointerType())
         EmitRelatedResultTypeNote(From);
-    }
-    else if (getLangOpts().ObjCAutoRefCount &&
-             !CheckObjCARCUnavailableWeakConversion(ToType,
-                                                    From->getType())) {
+    } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
+               !CheckObjCARCUnavailableWeakConversion(ToType,
+                                                      From->getType())) {
       if (Action == AA_Initializing)
         Diag(From->getLocStart(),
              diag::err_arc_weak_unavailable_assign);
@@ -3729,8 +3728,8 @@
       (void) PrepareCastToObjCObjectPointer(E);
       From = E.get();
     }
-    if (getLangOpts().ObjCAutoRefCount)
-      CheckObjCARCConversion(SourceRange(), ToType, From, CCK);
+    if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
+      CheckObjCConversion(SourceRange(), ToType, From, CCK);
     From = ImpCastExprToType(From, ToType, Kind, VK_RValue, &BasePath, CCK)
              .get();
     break;
@@ -4495,25 +4494,6 @@
   }
 }
 
-/// \brief Determine whether T has a non-trivial Objective-C lifetime in
-/// ARC mode.
-static bool hasNontrivialObjCLifetime(QualType T) {
-  switch (T.getObjCLifetime()) {
-  case Qualifiers::OCL_ExplicitNone:
-    return false;
-
-  case Qualifiers::OCL_Strong:
-  case Qualifiers::OCL_Weak:
-  case Qualifiers::OCL_Autoreleasing:
-    return true;
-
-  case Qualifiers::OCL_None:
-    return T->isObjCLifetimeType();
-  }
-
-  llvm_unreachable("Unknown ObjC lifetime qualifier");
-}
-
 static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
                                     QualType RhsT, SourceLocation KeyLoc);
 
@@ -4607,10 +4587,9 @@
       return S.canThrow(Result.get()) == CT_Cannot;
 
     if (Kind == clang::TT_IsTriviallyConstructible) {
-      // Under Objective-C ARC, if the destination has non-trivial Objective-C
-      // lifetime, this is a non-trivial construction.
-      if (S.getLangOpts().ObjCAutoRefCount &&
-          hasNontrivialObjCLifetime(T.getNonReferenceType()))
+      // Under Objective-C ARC and Weak, if the destination has non-trivial
+      // Objective-C lifetime, this is a non-trivial construction.
+      if (T.getNonReferenceType().hasNonTrivialObjCLifetime())
         return false;
 
       // The initialization succeeded; now make sure there are no non-trivial
@@ -4829,10 +4808,9 @@
       return Self.canThrow(Result.get()) == CT_Cannot;
 
     if (BTT == BTT_IsTriviallyAssignable) {
-      // Under Objective-C ARC, if the destination has non-trivial Objective-C
-      // lifetime, this is a non-trivial assignment.
-      if (Self.getLangOpts().ObjCAutoRefCount &&
-          hasNontrivialObjCLifetime(LhsT.getNonReferenceType()))
+      // Under Objective-C ARC and Weak, if the destination has non-trivial
+      // Objective-C lifetime, this is a non-trivial assignment.
+      if (LhsT.getNonReferenceType().hasNonTrivialObjCLifetime())
         return false;
 
       return !Result.get()->hasNonTrivialCall(Self.Context);
@@ -5967,9 +5945,21 @@
       } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) {
         D = BoxedExpr->getBoxingMethod();
       } else if (ObjCArrayLiteral *ArrayLit = dyn_cast<ObjCArrayLiteral>(E)) {
+        // Don't do reclaims if we're using the zero-element array
+        // constant.
+        if (ArrayLit->getNumElements() == 0 &&
+            Context.getLangOpts().ObjCRuntime.hasEmptyCollections())
+          return E;
+
         D = ArrayLit->getArrayWithObjectsMethod();
       } else if (ObjCDictionaryLiteral *DictLit
                                         = dyn_cast<ObjCDictionaryLiteral>(E)) {
+        // Don't do reclaims if we're using the zero-element dictionary
+        // constant.
+        if (DictLit->getNumElements() == 0 &&
+            Context.getLangOpts().ObjCRuntime.hasEmptyCollections())
+          return E;
+
         D = DictLit->getDictWithObjectsMethod();
       }
 
@@ -6136,7 +6126,7 @@
         return E;
       return new (Context) BinaryOperator(
           BO->getLHS(), RHS.get(), BO_Comma, BO->getType(), BO->getValueKind(),
-          BO->getObjectKind(), BO->getOperatorLoc(), BO->isFPContractable());
+          BO->getObjectKind(), BO->getOperatorLoc(), BO->getFPFeatures());
     }
   }
 
@@ -6402,6 +6392,23 @@
   return false;
 }
 
+/// \brief Check if it's ok to try and recover dot pseudo destructor calls on
+/// pointer objects.
+static bool
+canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef,
+                                                   QualType DestructedType) {
+  // If this is a record type, check if its destructor is callable.
+  if (auto *RD = DestructedType->getAsCXXRecordDecl()) {
+    if (CXXDestructorDecl *D = SemaRef.LookupDestructor(RD))
+      return SemaRef.CanUseDecl(D, /*TreatUnavailableAsInvalid=*/false);
+    return false;
+  }
+
+  // Otherwise, check if it's a type for which it's valid to use a pseudo-dtor.
+  return DestructedType->isDependentType() || DestructedType->isScalarType() ||
+         DestructedType->isVectorType();
+}
+
 ExprResult Sema::BuildPseudoDestructorExpr(Expr *Base,
                                            SourceLocation OpLoc,
                                            tok::TokenKind OpKind,
@@ -6436,15 +6443,36 @@
       = DestructedTypeInfo->getTypeLoc().getLocalSourceRange().getBegin();
     if (!DestructedType->isDependentType() && !ObjectType->isDependentType()) {
       if (!Context.hasSameUnqualifiedType(DestructedType, ObjectType)) {
-        Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
-          << ObjectType << DestructedType << Base->getSourceRange()
-          << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
+        // Detect dot pseudo destructor calls on pointer objects, e.g.:
+        //   Foo *foo;
+        //   foo.~Foo();
+        if (OpKind == tok::period && ObjectType->isPointerType() &&
+            Context.hasSameUnqualifiedType(DestructedType,
+                                           ObjectType->getPointeeType())) {
+          auto Diagnostic =
+              Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
+              << ObjectType << /*IsArrow=*/0 << Base->getSourceRange();
 
-        // Recover by setting the destructed type to the object type.
-        DestructedType = ObjectType;
-        DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType,
-                                                           DestructedTypeStart);
-        Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
+          // Issue a fixit only when the destructor is valid.
+          if (canRecoverDotPseudoDestructorCallsOnPointerObjects(
+                  *this, DestructedType))
+            Diagnostic << FixItHint::CreateReplacement(OpLoc, "->");
+
+          // Recover by setting the object type to the destructed type and the
+          // operator to '->'.
+          ObjectType = DestructedType;
+          OpKind = tok::arrow;
+        } else {
+          Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
+              << ObjectType << DestructedType << Base->getSourceRange()
+              << DestructedTypeInfo->getTypeLoc().getLocalSourceRange();
+
+          // Recover by setting the destructed type to the object type.
+          DestructedType = ObjectType;
+          DestructedTypeInfo =
+              Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart);
+          Destructed = PseudoDestructorTypeStorage(DestructedTypeInfo);
+        }
       } else if (DestructedType.getObjCLifetime() !=
                                                 ObjectType.getObjCLifetime()) {
 
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp
index c9aa99e..ab0d9c2 100644
--- a/lib/Sema/SemaExprMember.cpp
+++ b/lib/Sema/SemaExprMember.cpp
@@ -1475,7 +1475,7 @@
       }
     }
     bool warn = true;
-    if (S.getLangOpts().ObjCAutoRefCount) {
+    if (S.getLangOpts().ObjCWeak) {
       Expr *BaseExp = BaseExpr.get()->IgnoreParenImpCasts();
       if (UnaryOperator *UO = dyn_cast<UnaryOperator>(BaseExp))
         if (UO->getOpcode() == UO_Deref)
@@ -1502,11 +1502,9 @@
         IV, IV->getUsageType(BaseType), MemberLoc, OpLoc, BaseExpr.get(),
         IsArrow);
 
-    if (S.getLangOpts().ObjCAutoRefCount) {
-      if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
-        if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
-          S.recordUseOfEvaluatedWeak(Result);
-      }
+    if (IV->getType().getObjCLifetime() == Qualifiers::OCL_Weak) {
+      if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, MemberLoc))
+        S.recordUseOfEvaluatedWeak(Result);
     }
 
     return Result;
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 7dbd660..e18ef96 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -2260,6 +2260,53 @@
                      edit::rewriteObjCRedundantCallWithLiteral);
 }
 
+static void checkFoundationAPI(Sema &S, SourceLocation Loc,
+                               const ObjCMethodDecl *Method,
+                               ArrayRef<Expr *> Args, QualType ReceiverType,
+                               bool IsClassObjectCall) {
+  // Check if this is a performSelector method that uses a selector that returns
+  // a record or a vector type.
+  if (Method->getSelector().getMethodFamily() != OMF_performSelector ||
+      Args.empty())
+    return;
+  const auto *SE = dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens());
+  if (!SE)
+    return;
+  ObjCMethodDecl *ImpliedMethod;
+  if (!IsClassObjectCall) {
+    const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>();
+    if (!OPT || !OPT->getInterfaceDecl())
+      return;
+    ImpliedMethod =
+        OPT->getInterfaceDecl()->lookupInstanceMethod(SE->getSelector());
+    if (!ImpliedMethod)
+      ImpliedMethod =
+          OPT->getInterfaceDecl()->lookupPrivateMethod(SE->getSelector());
+  } else {
+    const auto *IT = ReceiverType->getAs<ObjCInterfaceType>();
+    if (!IT)
+      return;
+    ImpliedMethod = IT->getDecl()->lookupClassMethod(SE->getSelector());
+    if (!ImpliedMethod)
+      ImpliedMethod =
+          IT->getDecl()->lookupPrivateClassMethod(SE->getSelector());
+  }
+  if (!ImpliedMethod)
+    return;
+  QualType Ret = ImpliedMethod->getReturnType();
+  if (Ret->isRecordType() || Ret->isVectorType() || Ret->isExtVectorType()) {
+    QualType Ret = ImpliedMethod->getReturnType();
+    S.Diag(Loc, diag::warn_objc_unsafe_perform_selector)
+        << Method->getSelector()
+        << (!Ret->isRecordType()
+                ? /*Vector*/ 2
+                : Ret->isUnionType() ? /*Union*/ 1 : /*Struct*/ 0);
+    S.Diag(ImpliedMethod->getLocStart(),
+           diag::note_objc_unsafe_perform_selector_method_declared_here)
+        << ImpliedMethod->getSelector() << Ret;
+  }
+}
+
 /// \brief Diagnose use of %s directive in an NSString which is being passed
 /// as formatting string to formatting method.
 static void
@@ -2462,6 +2509,9 @@
     if (!isImplicit)
       checkCocoaAPI(*this, Result);
   }
+  if (Method)
+    checkFoundationAPI(*this, SelLoc, Method, makeArrayRef(Args, NumArgs),
+                       ReceiverType, /*IsClassObjectCall=*/true);
   return MaybeBindToTemporary(Result);
 }
 
@@ -2501,6 +2551,24 @@
                               /*isImplicit=*/true);
 }
 
+static bool isMethodDeclaredInRootProtocol(Sema &S, const ObjCMethodDecl *M) {
+  if (!S.NSAPIObj)
+    return false;
+  const auto *Protocol = dyn_cast<ObjCProtocolDecl>(M->getDeclContext());
+  if (!Protocol)
+    return false;
+  const IdentifierInfo *II = S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSObject);
+  if (const auto *RootClass = dyn_cast_or_null<ObjCInterfaceDecl>(
+          S.LookupSingleName(S.TUScope, II, Protocol->getLocStart(),
+                             Sema::LookupOrdinaryName))) {
+    for (const ObjCProtocolDecl *P : RootClass->all_referenced_protocols()) {
+      if (P->getCanonicalDecl() == Protocol->getCanonicalDecl())
+        return true;
+    }
+  }
+  return false;
+}
+
 /// \brief Build an Objective-C instance message expression.
 ///
 /// This routine takes care of both normal instance messages and
@@ -2676,7 +2744,7 @@
         if (!Method) {
           Method = LookupMethodInQualifiedType(Sel, QClassTy, true);
           // warn if instance method found for a Class message.
-          if (Method) {
+          if (Method && !isMethodDeclaredInRootProtocol(*this, Method)) {
             Diag(SelLoc, diag::warn_instance_method_on_class_found)
               << Method->getSelector() << Sel;
             Diag(Method->getLocation(), diag::note_method_declared_at)
@@ -2920,7 +2988,8 @@
     
     case OMF_performSelector:
       if (Method && NumArgs >= 1) {
-        if (ObjCSelectorExpr *SelExp = dyn_cast<ObjCSelectorExpr>(Args[0])) {
+        if (const auto *SelExp =
+                dyn_cast<ObjCSelectorExpr>(Args[0]->IgnoreParens())) {
           Selector ArgSel = SelExp->getSelector();
           ObjCMethodDecl *SelMethod = 
             LookupInstanceMethodInGlobalPool(ArgSel,
@@ -2936,7 +3005,6 @@
               case OMF_copy:
               case OMF_mutableCopy:
               case OMF_new:
-              case OMF_self:
               case OMF_init:
                 // Issue error, unless ns_returns_not_retained.
                 if (!SelMethod->hasAttr<NSReturnsNotRetainedAttr>()) {
@@ -2987,6 +3055,26 @@
     if (!isImplicit)
       checkCocoaAPI(*this, Result);
   }
+  if (Method) {
+    bool IsClassObjectCall = ClassMessage;
+    // 'self' message receivers in class methods should be treated as message
+    // sends to the class object in order for the semantic checks to be
+    // performed correctly. Messages to 'super' already count as class messages,
+    // so they don't need to be handled here.
+    if (Receiver && isSelfExpr(Receiver)) {
+      if (const auto *OPT = ReceiverType->getAs<ObjCObjectPointerType>()) {
+        if (OPT->getObjectType()->isObjCClass()) {
+          if (const auto *CurMeth = getCurMethodDecl()) {
+            IsClassObjectCall = true;
+            ReceiverType =
+                Context.getObjCInterfaceType(CurMeth->getClassInterface());
+          }
+        }
+      }
+    }
+    checkFoundationAPI(*this, SelLoc, Method, makeArrayRef(Args, NumArgs),
+                       ReceiverType, IsClassObjectCall);
+  }
 
   if (getLangOpts().ObjCAutoRefCount) {
     // In ARC, annotate delegate init calls.
@@ -3006,7 +3094,9 @@
     // In ARC, check for message sends which are likely to introduce
     // retain cycles.
     checkRetainCycles(Result);
+  }
 
+  if (getLangOpts().ObjCWeak) {
     if (!isImplicit && Method) {
       if (const ObjCPropertyDecl *Prop = Method->findPropertyDecl()) {
         bool IsWeak =
@@ -3259,7 +3349,7 @@
       if (isAnyRetainable(TargetClass) &&
           isAnyRetainable(SourceClass) &&
           var &&
-          var->getStorageClass() == SC_Extern &&
+          !var->hasDefinition(Context) &&
           var->getType().isConstQualified()) {
 
         // In system headers, they can also be assumed to be immune to retains.
@@ -4012,11 +4102,10 @@
 }
 
 Sema::ARCConversionResult
-Sema::CheckObjCARCConversion(SourceRange castRange, QualType castType,
-                             Expr *&castExpr, CheckedConversionKind CCK,
-                             bool Diagnose,
-                             bool DiagnoseCFAudited,
-                             BinaryOperatorKind Opc) {
+Sema::CheckObjCConversion(SourceRange castRange, QualType castType,
+                          Expr *&castExpr, CheckedConversionKind CCK,
+                          bool Diagnose, bool DiagnoseCFAudited,
+                          BinaryOperatorKind Opc) {
   QualType castExprType = castExpr->getType();
 
   // For the purposes of the classification, we assume reference types
@@ -4056,7 +4145,12 @@
     }
     return ACR_okay;
   }
-  
+
+  // The life-time qualifier cast check above is all we need for ObjCWeak.
+  // ObjCAutoRefCount has more restrictions on what is legal.
+  if (!getLangOpts().ObjCAutoRefCount)
+    return ACR_okay;
+
   if (isAnyCLike(exprACTC) && isAnyCLike(castACTC)) return ACR_okay;
 
   // Allow all of these types to be cast to integer types (but not
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index b053c83..7704fb8 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -945,6 +945,7 @@
   case InitializedEntity::EK_Base:
   case InitializedEntity::EK_Delegating:
   case InitializedEntity::EK_BlockElement:
+  case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
   case InitializedEntity::EK_Binding:
     llvm_unreachable("unexpected braced scalar init");
   }
@@ -2237,6 +2238,10 @@
     }
 
     unsigned FieldIndex = 0;
+
+    if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+      FieldIndex = CXXRD->getNumBases();
+
     for (auto *FI : RT->getDecl()->fields()) {
       if (FI->isUnnamedBitfield())
         continue;
@@ -2260,15 +2265,17 @@
           assert(StructuredList->getNumInits() == 1
                  && "A union should never have more than one initializer!");
 
-          // We're about to throw away an initializer, emit warning.
-          SemaRef.Diag(D->getFieldLoc(),
-                       diag::warn_initializer_overrides)
-            << D->getSourceRange();
           Expr *ExistingInit = StructuredList->getInit(0);
-          SemaRef.Diag(ExistingInit->getLocStart(),
-                       diag::note_previous_initializer)
-            << /*FIXME:has side effects=*/0
-            << ExistingInit->getSourceRange();
+          if (ExistingInit) {
+            // We're about to throw away an initializer, emit warning.
+            SemaRef.Diag(D->getFieldLoc(),
+                         diag::warn_initializer_overrides)
+              << D->getSourceRange();
+            SemaRef.Diag(ExistingInit->getLocStart(),
+                         diag::note_previous_initializer)
+              << /*FIXME:has side effects=*/0
+              << ExistingInit->getSourceRange();
+          }
 
           // remove existing initializer
           StructuredList->resizeInits(SemaRef.Context, 0);
@@ -2925,6 +2932,7 @@
   case EK_VectorElement:
   case EK_ComplexElement:
   case EK_BlockElement:
+  case EK_LambdaToBlockConversionBlockElement:
   case EK_CompoundLiteralInit:
   case EK_RelatedResult:
     return DeclarationName();
@@ -2954,6 +2962,7 @@
   case EK_VectorElement:
   case EK_ComplexElement:
   case EK_BlockElement:
+  case EK_LambdaToBlockConversionBlockElement:
   case EK_LambdaCapture:
   case EK_CompoundLiteralInit:
   case EK_RelatedResult:
@@ -2983,6 +2992,7 @@
   case EK_VectorElement:
   case EK_ComplexElement:
   case EK_BlockElement:
+  case EK_LambdaToBlockConversionBlockElement:
   case EK_LambdaCapture:
   case EK_RelatedResult:
     break;
@@ -3016,6 +3026,9 @@
   case EK_VectorElement: OS << "VectorElement " << Index; break;
   case EK_ComplexElement: OS << "ComplexElement " << Index; break;
   case EK_BlockElement: OS << "Block"; break;
+  case EK_LambdaToBlockConversionBlockElement:
+    OS << "Block (lambda)";
+    break;
   case EK_LambdaCapture:
     OS << "LambdaCapture ";
     OS << DeclarationName(Capture.VarID);
@@ -3611,9 +3624,13 @@
   //       destination object.
   // Per DR (no number yet), this does not apply when initializing a base
   // class or delegating to another constructor from a mem-initializer.
+  // ObjC++: Lambda captured by the block in the lambda to block conversion
+  // should avoid copy elision.
   if (S.getLangOpts().CPlusPlus1z &&
       Entity.getKind() != InitializedEntity::EK_Base &&
       Entity.getKind() != InitializedEntity::EK_Delegating &&
+      Entity.getKind() !=
+          InitializedEntity::EK_LambdaToBlockConversionBlockElement &&
       UnwrappedArgs.size() == 1 && UnwrappedArgs[0]->isRValue() &&
       S.Context.hasSameUnqualifiedType(UnwrappedArgs[0]->getType(), DestType)) {
     // Convert qualifications if necessary.
@@ -3977,6 +3994,8 @@
       ImplicitConversionSequence ICS;
       ICS.setStandard();
       ICS.Standard.setAsIdentityConversion();
+      if (!E->isRValue())
+        ICS.Standard.First = ICK_Lvalue_To_Rvalue;
       // If E is of a floating-point type, then the conversion is ill-formed
       // due to narrowing, but go through the motions in order to produce the
       // right diagnostic.
@@ -5472,6 +5491,7 @@
   case InitializedEntity::EK_VectorElement:
   case InitializedEntity::EK_ComplexElement:
   case InitializedEntity::EK_BlockElement:
+  case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
   case InitializedEntity::EK_LambdaCapture:
   case InitializedEntity::EK_CompoundLiteralInit:
     return Sema::AA_Initializing;
@@ -5495,6 +5515,7 @@
   case InitializedEntity::EK_ComplexElement:
   case InitializedEntity::EK_Exception:
   case InitializedEntity::EK_BlockElement:
+  case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
   case InitializedEntity::EK_LambdaCapture:
   case InitializedEntity::EK_CompoundLiteralInit:
     return false;
@@ -5521,6 +5542,7 @@
     case InitializedEntity::EK_VectorElement:
     case InitializedEntity::EK_ComplexElement:
     case InitializedEntity::EK_BlockElement:
+    case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
     case InitializedEntity::EK_LambdaCapture:
       return false;
 
@@ -5568,6 +5590,7 @@
   case InitializedEntity::EK_VectorElement:
   case InitializedEntity::EK_ComplexElement:
   case InitializedEntity::EK_BlockElement:
+  case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
   case InitializedEntity::EK_CompoundLiteralInit:
   case InitializedEntity::EK_RelatedResult:
     return Initializer->getLocStart();
@@ -6004,6 +6027,7 @@
   case InitializedEntity::EK_ArrayElement:
   case InitializedEntity::EK_VectorElement:
   case InitializedEntity::EK_BlockElement:
+  case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
   case InitializedEntity::EK_ComplexElement:
     // Could not determine what the full initialization is. Assume it might not
     // outlive the full-expression.
@@ -6092,6 +6116,7 @@
     return FallbackDecl;
 
   case InitializedEntity::EK_BlockElement:
+  case InitializedEntity::EK_LambdaToBlockConversionBlockElement:
   case InitializedEntity::EK_LambdaCapture:
   case InitializedEntity::EK_Exception:
   case InitializedEntity::EK_VectorElement:
@@ -6670,14 +6695,10 @@
                                   /*IsInitializerList=*/false,
                                   ExtendingEntity->getDecl());
 
-      // If we're binding to an Objective-C object that has lifetime, we
-      // need cleanups. Likewise if we're extending this temporary to automatic
-      // storage duration -- we need to register its cleanup during the
-      // full-expression's cleanups.
-      if ((S.getLangOpts().ObjCAutoRefCount &&
-           MTE->getType()->isObjCLifetimeType()) ||
-          (MTE->getStorageDuration() == SD_Automatic &&
-           MTE->getType().isDestructedType()))
+      // If we're extending this temporary to automatic storage duration -- we
+      // need to register its cleanup during the full-expression's cleanups.
+      if (MTE->getStorageDuration() == SD_Automatic &&
+          MTE->getType().isDestructedType())
         S.Cleanup.setExprNeedsCleanups(true);
 
       CurInit = MTE;
diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp
index a0d5749..df25900 100644
--- a/lib/Sema/SemaLambda.cpp
+++ b/lib/Sema/SemaLambda.cpp
@@ -1607,10 +1607,9 @@
   CallOperator->markUsed(Context);
 
   ExprResult Init = PerformCopyInitialization(
-                      InitializedEntity::InitializeBlock(ConvLocation, 
-                                                         Src->getType(), 
-                                                         /*NRVO=*/false),
-                      CurrentLocation, Src);
+      InitializedEntity::InitializeLambdaToBlock(ConvLocation, Src->getType(),
+                                                 /*NRVO=*/false),
+      CurrentLocation, Src);
   if (!Init.isInvalid())
     Init = ActOnFinishFullExpr(Init.get());
   
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index e2cb2c8..50439ca 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -3430,6 +3430,12 @@
           SM == ShadowMaps.rbegin())
         continue;
 
+      // A shadow declaration that's created by a resolved using declaration
+      // is not hidden by the same using declaration.
+      if (isa<UsingShadowDecl>(ND) && isa<UsingDecl>(D) &&
+          cast<UsingShadowDecl>(ND)->getUsingDecl() == D)
+        continue;
+
       // We've found a declaration that hides this one.
       return D;
     }
@@ -3442,7 +3448,8 @@
                                bool QualifiedNameLookup,
                                bool InBaseClass,
                                VisibleDeclConsumer &Consumer,
-                               VisibleDeclsRecord &Visited) {
+                               VisibleDeclsRecord &Visited,
+                               bool IncludeDependentBases = false) {
   if (!Ctx)
     return;
 
@@ -3498,7 +3505,8 @@
     ShadowContextRAII Shadow(Visited);
     for (auto I : Ctx->using_directives()) {
       LookupVisibleDecls(I->getNominatedNamespace(), Result,
-                         QualifiedNameLookup, InBaseClass, Consumer, Visited);
+                         QualifiedNameLookup, InBaseClass, Consumer, Visited,
+                         IncludeDependentBases);
     }
   }
 
@@ -3510,14 +3518,28 @@
     for (const auto &B : Record->bases()) {
       QualType BaseType = B.getType();
 
-      // Don't look into dependent bases, because name lookup can't look
-      // there anyway.
-      if (BaseType->isDependentType())
-        continue;
-
-      const RecordType *Record = BaseType->getAs<RecordType>();
-      if (!Record)
-        continue;
+      RecordDecl *RD;
+      if (BaseType->isDependentType()) {
+        if (!IncludeDependentBases) {
+          // Don't look into dependent bases, because name lookup can't look
+          // there anyway.
+          continue;
+        }
+        const auto *TST = BaseType->getAs<TemplateSpecializationType>();
+        if (!TST)
+          continue;
+        TemplateName TN = TST->getTemplateName();
+        const auto *TD =
+            dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
+        if (!TD)
+          continue;
+        RD = TD->getTemplatedDecl();
+      } else {
+        const auto *Record = BaseType->getAs<RecordType>();
+        if (!Record)
+          continue;
+        RD = Record->getDecl();
+      }
 
       // FIXME: It would be nice to be able to determine whether referencing
       // a particular member would be ambiguous. For example, given
@@ -3540,8 +3562,8 @@
 
       // Find results in this base class (and its bases).
       ShadowContextRAII Shadow(Visited);
-      LookupVisibleDecls(Record->getDecl(), Result, QualifiedNameLookup,
-                         true, Consumer, Visited);
+      LookupVisibleDecls(RD, Result, QualifiedNameLookup, true, Consumer,
+                         Visited, IncludeDependentBases);
     }
   }
 
@@ -3710,7 +3732,8 @@
 
 void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
                               VisibleDeclConsumer &Consumer,
-                              bool IncludeGlobalScope) {
+                              bool IncludeGlobalScope,
+                              bool IncludeDependentBases) {
   LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
   Result.setAllowHidden(Consumer.includeHiddenDecls());
   VisibleDeclsRecord Visited;
@@ -3718,7 +3741,8 @@
     Visited.visitedContext(Context.getTranslationUnitDecl());
   ShadowContextRAII Shadow(Visited);
   ::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true,
-                       /*InBaseClass=*/false, Consumer, Visited);
+                       /*InBaseClass=*/false, Consumer, Visited,
+                       IncludeDependentBases);
 }
 
 /// LookupOrCreateLabel - Do a name lookup of a label with the specified name.
@@ -4958,8 +4982,6 @@
 
 void Sema::diagnoseMissingImport(SourceLocation Loc, NamedDecl *Decl,
                                  MissingImportKind MIK, bool Recover) {
-  assert(!isVisible(Decl) && "missing import for non-hidden decl?");
-
   // Suggest importing a module providing the definition of this entity, if
   // possible.
   NamedDecl *Def = getDefinitionToImport(Decl);
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 3481b82..ae86bec 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -200,9 +200,10 @@
   if (ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(ClassDecl)) {
     if (CDecl->IsClassExtension()) {
       Res = HandlePropertyInClassExtension(S, AtLoc, LParenLoc,
-                                           FD, GetterSel, SetterSel,
-                                           isReadWrite,
-                                           Attributes,
+                                           FD,
+                                           GetterSel, ODS.getGetterNameLoc(),
+                                           SetterSel, ODS.getSetterNameLoc(),
+                                           isReadWrite, Attributes,
                                            ODS.getPropertyAttributes(),
                                            T, TSI, MethodImplKind);
       if (!Res)
@@ -212,9 +213,10 @@
 
   if (!Res) {
     Res = CreatePropertyDecl(S, ClassDecl, AtLoc, LParenLoc, FD,
-                             GetterSel, SetterSel, isReadWrite,
-                             Attributes, ODS.getPropertyAttributes(),
-                             T, TSI, MethodImplKind);
+                             GetterSel, ODS.getGetterNameLoc(), SetterSel,
+                             ODS.getSetterNameLoc(), isReadWrite, Attributes,
+                             ODS.getPropertyAttributes(), T, TSI,
+                             MethodImplKind);
     if (lexicalDC)
       Res->setLexicalDeclContext(lexicalDC);
   }
@@ -412,7 +414,10 @@
                                      SourceLocation AtLoc,
                                      SourceLocation LParenLoc,
                                      FieldDeclarator &FD,
-                                     Selector GetterSel, Selector SetterSel,
+                                     Selector GetterSel,
+                                     SourceLocation GetterNameLoc,
+                                     Selector SetterSel,
+                                     SourceLocation SetterNameLoc,
                                      const bool isReadWrite,
                                      unsigned &Attributes,
                                      const unsigned AttributesAsWritten,
@@ -512,7 +517,8 @@
   // Create a new ObjCPropertyDecl with the DeclContext being
   // the class extension.
   ObjCPropertyDecl *PDecl = CreatePropertyDecl(S, CDecl, AtLoc, LParenLoc,
-                                               FD, GetterSel, SetterSel,
+                                               FD, GetterSel, GetterNameLoc,
+                                               SetterSel, SetterNameLoc,
                                                isReadWrite,
                                                Attributes, AttributesAsWritten,
                                                T, TSI, MethodImplKind, DC);
@@ -562,7 +568,9 @@
                                            SourceLocation LParenLoc,
                                            FieldDeclarator &FD,
                                            Selector GetterSel,
+                                           SourceLocation GetterNameLoc,
                                            Selector SetterSel,
+                                           SourceLocation SetterNameLoc,
                                            const bool isReadWrite,
                                            const unsigned Attributes,
                                            const unsigned AttributesAsWritten,
@@ -636,15 +644,15 @@
     PDecl->setInvalidDecl();
   }
 
-  ProcessDeclAttributes(S, PDecl, FD.D);
-
   // Regardless of setter/getter attribute, we save the default getter/setter
   // selector names in anticipation of declaration of setter/getter methods.
-  PDecl->setGetterName(GetterSel);
-  PDecl->setSetterName(SetterSel);
+  PDecl->setGetterName(GetterSel, GetterNameLoc);
+  PDecl->setSetterName(SetterSel, SetterNameLoc);
   PDecl->setPropertyAttributesAsWritten(
                           makePropertyAttributesAsWritten(AttributesAsWritten));
 
+  ProcessDeclAttributes(S, PDecl, FD.D);
+
   if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
 
@@ -2177,12 +2185,9 @@
   DiagnosePropertyAccessorMismatch(property, GetterMethod,
                                    property->getLocation());
 
-  if (SetterMethod) {
-    ObjCPropertyDecl::PropertyAttributeKind CAttr =
-      property->getPropertyAttributes();
-    if ((!(CAttr & ObjCPropertyDecl::OBJC_PR_readonly)) &&
-        Context.getCanonicalType(SetterMethod->getReturnType()) !=
-            Context.VoidTy)
+  if (!property->isReadOnly() && SetterMethod) {
+    if (Context.getCanonicalType(SetterMethod->getReturnType()) !=
+        Context.VoidTy)
       Diag(SetterMethod->getLocation(), diag::err_setter_type_void);
     if (SetterMethod->param_size() != 1 ||
         !Context.hasSameUnqualifiedType(
@@ -2250,6 +2255,8 @@
           SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section,
                                       SA->getName(), Loc));
 
+    ProcessAPINotes(GetterMethod);
+
     if (getLangOpts().ObjCAutoRefCount)
       CheckARCMethodDecl(GetterMethod);
   } else
@@ -2315,6 +2322,9 @@
         SetterMethod->addAttr(
             SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section,
                                         SA->getName(), Loc));
+
+    ProcessAPINotes(SetterMethod);
+
       // It's possible for the user to have set a very odd custom
       // setter selector that causes it to have a method family.
       if (getLangOpts().ObjCAutoRefCount)
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index f976b76..aed258a 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -4048,7 +4048,7 @@
         = S.Context.canAssignObjCInterfaces(ToPtr1, ToPtr2);
       bool ToAssignRight
         = S.Context.canAssignObjCInterfaces(ToPtr2, ToPtr1);
-      
+
       // A conversion to an a non-id object pointer type or qualified 'id' 
       // type is better than a conversion to 'id'.
       if (ToPtr1->isObjCIdType() &&
@@ -4082,11 +4082,25 @@
         return ImplicitConversionSequence::Better;
 
       //   -- "conversion of C* to B* is better than conversion of C* to A*,"
-      if (S.Context.hasSameType(FromType1, FromType2) && 
+      if (S.Context.hasSameType(FromType1, FromType2) &&
           !FromPtr1->isObjCIdType() && !FromPtr1->isObjCClassType() &&
-          (ToAssignLeft != ToAssignRight))
+          (ToAssignLeft != ToAssignRight)) {
+        if (FromPtr1->isSpecialized()) {
+          // "conversion of B<A> * to B * is better than conversion of B * to
+          // C *.
+          bool IsFirstSame =
+              FromPtr1->getInterfaceDecl() == ToPtr1->getInterfaceDecl();
+          bool IsSecondSame =
+              FromPtr1->getInterfaceDecl() == ToPtr2->getInterfaceDecl();
+          if (IsFirstSame) {
+            if (!IsSecondSame)
+              return ImplicitConversionSequence::Better;
+          } else if (IsSecondSame)
+            return ImplicitConversionSequence::Worse;
+        }
         return ToAssignLeft? ImplicitConversionSequence::Worse
                            : ImplicitConversionSequence::Better;
+      }
 
       //   -- "conversion of B* to A* is better than conversion of C* to A*,"
       if (S.Context.hasSameUnqualifiedType(ToType1, ToType2) &&
@@ -6228,11 +6242,11 @@
 }
 
 template <typename CheckFn>
-static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const FunctionDecl *FD,
+static bool diagnoseDiagnoseIfAttrsWith(Sema &S, const NamedDecl *ND,
                                         bool ArgDependent, SourceLocation Loc,
                                         CheckFn &&IsSuccessful) {
   SmallVector<const DiagnoseIfAttr *, 8> Attrs;
-  for (const auto *DIA : FD->specific_attrs<DiagnoseIfAttr>()) {
+  for (const auto *DIA : ND->specific_attrs<DiagnoseIfAttr>()) {
     if (ArgDependent == DIA->getArgDependent())
       Attrs.push_back(DIA);
   }
@@ -6279,16 +6293,16 @@
         // EvaluateWithSubstitution only cares about the position of each
         // argument in the arg list, not the ParmVarDecl* it maps to.
         if (!DIA->getCond()->EvaluateWithSubstitution(
-                Result, Context, DIA->getParent(), Args, ThisArg))
+                Result, Context, cast<FunctionDecl>(DIA->getParent()), Args, ThisArg))
           return false;
         return Result.isInt() && Result.getInt().getBoolValue();
       });
 }
 
-bool Sema::diagnoseArgIndependentDiagnoseIfAttrs(const FunctionDecl *Function,
+bool Sema::diagnoseArgIndependentDiagnoseIfAttrs(const NamedDecl *ND,
                                                  SourceLocation Loc) {
   return diagnoseDiagnoseIfAttrsWith(
-      *this, Function, /*ArgDependent=*/false, Loc,
+      *this, ND, /*ArgDependent=*/false, Loc,
       [&](const DiagnoseIfAttr *DIA) {
         bool Result;
         return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) &&
@@ -6307,30 +6321,45 @@
   for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) {
     NamedDecl *D = F.getDecl()->getUnderlyingDecl();
     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
-      if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic())
+      if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) {
+        QualType ObjectType;
+        Expr::Classification ObjectClassification;
+        if (Expr *E = Args[0]) {
+          // Use the explit base to restrict the lookup:
+          ObjectType = E->getType();
+          ObjectClassification = E->Classify(Context);
+        } // .. else there is an implit base.
         AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(),
-                           cast<CXXMethodDecl>(FD)->getParent(),
-                           Args[0]->getType(), Args[0]->Classify(Context),
-                           Args.slice(1), CandidateSet, SuppressUserConversions,
-                           PartialOverloading);
-      else
+                           cast<CXXMethodDecl>(FD)->getParent(), ObjectType,
+                           ObjectClassification, Args.slice(1), CandidateSet,
+                           SuppressUserConversions, PartialOverloading);
+      } else {
         AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet,
                              SuppressUserConversions, PartialOverloading);
+      }
     } else {
       FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D);
       if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) &&
-          !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic())
+          !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic()) {
+        QualType ObjectType;
+        Expr::Classification ObjectClassification;
+        if (Expr *E = Args[0]) {
+          // Use the explit base to restrict the lookup:
+          ObjectType = E->getType();
+          ObjectClassification = E->Classify(Context);
+        } // .. else there is an implit base.
         AddMethodTemplateCandidate(
             FunTmpl, F.getPair(),
             cast<CXXRecordDecl>(FunTmpl->getDeclContext()),
-            ExplicitTemplateArgs, Args[0]->getType(),
-            Args[0]->Classify(Context), Args.slice(1), CandidateSet,
-            SuppressUserConversions, PartialOverloading);
-      else
+            ExplicitTemplateArgs, ObjectType, ObjectClassification,
+            Args.slice(1), CandidateSet, SuppressUserConversions,
+            PartialOverloading);
+      } else {
         AddTemplateOverloadCandidate(FunTmpl, F.getPair(),
                                      ExplicitTemplateArgs, Args,
                                      CandidateSet, SuppressUserConversions,
                                      PartialOverloading);
+      }
     }
   }
 }
@@ -11385,6 +11414,10 @@
       assert(!KnownValid && "Explicit template arguments?");
       return;
     }
+    // Prevent ill-formed function decls to be added as overload candidates.
+    if (!dyn_cast<FunctionProtoType>(Func->getType()->getAs<FunctionType>()))
+      return;
+
     S.AddOverloadCandidate(Func, FoundDecl, Args, CandidateSet,
                            /*SuppressUsedConversions=*/false,
                            PartialOverloading);
@@ -11957,7 +11990,7 @@
                                      Fns.begin(), Fns.end());
     return new (Context)
         CXXOperatorCallExpr(Context, Op, Fn, ArgsArray, Context.DependentTy,
-                            VK_RValue, OpLoc, false);
+                            VK_RValue, OpLoc, FPOptions());
   }
 
   // Build an empty overload set.
@@ -12027,7 +12060,7 @@
       Args[0] = Input;
       CallExpr *TheCall =
         new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(), ArgsArray,
-                                          ResultTy, VK, OpLoc, false);
+                                          ResultTy, VK, OpLoc, FPOptions());
 
       if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall, FnDecl))
         return ExprError();
@@ -12125,12 +12158,12 @@
       if (Opc <= BO_Assign || Opc > BO_OrAssign)
         return new (Context) BinaryOperator(
             Args[0], Args[1], Opc, Context.DependentTy, VK_RValue, OK_Ordinary,
-            OpLoc, FPFeatures.fp_contract);
+            OpLoc, FPFeatures);
 
       return new (Context) CompoundAssignOperator(
           Args[0], Args[1], Opc, Context.DependentTy, VK_LValue, OK_Ordinary,
           Context.DependentTy, Context.DependentTy, OpLoc,
-          FPFeatures.fp_contract);
+          FPFeatures);
     }
 
     // FIXME: save results of ADL from here?
@@ -12144,7 +12177,7 @@
                                      Fns.begin(), Fns.end());
     return new (Context)
         CXXOperatorCallExpr(Context, Op, Fn, Args, Context.DependentTy,
-                            VK_RValue, OpLoc, FPFeatures.fp_contract);
+                            VK_RValue, OpLoc, FPFeatures);
   }
 
   // Always do placeholder-like conversions on the RHS.
@@ -12259,7 +12292,7 @@
         CXXOperatorCallExpr *TheCall =
           new (Context) CXXOperatorCallExpr(Context, Op, FnExpr.get(),
                                             Args, ResultTy, VK, OpLoc,
-                                            FPFeatures.fp_contract);
+                                            FPFeatures);
 
         if (CheckCallReturnType(FnDecl->getReturnType(), OpLoc, TheCall,
                                 FnDecl))
@@ -12407,7 +12440,7 @@
 
     return new (Context)
         CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args,
-                            Context.DependentTy, VK_RValue, RLoc, false);
+                            Context.DependentTy, VK_RValue, RLoc, FPOptions());
   }
 
   // Handle placeholders on both operands.
@@ -12483,7 +12516,7 @@
           new (Context) CXXOperatorCallExpr(Context, OO_Subscript,
                                             FnExpr.get(), Args,
                                             ResultTy, VK, RLoc,
-                                            false);
+                                            FPOptions());
 
         if (CheckCallReturnType(FnDecl->getReturnType(), LLoc, TheCall, FnDecl))
           return ExprError();
@@ -13046,7 +13079,7 @@
 
   CXXOperatorCallExpr *TheCall = new (Context)
       CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy,
-                          VK, RParenLoc, false);
+                          VK, RParenLoc, FPOptions());
 
   if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method))
     return true;
@@ -13226,7 +13259,7 @@
   ResultTy = ResultTy.getNonLValueExprType(Context);
   CXXOperatorCallExpr *TheCall =
     new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr.get(),
-                                      Base, ResultTy, VK, OpLoc, false);
+                                      Base, ResultTy, VK, OpLoc, FPOptions());
 
   if (CheckCallReturnType(Method->getReturnType(), OpLoc, TheCall, Method))
     return ExprError();
diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp
index 8e53fda..b6b429d 100644
--- a/lib/Sema/SemaPseudoObject.cpp
+++ b/lib/Sema/SemaPseudoObject.cpp
@@ -447,7 +447,8 @@
     syntactic = new (S.Context) BinaryOperator(syntacticLHS, capturedRHS,
                                                opcode, capturedRHS->getType(),
                                                capturedRHS->getValueKind(),
-                                               OK_Ordinary, opcLoc, false);
+                                               OK_Ordinary, opcLoc,
+                                               FPOptions());
   } else {
     ExprResult opLHS = buildGet();
     if (opLHS.isInvalid()) return ExprError();
@@ -465,7 +466,7 @@
                                              OK_Ordinary,
                                              opLHS.get()->getType(),
                                              result.get()->getType(),
-                                             opcLoc, false);
+                                             opcLoc, FPOptions());
   }
 
   // The result of the assignment, if not void, is the value set into
@@ -841,12 +842,10 @@
           result = S.ImpCastExprToType(result.get(), propType, CK_BitCast);
       }
     }
-    if (S.getLangOpts().ObjCAutoRefCount) {
-      Qualifiers::ObjCLifetime LT = propType.getObjCLifetime();
-      if (LT == Qualifiers::OCL_Weak)
-        if (!S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, RefExpr->getLocation()))
-              S.getCurFunction()->markSafeWeakUse(RefExpr);
-    }
+    if (propType.getObjCLifetime() == Qualifiers::OCL_Weak &&
+        !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
+                           RefExpr->getLocation()))
+      S.getCurFunction()->markSafeWeakUse(RefExpr);
   }
 
   return result;
@@ -962,11 +961,11 @@
 }
 
 ExprResult ObjCPropertyOpBuilder::complete(Expr *SyntacticForm) {
-  if (S.getLangOpts().ObjCAutoRefCount && isWeakProperty() &&
+  if (isWeakProperty() &&
       !S.Diags.isIgnored(diag::warn_arc_repeated_use_of_weak,
                          SyntacticForm->getLocStart()))
-      S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
-                                 SyntacticRefExpr->isMessagingGetter());
+    S.recordUseOfEvaluatedWeak(SyntacticRefExpr,
+                               SyntacticRefExpr->isMessagingGetter());
 
   return PseudoOpBuilder::complete(SyntacticForm);
 }
@@ -1127,8 +1126,8 @@
   if (!Getter)
     return;
   QualType T = Getter->parameters()[0]->getType();
-  S.CheckObjCARCConversion(Key->getSourceRange(), 
-                         T, Key, Sema::CCK_ImplicitConversion);
+  S.CheckObjCConversion(Key->getSourceRange(), T, Key,
+                        Sema::CCK_ImplicitConversion);
 }
 
 bool ObjCSubscriptOpBuilder::findAtIndexGetter() {
@@ -1587,7 +1586,8 @@
   // Do nothing if either argument is dependent.
   if (LHS->isTypeDependent() || RHS->isTypeDependent())
     return new (Context) BinaryOperator(LHS, RHS, opcode, Context.DependentTy,
-                                        VK_RValue, OK_Ordinary, opcLoc, false);
+                                        VK_RValue, OK_Ordinary, opcLoc,
+                                        FPOptions());
 
   // Filter out non-overload placeholder types in the RHS.
   if (RHS->getType()->isNonOverloadPlaceholderType()) {
@@ -1652,14 +1652,15 @@
                                                 cop->getObjectKind(),
                                                 cop->getComputationLHSType(),
                                                 cop->getComputationResultType(),
-                                                cop->getOperatorLoc(), false);
+                                                cop->getOperatorLoc(),
+                                                FPOptions());
   } else if (BinaryOperator *bop = dyn_cast<BinaryOperator>(syntax)) {
     Expr *lhs = stripOpaqueValuesFromPseudoObjectRef(*this, bop->getLHS());
     Expr *rhs = cast<OpaqueValueExpr>(bop->getRHS())->getSourceExpr();
     return new (Context) BinaryOperator(lhs, rhs, bop->getOpcode(),
                                         bop->getType(), bop->getValueKind(),
                                         bop->getObjectKind(),
-                                        bop->getOperatorLoc(), false);
+                                        bop->getOperatorLoc(), FPOptions());
   } else {
     assert(syntax->hasPlaceholderType(BuiltinType::PseudoObject));
     return stripOpaqueValuesFromPseudoObjectRef(*this, syntax);
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 390e1b5..8163cc1 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -711,6 +711,9 @@
                                               EnumValsTy::iterator &EI,
                                               EnumValsTy::iterator &EIEnd,
                                               const llvm::APSInt &Val) {
+  if (!ED->isClosed())
+    return false;
+
   if (const DeclRefExpr *DRE =
           dyn_cast<DeclRefExpr>(CaseExpr->IgnoreParenImpCasts())) {
     if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
@@ -722,15 +725,14 @@
     }
   }
 
-  if (ED->hasAttr<FlagEnumAttr>()) {
+  if (ED->hasAttr<FlagEnumAttr>())
     return !S.IsValueInFlagEnum(ED, Val, false);
-  } else {
-    while (EI != EIEnd && EI->first < Val)
-      EI++;
 
-    if (EI != EIEnd && EI->first == Val)
-      return false;
-  }
+  while (EI != EIEnd && EI->first < Val)
+    EI++;
+
+  if (EI != EIEnd && EI->first == Val)
+    return false;
 
   return true;
 }
@@ -1147,7 +1149,7 @@
         }
       }
 
-      if (TheDefaultStmt && UnhandledNames.empty())
+      if (TheDefaultStmt && UnhandledNames.empty() && ED->isClosedNonFlag())
         Diag(TheDefaultStmt->getDefaultLoc(), diag::warn_unreachable_default);
 
       // Produce a nice diagnostic if multiple values aren't handled.
@@ -1198,6 +1200,9 @@
         AdjustAPSInt(RhsVal, DstWidth, DstIsSigned);
         const EnumDecl *ED = ET->getDecl();
 
+        if (!ED->isClosed())
+          return;
+
         if (ED->hasAttr<FlagEnumAttr>()) {
           if (!IsValueInFlagEnum(ED, RhsVal, true))
             Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
@@ -1772,6 +1777,7 @@
 Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
                                  Stmt *First, Expr *collection,
                                  SourceLocation RParenLoc) {
+  getCurFunction()->setHasBranchProtectedScope();
 
   ExprResult CollectionExprResult =
     CheckObjCForCollectionOperand(ForLoc, collection);
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index ad1e89a..0f7738b 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1288,6 +1288,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, NewClass, Attr);
+  ProcessAPINotes(NewClass);
 
   if (PrevClassTemplate)
     mergeDeclAttributes(NewClass, PrevClassTemplate->getTemplatedDecl());
@@ -2402,6 +2403,13 @@
         Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
     }
 
+    if (Decl->getSpecializationKind() == TSK_Undeclared) {
+      MultiLevelTemplateArgumentList TemplateArgLists;
+      TemplateArgLists.addOuterTemplateArguments(Converted);
+      InstantiateAttrsForDecl(TemplateArgLists, ClassTemplate->getTemplatedDecl(),
+                              Decl);
+    }
+
     // Diagnose uses of this specialization.
     (void)DiagnoseUseOfDecl(Decl, TemplateLoc);
 
@@ -6763,6 +6771,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
+  ProcessAPINotes(Specialization);
 
   // Add alignment attributes if necessary; these attributes are checked when
   // the ASTContext lays out the structure.
@@ -7796,6 +7805,7 @@
   bool PreviouslyDLLExported = Specialization->hasAttr<DLLExportAttr>();
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
+  ProcessAPINotes(Specialization);
 
   // Add the explicit instantiation into its lexical context. However,
   // since explicit instantiations are never found by name lookup, we
@@ -8215,6 +8225,7 @@
         // Merge attributes.
         if (AttributeList *Attr = D.getDeclSpec().getAttributes().getList())
           ProcessDeclAttributeList(S, Prev, Attr);
+        ProcessAPINotes(Prev);
       }
       if (TSK == TSK_ExplicitInstantiationDefinition)
         InstantiateVariableDefinition(D.getIdentifierLoc(), Prev);
@@ -8374,6 +8385,7 @@
   Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
   if (Attr)
     ProcessDeclAttributeList(S, Specialization, Attr);
+  ProcessAPINotes(Specialization);
 
   if (Specialization->isDefined()) {
     // Let the ASTConsumer know that this function has been explicitly
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index 9f744a1..59f2096 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1882,6 +1882,9 @@
   namespace sema {
     Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, Sema &S,
                             const MultiLevelTemplateArgumentList &TemplateArgs);
+    Attr *instantiateTemplateAttributeForDecl(
+        const Attr *At, ASTContext &C, Sema &S,
+        const MultiLevelTemplateArgumentList &TemplateArgs);
   }
 }
 
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2007757..3006424 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -328,6 +328,34 @@
       Attr.getRange());
 }
 
+static bool DeclContainsAttr(const Decl *D, const Attr *NewAttr) {
+  if (!D->hasAttrs() || NewAttr->duplicatesAllowed())
+    return false;
+  return llvm::find_if(D->getAttrs(), [NewAttr](const Attr *Attr) {
+           return Attr->getKind() == NewAttr->getKind();
+         }) != D->getAttrs().end();
+}
+
+void Sema::InstantiateAttrsForDecl(
+    const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
+    Decl *New, LateInstantiatedAttrVec *LateAttrs,
+    LocalInstantiationScope *OuterMostScope) {
+  if (NamedDecl *ND = dyn_cast<NamedDecl>(New)) {
+    for (const auto *TmplAttr : Tmpl->attrs()) {
+      // FIXME: If any of the special case versions from InstantiateAttrs become
+      // applicable to template declaration, we'll need to add them here.
+      CXXThisScopeRAII ThisScope(
+          *this, dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext()),
+          /*TypeQuals*/ 0, ND->isCXXInstanceMember());
+
+      Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(
+          TmplAttr, Context, *this, TemplateArgs);
+      if (NewAttr && !DeclContainsAttr(New, NewAttr))
+        New->addAttr(NewAttr);
+    }
+  }
+}
+
 void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
                             const Decl *Tmpl, Decl *New,
                             LateInstantiatedAttrVec *LateAttrs,
@@ -421,7 +449,8 @@
 
       Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
                                                          *this, TemplateArgs);
-      if (NewAttr)
+
+      if (NewAttr && !DeclContainsAttr(New, NewAttr))
         New->addAttr(NewAttr);
     }
   }
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 2cdf76c..44e61bb 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1159,20 +1159,6 @@
     ResultTL = ObjCObjectPointerTL.getPointeeLoc();
   }
 
-  if (auto OTPTL = ResultTL.getAs<ObjCTypeParamTypeLoc>()) {
-    // Protocol qualifier information.
-    if (OTPTL.getNumProtocols() > 0) {
-      assert(OTPTL.getNumProtocols() == Protocols.size());
-      OTPTL.setProtocolLAngleLoc(ProtocolLAngleLoc);
-      OTPTL.setProtocolRAngleLoc(ProtocolRAngleLoc);
-      for (unsigned i = 0, n = Protocols.size(); i != n; ++i)
-        OTPTL.setProtocolLoc(i, ProtocolLocs[i]);
-    }
-
-    // We're done. Return the completed type to the parser.
-    return CreateParsedType(Result, ResultTInfo);
-  }
-
   auto ObjCObjectTL = ResultTL.castAs<ObjCObjectTypeLoc>();
 
   // Type argument information.
@@ -3355,25 +3341,9 @@
     if (auto recordType = type->getAs<RecordType>()) {
       RecordDecl *recordDecl = recordType->getDecl();
 
-      bool isCFError = false;
-      if (S.CFError) {
-        // If we already know about CFError, test it directly.
-        isCFError = (S.CFError == recordDecl);
-      } else {
-        // Check whether this is CFError, which we identify based on its bridge
-        // to NSError.
-        if (recordDecl->getTagKind() == TTK_Struct && numNormalPointers > 0) {
-          if (auto bridgeAttr = recordDecl->getAttr<ObjCBridgeAttr>()) {
-            if (bridgeAttr->getBridgedType() == S.getNSErrorIdent()) {
-              S.CFError = recordDecl;
-              isCFError = true;
-            }
-          }
-        }
-      }
-
       // If this is CFErrorRef*, report it as such.
-      if (isCFError && numNormalPointers == 2 && numTypeSpecifierPointers < 2) {
+      if (numNormalPointers == 2 && numTypeSpecifierPointers < 2 &&
+          S.isCFError(recordDecl)) {
         return PointerDeclaratorKind::CFErrorRefPointer;
       }
       break;
@@ -3397,6 +3367,26 @@
   }
 }
 
+bool Sema::isCFError(RecordDecl *recordDecl) {
+  // If we already know about CFError, test it directly.
+  if (CFError) {
+    return (CFError == recordDecl);
+  }
+
+  // Check whether this is CFError, which we identify based on being
+  // bridged to NSError.
+  if (recordDecl->getTagKind() == TTK_Struct) {
+    if (auto bridgeAttr = recordDecl->getAttr<ObjCBridgeAttr>()) {
+      if (bridgeAttr->getBridgedType() == getNSErrorIdent()) {
+        CFError = recordDecl;
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
 static FileID getNullabilityCompletenessCheckFileID(Sema &S,
                                                     SourceLocation loc) {
   // If we're anywhere in a function, method, or closure context, don't perform
@@ -5979,12 +5969,34 @@
   return false;
 }
 
+/// Rebuild an attributed type without the nullability attribute on it.
+static QualType rebuildAttributedTypeWithoutNullability(ASTContext &ctx,
+                                                        QualType type) {
+  auto attributed = dyn_cast<AttributedType>(type.getTypePtr());
+  if (!attributed) return type;
+
+  // Skip the nullability attribute; we're done.
+  if (attributed->getImmediateNullability()) {
+    return attributed->getModifiedType();
+  }
+
+  // Build the modified type.
+  auto modified = rebuildAttributedTypeWithoutNullability(
+                    ctx, attributed->getModifiedType());
+  assert(modified.getTypePtr() != attributed->getModifiedType().getTypePtr());
+  return ctx.getAttributedType(attributed->getAttrKind(), modified,
+                                   attributed->getEquivalentType());
+}
+
 bool Sema::checkNullabilityTypeSpecifier(QualType &type,
                                          NullabilityKind nullability,
                                          SourceLocation nullabilityLoc,
                                          bool isContextSensitive,
-                                         bool allowOnArrayType) {
-  recordNullabilitySeen(*this, nullabilityLoc);
+                                         bool allowOnArrayType,
+                                         bool implicit,
+                                         bool overrideExisting) {
+  if (!implicit)
+    recordNullabilitySeen(*this, nullabilityLoc);
 
   // Check for existing nullability attributes on the type.
   QualType desugared = type;
@@ -5993,6 +6005,9 @@
     if (auto existingNullability = attributed->getImmediateNullability()) {
       // Duplicated nullability.
       if (nullability == *existingNullability) {
+        if (implicit)
+          break;
+
         Diag(nullabilityLoc, diag::warn_nullability_duplicate)
           << DiagNullabilityKind(nullability, isContextSensitive)
           << FixItHint::CreateRemoval(nullabilityLoc);
@@ -6000,11 +6015,16 @@
         break;
       } 
 
-      // Conflicting nullability.
-      Diag(nullabilityLoc, diag::err_nullability_conflicting)
-        << DiagNullabilityKind(nullability, isContextSensitive)
-        << DiagNullabilityKind(*existingNullability, false);
-      return true;
+      if (!overrideExisting) {
+        // Conflicting nullability.
+        Diag(nullabilityLoc, diag::err_nullability_conflicting)
+          << DiagNullabilityKind(nullability, isContextSensitive)
+          << DiagNullabilityKind(*existingNullability, false);
+        return true;
+      }
+
+      // Rebuild the attributed type, dropping the existing nullability.
+      type  = rebuildAttributedTypeWithoutNullability(Context, type);
     }
 
     desugared = attributed->getModifiedType();
@@ -6015,7 +6035,7 @@
   // have nullability specifiers on them, which means we cannot
   // provide a useful Fix-It.
   if (auto existingNullability = desugared->getNullability(Context)) {
-    if (nullability != *existingNullability) {
+    if (nullability != *existingNullability && !implicit) {
       Diag(nullabilityLoc, diag::err_nullability_conflicting)
         << DiagNullabilityKind(nullability, isContextSensitive)
         << DiagNullabilityKind(*existingNullability, false);
@@ -6040,15 +6060,16 @@
   // If this definitely isn't a pointer type, reject the specifier.
   if (!desugared->canHaveNullability() &&
       !(allowOnArrayType && desugared->isArrayType())) {
-    Diag(nullabilityLoc, diag::err_nullability_nonpointer)
-      << DiagNullabilityKind(nullability, isContextSensitive) << type;
+    if (!implicit) {
+      Diag(nullabilityLoc, diag::err_nullability_nonpointer)
+        << DiagNullabilityKind(nullability, isContextSensitive) << type;
+    }
     return true;
   }
   
   // For the context-sensitive keywords/Objective-C property
   // attributes, require that the type be a single-level pointer.
   if (isContextSensitive) {
-    // Make sure that the pointee isn't itself a pointer type.
     const Type *pointeeType;
     if (desugared->isArrayType())
       pointeeType = desugared->getArrayElementTypeNoTypeQual();
@@ -6077,13 +6098,6 @@
 }
 
 bool Sema::checkObjCKindOfType(QualType &type, SourceLocation loc) {
-  if (isa<ObjCTypeParamType>(type)) {
-    // Build the attributed type to record where __kindof occurred.
-    type = Context.getAttributedType(AttributedType::attr_objc_kindof,
-                                     type, type);
-    return false;
-  }
-
   // Find out if it's an Objective-C object or object pointer type;
   const ObjCObjectPointerType *ptrType = type->getAs<ObjCObjectPointerType>();
   const ObjCObjectType *objType = ptrType ? ptrType->getObjectType() 
@@ -6829,7 +6843,7 @@
               mapNullabilityAttrKind(attr.getKind()),
               attr.getLoc(),
               attr.isContextSensitiveKeywordAttribute(),
-              allowOnArrayType)) {
+              allowOnArrayType, /*implicit=*/false)) {
           attr.setInvalid();
         }
 
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index f8e65a1..39ec495 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -8855,7 +8855,7 @@
     return E;
 
   Sema::FPContractStateRAII FPContractState(getSema());
-  getSema().FPFeatures.fp_contract = E->isFPContractable();
+  getSema().FPFeatures = E->getFPFeatures();
 
   return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
                                             LHS.get(), RHS.get());
@@ -9335,7 +9335,7 @@
     return SemaRef.MaybeBindToTemporary(E);
 
   Sema::FPContractStateRAII FPContractState(getSema());
-  getSema().FPFeatures.fp_contract = E->isFPContractable();
+  getSema().FPFeatures = E->getFPFeatures();
 
   return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
                                                  E->getOperatorLoc(),
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 53224e2..039bbcc 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -36,6 +36,7 @@
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/Sanitizers.h"
@@ -461,6 +462,30 @@
   return checkDiagnosticGroupMappings(StoredDiags, Diags, Complain);
 }
 
+/// Return the top import module if it is implicit, nullptr otherwise.
+static Module *getTopImportImplicitModule(ModuleManager &ModuleMgr,
+                                          Preprocessor &PP) {
+  // If the original import came from a file explicitly generated by the user,
+  // don't check the diagnostic mappings.
+  // FIXME: currently this is approximated by checking whether this is not a
+  // module import of an implicitly-loaded module file.
+  // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
+  // the transitive closure of its imports, since unrelated modules cannot be
+  // imported until after this module finishes validation.
+  ModuleFile *TopImport = &*ModuleMgr.rbegin();
+  while (!TopImport->ImportedBy.empty())
+    TopImport = TopImport->ImportedBy[0];
+  if (TopImport->Kind != MK_ImplicitModule)
+    return nullptr;
+
+  StringRef ModuleName = TopImport->ModuleName;
+  assert(!ModuleName.empty() && "diagnostic options read before module name");
+
+  Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
+  assert(M && "missing module");
+  return M;
+}
+
 bool PCHValidator::ReadDiagnosticOptions(
     IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts, bool Complain) {
   DiagnosticsEngine &ExistingDiags = PP.getDiagnostics();
@@ -474,28 +499,14 @@
   ModuleManager &ModuleMgr = Reader.getModuleManager();
   assert(ModuleMgr.size() >= 1 && "what ASTFile is this then");
 
-  // If the original import came from a file explicitly generated by the user,
-  // don't check the diagnostic mappings.
-  // FIXME: currently this is approximated by checking whether this is not a
-  // module import of an implicitly-loaded module file.
-  // Note: ModuleMgr.rbegin() may not be the current module, but it must be in
-  // the transitive closure of its imports, since unrelated modules cannot be
-  // imported until after this module finishes validation.
-  ModuleFile *TopImport = *ModuleMgr.rbegin();
-  while (!TopImport->ImportedBy.empty())
-    TopImport = TopImport->ImportedBy[0];
-  if (TopImport->Kind != MK_ImplicitModule)
+  Module *TopM = getTopImportImplicitModule(ModuleMgr, PP);
+  if (!TopM)
     return false;
 
-  StringRef ModuleName = TopImport->ModuleName;
-  assert(!ModuleName.empty() && "diagnostic options read before module name");
-
-  Module *M = PP.getHeaderSearchInfo().lookupModule(ModuleName);
-  assert(M && "missing module");
-
   // FIXME: if the diagnostics are incompatible, save a DiagnosticOptions that
   // contains the union of their flags.
-  return checkDiagnosticMappings(*Diags, ExistingDiags, M->IsSystem, Complain);
+  return checkDiagnosticMappings(*Diags, ExistingDiags, TopM->IsSystem,
+                                 Complain);
 }
 
 /// \brief Collect the macro definitions provided by the given preprocessor
@@ -1707,15 +1718,15 @@
   // Note that we are loading defined macros.
   Deserializing Macros(this);
 
-  for (auto &I : llvm::reverse(ModuleMgr)) {
-    BitstreamCursor &MacroCursor = I->MacroCursor;
+  for (ModuleFile &I : llvm::reverse(ModuleMgr)) {
+    BitstreamCursor &MacroCursor = I.MacroCursor;
 
     // If there was no preprocessor block, skip this file.
     if (MacroCursor.getBitcodeBytes().empty())
       continue;
 
     BitstreamCursor Cursor = MacroCursor;
-    Cursor.JumpToBit(I->MacroStartOffset);
+    Cursor.JumpToBit(I.MacroStartOffset);
 
     RecordData Record;
     while (true) {
@@ -1737,7 +1748,7 @@
 
         case PP_MACRO_OBJECT_LIKE:
         case PP_MACRO_FUNCTION_LIKE: {
-          IdentifierInfo *II = getLocalIdentifier(*I, Record[0]);
+          IdentifierInfo *II = getLocalIdentifier(I, Record[0]);
           if (II->isOutOfDate())
             updateOutOfDateIdentifier(*II);
           break;
@@ -2149,7 +2160,7 @@
 ASTReader::ASTReadResult ASTReader::ReadOptionsBlock(
     BitstreamCursor &Stream, unsigned ClientLoadCapabilities,
     bool AllowCompatibleConfigurationMismatch, ASTReaderListener &Listener,
-    std::string &SuggestedPredefines, bool ValidateDiagnosticOptions) {
+    std::string &SuggestedPredefines) {
   if (Stream.EnterSubBlock(OPTIONS_BLOCK_ID))
     return Failure;
 
@@ -2191,15 +2202,6 @@
       break;
     }
 
-    case DIAGNOSTIC_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
-      if (ValidateDiagnosticOptions &&
-          !AllowCompatibleConfigurationMismatch &&
-          ParseDiagnosticOptions(Record, Complain, Listener))
-        return OutOfDate;
-      break;
-    }
-
     case FILE_SYSTEM_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
       if (!AllowCompatibleConfigurationMismatch &&
@@ -2240,6 +2242,18 @@
     return Failure;
   }
 
+  // Lambda to read the unhashed control block the first time it's called.
+  bool HasReadUnhashedControlBlock = false;
+  auto readUnhashedControlBlockOnce = [&]() {
+    if (!HasReadUnhashedControlBlock) {
+      HasReadUnhashedControlBlock = true;
+      if (ASTReadResult Result =
+              readUnhashedControlBlock(F, ImportedBy, ClientLoadCapabilities))
+        return Result;
+    }
+    return Success;
+  };
+
   // Read all of the records and blocks in the control block.
   RecordData Record;
   unsigned NumInputs = 0;
@@ -2252,6 +2266,11 @@
       Error("malformed block record in AST file");
       return Failure;
     case llvm::BitstreamEntry::EndBlock: {
+      // Validate the module before returning.  This call catches an AST with
+      // no module name and no imports.
+      if (ASTReadResult Result = readUnhashedControlBlockOnce())
+        return Result;
+
       // Validate input files.
       const HeaderSearchOptions &HSOpts =
           PP.getHeaderSearchInfo().getHeaderSearchOpts();
@@ -2323,13 +2342,10 @@
           // FIXME: Allow this for files explicitly specified with -include-pch.
           bool AllowCompatibleConfigurationMismatch =
               F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule;
-          const HeaderSearchOptions &HSOpts =
-              PP.getHeaderSearchInfo().getHeaderSearchOpts();
 
           Result = ReadOptionsBlock(Stream, ClientLoadCapabilities,
                                     AllowCompatibleConfigurationMismatch,
-                                    *Listener, SuggestedPredefines,
-                                    HSOpts.ModulesValidateDiagnosticOptions);
+                                    *Listener, SuggestedPredefines);
           if (Result == Failure) {
             Error("malformed block record in AST file");
             return Result;
@@ -2403,12 +2419,13 @@
       break;
     }
 
-    case SIGNATURE:
-      assert((!F.Signature || F.Signature == Record[0]) && "signature changed");
-      F.Signature = Record[0];
-      break;
-
     case IMPORTS: {
+      // Validate the AST before processing any imports (otherwise, untangling
+      // them can be error-prone and expensive).  A module will have a name and
+      // will already have been validated, but this catches the PCH case.
+      if (ASTReadResult Result = readUnhashedControlBlockOnce())
+        return Result;
+
       // Load each of the imported PCH files.
       unsigned Idx = 0, N = Record.size();
       while (Idx < N) {
@@ -2421,7 +2438,10 @@
             ReadUntranslatedSourceLocation(Record[Idx++]);
         off_t StoredSize = (off_t)Record[Idx++];
         time_t StoredModTime = (time_t)Record[Idx++];
-        ASTFileSignature StoredSignature = Record[Idx++];
+        ASTFileSignature StoredSignature = {
+            {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++]}}};
         auto ImportedFile = ReadPath(F, Record, Idx);
 
         // If our client can't cope with us being out of date, we can't cope with
@@ -2473,6 +2493,12 @@
       F.ModuleName = Blob;
       if (Listener)
         Listener->ReadModuleName(F.ModuleName);
+
+      // Validate the AST as soon as we have a name so we can exit early on
+      // failure.
+      if (ASTReadResult Result = readUnhashedControlBlockOnce())
+        return Result;
+
       break;
 
     case MODULE_DIRECTORY: {
@@ -2513,6 +2539,7 @@
       F.InputFileOffsets =
           (const llvm::support::unaligned_uint64_t *)Blob.data();
       F.InputFilesLoaded.resize(NumInputs);
+      F.NumUserInputFiles = NumUserInputs;
       break;
     }
   }
@@ -3123,14 +3150,6 @@
       F.ObjCCategories.swap(Record);
       break;
 
-    case DIAG_PRAGMA_MAPPINGS:
-      if (F.PragmaDiagMappings.empty())
-        F.PragmaDiagMappings.swap(Record);
-      else
-        F.PragmaDiagMappings.insert(F.PragmaDiagMappings.end(),
-                                    Record.begin(), Record.end());
-      break;
-
     case CUDA_SPECIAL_DECL_REFS:
       // Later tables overwrite earlier ones.
       // FIXME: Modules will have trouble with this.
@@ -3245,8 +3264,11 @@
         for (unsigned I = 0, N = Record.size(); I != N; /**/) {
           unsigned GlobalID = getGlobalSubmoduleID(F, Record[I++]);
           SourceLocation Loc = ReadSourceLocation(F, Record, I);
-          if (GlobalID)
+          if (GlobalID) {
             ImportedModules.push_back(ImportedSubmodule(GlobalID, Loc));
+            if (DeserializationListener)
+              DeserializationListener->ModuleImportRead(GlobalID, Loc);
+          }
         }
       }
       break;
@@ -3319,6 +3341,28 @@
       }
       ForceCUDAHostDeviceDepth = Record[0];
       break;
+
+    case PACK_PRAGMA_OPTIONS: {
+      if (Record.size() < 3) {
+        Error("invalid pragma pack record");
+        return Failure;
+      }
+      PragmaPackCurrentValue = Record[0];
+      PragmaPackCurrentLocation = ReadSourceLocation(F, Record[1]);
+      unsigned NumStackEntries = Record[2];
+      unsigned Idx = 3;
+      // Reset the stack when importing a new module.
+      PragmaPackStack.clear();
+      for (unsigned I = 0; I < NumStackEntries; ++I) {
+        PragmaPackStackEntry Entry;
+        Entry.Value = Record[Idx++];
+        Entry.Location = ReadSourceLocation(F, Record[Idx++]);
+        PragmaPackStrings.push_back(ReadString(Record, Idx));
+        Entry.SlotLabel = PragmaPackStrings.back();
+        PragmaPackStack.push_back(Entry);
+      }
+      break;
+    }
     }
   }
 }
@@ -3342,8 +3386,7 @@
   // usable header search context.
   assert(!F.ModuleName.empty() &&
          "MODULE_NAME should come before MODULE_MAP_FILE");
-  if (F.Kind == MK_ImplicitModule &&
-      (*ModuleMgr.begin())->Kind != MK_MainFile) {
+  if (F.Kind == MK_ImplicitModule && ModuleMgr.begin()->Kind != MK_MainFile) {
     // An implicitly-loaded module file should have its module listed in some
     // module map file that we've already loaded.
     Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
@@ -3621,10 +3664,10 @@
 
   unsigned NumModules = ModuleMgr.size();
   SmallVector<ImportedModule, 4> Loaded;
-  switch(ASTReadResult ReadResult = ReadASTCore(FileName, Type, ImportLoc,
-                                                /*ImportedBy=*/nullptr, Loaded,
-                                                0, 0, 0,
-                                                ClientLoadCapabilities)) {
+  switch (ASTReadResult ReadResult =
+              ReadASTCore(FileName, Type, ImportLoc,
+                          /*ImportedBy=*/nullptr, Loaded, 0, 0,
+                          ASTFileSignature(), ClientLoadCapabilities)) {
   case Failure:
   case Missing:
   case OutOfDate:
@@ -3635,11 +3678,10 @@
     for (const ImportedModule &IM : Loaded)
       LoadedSet.insert(IM.Mod);
 
-    ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, ModuleMgr.end(),
-                            LoadedSet,
+    ModuleMgr.removeModules(ModuleMgr.begin() + NumModules, LoadedSet,
                             Context.getLangOpts().Modules
-                              ? &PP.getHeaderSearchInfo().getModuleMap()
-                              : nullptr);
+                                ? &PP.getHeaderSearchInfo().getModuleMap()
+                                : nullptr);
 
     // If we find that any modules are unusable, the global index is going
     // to be out-of-date. Just remove it.
@@ -3986,6 +4028,11 @@
       Loaded.push_back(ImportedModule(M, ImportedBy, ImportLoc));
       return Success;
 
+    case UNHASHED_CONTROL_BLOCK_ID:
+      // This block is handled using look-ahead during ReadControlBlock.  We
+      // shouldn't get here!
+      return Failure;
+
     default:
       if (Stream.SkipBlock()) {
         Error("malformed block record in AST file");
@@ -3998,6 +4045,122 @@
   return Success;
 }
 
+ASTReader::ASTReadResult
+ASTReader::readUnhashedControlBlock(ModuleFile &F, bool WasImportedBy,
+                                    unsigned ClientLoadCapabilities) {
+  const HeaderSearchOptions &HSOpts =
+      PP.getHeaderSearchInfo().getHeaderSearchOpts();
+  bool AllowCompatibleConfigurationMismatch =
+      F.Kind == MK_ExplicitModule || F.Kind == MK_PrebuiltModule;
+
+  ASTReadResult Result = readUnhashedControlBlockImpl(
+      &F, F.Data, ClientLoadCapabilities, AllowCompatibleConfigurationMismatch,
+      Listener.get(),
+      WasImportedBy ? false : HSOpts.ModulesValidateDiagnosticOptions);
+
+  // If F was directly imported by another module, it's implicitly validated by
+  // the importing module.
+  if (DisableValidation || WasImportedBy ||
+      (AllowConfigurationMismatch && Result == ConfigurationMismatch))
+    return Success;
+
+  if (Result == Failure) {
+    Error("malformed block record in AST file");
+    return Failure;
+  }
+
+  if (Result == OutOfDate && F.Kind == MK_ImplicitModule) {
+    // If this module has already been finalized in the PCMCache, we're stuck
+    // with it; we can only load a single version of each module.
+    //
+    // This can happen when a module is imported in two contexts: in one, as a
+    // user module; in another, as a system module (due to an import from
+    // another module marked with the [system] flag).  It usually indicates a
+    // bug in the module map: this module should also be marked with [system].
+    //
+    // If -Wno-system-headers (the default), and the first import is as a
+    // system module, then validation will fail during the as-user import,
+    // since -Werror flags won't have been validated.  However, it's reasonable
+    // to treat this consistently as a system module.
+    //
+    // If -Wsystem-headers, the PCM on disk was built with
+    // -Wno-system-headers, and the first import is as a user module, then
+    // validation will fail during the as-system import since the PCM on disk
+    // doesn't guarantee that -Werror was respected.  However, the -Werror
+    // flags were checked during the initial as-user import.
+    if (PCMCache.isBufferFinal(F.FileName)) {
+      Diag(diag::warn_module_system_bit_conflict) << F.FileName;
+      return Success;
+    }
+  }
+
+  return Result;
+}
+
+ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
+    ModuleFile *F, llvm::StringRef StreamData, unsigned ClientLoadCapabilities,
+    bool AllowCompatibleConfigurationMismatch, ASTReaderListener *Listener,
+    bool ValidateDiagnosticOptions) {
+  // Initialize a stream.
+  BitstreamCursor Stream(StreamData);
+
+  // Sniff for the signature.
+  if (!startsWithASTFileMagic(Stream))
+    return Failure;
+
+  // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
+  if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
+    return Failure;
+
+  // Read all of the records in the options block.
+  RecordData Record;
+  ASTReadResult Result = Success;
+  while (1) {
+    llvm::BitstreamEntry Entry = Stream.advance();
+
+    switch (Entry.Kind) {
+    case llvm::BitstreamEntry::Error:
+    case llvm::BitstreamEntry::SubBlock:
+      return Failure;
+
+    case llvm::BitstreamEntry::EndBlock:
+      return Result;
+
+    case llvm::BitstreamEntry::Record:
+      // The interesting case.
+      break;
+    }
+
+    // Read and process a record.
+    Record.clear();
+    switch (
+        (UnhashedControlBlockRecordTypes)Stream.readRecord(Entry.ID, Record)) {
+    case SIGNATURE: {
+      if (F)
+        std::copy(Record.begin(), Record.end(), F->Signature.data());
+      break;
+    }
+    case DIAGNOSTIC_OPTIONS: {
+      bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0;
+      if (Listener && ValidateDiagnosticOptions &&
+          !AllowCompatibleConfigurationMismatch &&
+          ParseDiagnosticOptions(Record, Complain, *Listener))
+        Result = OutOfDate; // Don't return early.  Read the signature.
+      break;
+    }
+    case DIAG_PRAGMA_MAPPINGS:
+      if (!F)
+        break;
+      if (F->PragmaDiagMappings.empty())
+        F->PragmaDiagMappings.swap(Record);
+      else
+        F->PragmaDiagMappings.insert(F->PragmaDiagMappings.end(),
+                                     Record.begin(), Record.end());
+      break;
+    }
+  }
+}
+
 /// Parse a record and blob containing module file extension metadata.
 static bool parseModuleFileExtensionMetadata(
               const SmallVectorImpl<uint64_t> &Record,
@@ -4214,23 +4377,24 @@
 static ASTFileSignature readASTFileSignature(StringRef PCH) {
   BitstreamCursor Stream(PCH);
   if (!startsWithASTFileMagic(Stream))
-    return 0;
+    return ASTFileSignature();
 
-  // Scan for the CONTROL_BLOCK_ID block.
-  if (SkipCursorToBlock(Stream, CONTROL_BLOCK_ID))
-    return 0;
+  // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
+  if (SkipCursorToBlock(Stream, UNHASHED_CONTROL_BLOCK_ID))
+    return ASTFileSignature();
 
-  // Scan for SIGNATURE inside the control block.
+  // Scan for SIGNATURE inside the diagnostic options block.
   ASTReader::RecordData Record;
   while (true) {
     llvm::BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
     if (Entry.Kind != llvm::BitstreamEntry::Record)
-      return 0;
+      return ASTFileSignature();
 
     Record.clear();
     StringRef Blob;
     if (SIGNATURE == Stream.readRecord(Entry.ID, Record, &Blob))
-      return Record[0];
+      return {{{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2],
+                (uint32_t)Record[3], (uint32_t)Record[4]}}};
   }
 }
 
@@ -4349,7 +4513,8 @@
   }
 
   // Initialize the stream
-  BitstreamCursor Stream(PCHContainerRdr.ExtractPCH(**Buffer));
+  StringRef Bytes = PCHContainerRdr.ExtractPCH(**Buffer);
+  BitstreamCursor Stream(Bytes);
 
   // Sniff for the signature.
   if (!startsWithASTFileMagic(Stream))
@@ -4377,8 +4542,7 @@
         std::string IgnoredSuggestedPredefines;
         if (ReadOptionsBlock(Stream, ARR_ConfigurationMismatch | ARR_OutOfDate,
                              /*AllowCompatibleConfigurationMismatch*/ false,
-                             Listener, IgnoredSuggestedPredefines,
-                             ValidateDiagnosticOptions) != Success)
+                             Listener, IgnoredSuggestedPredefines) != Success)
           return true;
         break;
       }
@@ -4499,6 +4663,7 @@
 
   // Look for module file extension blocks, if requested.
   if (FindModuleFileExtensions) {
+    BitstreamCursor SavedStream = Stream;
     while (!SkipCursorToBlock(Stream, EXTENSION_BLOCK_ID)) {
       bool DoneWithExtensionBlock = false;
       while (!DoneWithExtensionBlock) {
@@ -4537,8 +4702,16 @@
        }
       }
     }
+    Stream = SavedStream;
   }
 
+  // Scan for the UNHASHED_CONTROL_BLOCK_ID block.
+  if (readUnhashedControlBlockImpl(
+          nullptr, Bytes, ARR_ConfigurationMismatch | ARR_OutOfDate,
+          /*AllowCompatibleConfigurationMismatch*/ false, &Listener,
+          ValidateDiagnosticOptions) != Success)
+    return true;
+
   return false;
 }
 
@@ -4617,6 +4790,7 @@
       bool IsExplicit = Record[Idx++];
       bool IsSystem = Record[Idx++];
       bool IsExternC = Record[Idx++];
+      bool IsSwiftInferImportAsMember = Record[Idx++];
       bool InferSubmodules = Record[Idx++];
       bool InferExplicitSubmodules = Record[Idx++];
       bool InferExportWildcard = Record[Idx++];
@@ -4661,6 +4835,7 @@
       CurrentModule->IsFromModuleFile = true;
       CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
       CurrentModule->IsExternC = IsExternC;
+      CurrentModule->IsSwiftInferImportAsMember = IsSwiftInferImportAsMember;
       CurrentModule->InferSubmodules = InferSubmodules;
       CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;
       CurrentModule->InferExportWildcard = InferExportWildcard;
@@ -4696,13 +4871,9 @@
         if (!CurrentModule->getUmbrellaHeader())
           ModMap.setUmbrellaHeader(CurrentModule, Umbrella, Blob);
         else if (CurrentModule->getUmbrellaHeader().Entry != Umbrella) {
-          // This can be a spurious difference caused by changing the VFS to
-          // point to a different copy of the file, and it is too late to
-          // to rebuild safely.
-          // FIXME: If we wrote the virtual paths instead of the 'real' paths,
-          // after input file validation only real problems would remain and we
-          // could just error. For now, assume it's okay.
-          break;
+          if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
+            Error("mismatched umbrella headers in submodule");
+          return OutOfDate;
         }
       }
       break;
@@ -5288,48 +5459,83 @@
 }
 
 void ASTReader::ReadPragmaDiagnosticMappings(DiagnosticsEngine &Diag) {
-  // FIXME: Make it work properly with modules.
-  SmallVector<DiagnosticsEngine::DiagState *, 32> DiagStates;
-  for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
-    ModuleFile &F = *(*I);
-    unsigned Idx = 0;
-    DiagStates.clear();
-    assert(!Diag.DiagStates.empty());
-    DiagStates.push_back(&Diag.DiagStates.front()); // the command-line one.
-    while (Idx < F.PragmaDiagMappings.size()) {
-      SourceLocation Loc = ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
-      unsigned DiagStateID = F.PragmaDiagMappings[Idx++];
-      if (DiagStateID != 0) {
-        Diag.DiagStatePoints.push_back(
-                    DiagnosticsEngine::DiagStatePoint(DiagStates[DiagStateID-1],
-                    FullSourceLoc(Loc, SourceMgr)));
-        continue;
-      }
+  using DiagState = DiagnosticsEngine::DiagState;
+  SmallVector<DiagState *, 32> DiagStates;
 
-      assert(DiagStateID == 0);
+  for (ModuleFile &F : ModuleMgr) {
+    unsigned Idx = 0;
+    auto &Record = F.PragmaDiagMappings;
+    if (Record.empty())
+      continue;
+
+    DiagStates.clear();
+
+    auto ReadDiagState =
+        [&](const DiagState &BasedOn, SourceLocation Loc,
+            bool IncludeNonPragmaStates) -> DiagnosticsEngine::DiagState * {
+      unsigned BackrefID = Record[Idx++];
+      if (BackrefID != 0)
+        return DiagStates[BackrefID - 1];
+
       // A new DiagState was created here.
-      Diag.DiagStates.push_back(*Diag.GetCurDiagState());
-      DiagnosticsEngine::DiagState *NewState = &Diag.DiagStates.back();
+      Diag.DiagStates.push_back(BasedOn);
+      DiagState *NewState = &Diag.DiagStates.back();
       DiagStates.push_back(NewState);
-      Diag.DiagStatePoints.push_back(
-          DiagnosticsEngine::DiagStatePoint(NewState,
-                                            FullSourceLoc(Loc, SourceMgr)));
-      while (true) {
-        assert(Idx < F.PragmaDiagMappings.size() &&
-               "Invalid data, didn't find '-1' marking end of diag/map pairs");
-        if (Idx >= F.PragmaDiagMappings.size()) {
-          break; // Something is messed up but at least avoid infinite loop in
-                 // release build.
-        }
-        unsigned DiagID = F.PragmaDiagMappings[Idx++];
-        if (DiagID == (unsigned)-1) {
-          break; // no more diag/map pairs for this location.
-        }
-        diag::Severity Map = (diag::Severity)F.PragmaDiagMappings[Idx++];
+      while (Idx + 1 < Record.size() && Record[Idx] != unsigned(-1)) {
+        unsigned DiagID = Record[Idx++];
+        diag::Severity Map = (diag::Severity)Record[Idx++];
         DiagnosticMapping Mapping = Diag.makeUserMapping(Map, Loc);
-        Diag.GetCurDiagState()->setMapping(DiagID, Mapping);
+        if (Mapping.isPragma() || IncludeNonPragmaStates)
+          NewState->setMapping(DiagID, Mapping);
+      }
+      assert(Idx != Record.size() && Record[Idx] == unsigned(-1) &&
+             "Invalid data, didn't find '-1' marking end of diag/map pairs");
+      ++Idx;
+      return NewState;
+    };
+
+    auto *FirstState = ReadDiagState(
+        F.isModule() ? DiagState() : *Diag.DiagStatesByLoc.CurDiagState,
+        SourceLocation(), F.isModule());
+    SourceLocation CurStateLoc =
+        ReadSourceLocation(F, F.PragmaDiagMappings[Idx++]);
+    auto *CurState = ReadDiagState(*FirstState, CurStateLoc, false);
+
+    if (!F.isModule()) {
+      Diag.DiagStatesByLoc.CurDiagState = CurState;
+      Diag.DiagStatesByLoc.CurDiagStateLoc = CurStateLoc;
+
+      // Preserve the property that the imaginary root file describes the
+      // current state.
+      auto &T = Diag.DiagStatesByLoc.Files[FileID()].StateTransitions;
+      if (T.empty())
+        T.push_back({CurState, 0});
+      else
+        T[0].State = CurState;
+    }
+
+    while (Idx < Record.size()) {
+      SourceLocation Loc = ReadSourceLocation(F, Record[Idx++]);
+      auto IDAndOffset = SourceMgr.getDecomposedLoc(Loc);
+      assert(IDAndOffset.second == 0 && "not a start location for a FileID");
+      unsigned Transitions = Record[Idx++];
+
+      // Note that we don't need to set up Parent/ParentOffset here, because
+      // we won't be changing the diagnostic state within imported FileIDs
+      // (other than perhaps appending to the main source file, which has no
+      // parent).
+      auto &F = Diag.DiagStatesByLoc.Files[IDAndOffset.first];
+      F.StateTransitions.reserve(F.StateTransitions.size() + Transitions);
+      for (unsigned I = 0; I != Transitions; ++I) {
+        unsigned Offset = Record[Idx++];
+        auto *State =
+            ReadDiagState(*FirstState, Loc.getLocWithOffset(Offset), false);
+        F.StateTransitions.push_back({State, Offset});
       }
     }
+
+    // Don't try to read these mappings again.
+    Record.clear();
   }
 }
 
@@ -5840,6 +6046,17 @@
     return Context.getPipeType(ElementType, ReadOnly);
   }
 
+  case TYPE_DEPENDENT_SIZED_EXT_VECTOR: {
+    unsigned Idx = 0;
+
+    // DependentSizedExtVectorType
+    QualType ElementType = readType(*Loc.F, Record, Idx);
+    Expr *SizeExpr = ReadExpr(*Loc.F);
+    SourceLocation AttrLoc = ReadSourceLocation(*Loc.F, Record, Idx);
+
+    return Context.getDependentSizedExtVectorType(ElementType, SizeExpr,
+                                                  AttrLoc);
+  }
   }
   llvm_unreachable("Invalid TypeCode!");
 }
@@ -6920,31 +7137,6 @@
   Consumer->HandleInterestingDecl(DeclGroupRef(ImplD));
 }
 
-void ASTReader::PassInterestingDeclsToConsumer() {
-  assert(Consumer);
-
-  if (PassingDeclsToConsumer)
-    return;
-
-  // Guard variable to avoid recursively redoing the process of passing
-  // decls to consumer.
-  SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
-                                                   true);
-
-  // Ensure that we've loaded all potentially-interesting declarations
-  // that need to be eagerly loaded.
-  for (auto ID : EagerlyDeserializedDecls)
-    GetDecl(ID);
-  EagerlyDeserializedDecls.clear();
-
-  while (!InterestingDecls.empty()) {
-    Decl *D = InterestingDecls.front();
-    InterestingDecls.pop_front();
-
-    PassInterestingDeclToConsumer(D);
-  }
-}
-
 void ASTReader::PassInterestingDeclToConsumer(Decl *D) {
   if (ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
     PassObjCImplDeclToConsumer(ImplD, Consumer);
@@ -7092,18 +7284,15 @@
                   GlobalPreprocessedEntityMap);
 
   llvm::errs() << "\n*** PCH/Modules Loaded:";
-  for (ModuleManager::ModuleConstIterator M = ModuleMgr.begin(),
-                                       MEnd = ModuleMgr.end();
-       M != MEnd; ++M)
-    (*M)->dump();
+  for (ModuleFile &M : ModuleMgr)
+    M.dump();
 }
 
 /// Return the amount of memory used by memory buffers, breaking down
 /// by heap-backed versus mmap'ed memory.
 void ASTReader::getMemoryBufferSizes(MemoryBufferSizes &sizes) const {
-  for (ModuleConstIterator I = ModuleMgr.begin(),
-      E = ModuleMgr.end(); I != E; ++I) {
-    if (llvm::MemoryBuffer *buf = (*I)->Buffer.get()) {
+  for (ModuleFile &I : ModuleMgr) {
+    if (llvm::MemoryBuffer *buf = I.Buffer) {
       size_t bytes = buf->getBufferSize();
       switch (buf->getBufferKind()) {
         case llvm::MemoryBuffer::MemoryBuffer_Malloc:
@@ -7132,7 +7321,7 @@
   // FIXME: What happens if these are changed by a module import?
   if (!FPPragmaOptions.empty()) {
     assert(FPPragmaOptions.size() == 1 && "Wrong number of FP_PRAGMA_OPTIONS");
-    SemaObj->FPFeatures.fp_contract = FPPragmaOptions[0];
+    SemaObj->FPFeatures = FPOptions(FPPragmaOptions[0]);
   }
 
   SemaObj->OpenCLFeatures.copy(OpenCLExtensions);
@@ -7173,6 +7362,34 @@
         PointersToMembersPragmaLocation);
   }
   SemaObj->ForceCUDAHostDeviceDepth = ForceCUDAHostDeviceDepth;
+
+  if (PragmaPackCurrentValue) {
+    // The bottom of the stack might have a default value. It must be adjusted
+    // to the current value to ensure that the packing state is preserved after
+    // popping entries that were included/imported from a PCH/module.
+    bool DropFirst = false;
+    if (!PragmaPackStack.empty() &&
+        PragmaPackStack.front().Location.isInvalid()) {
+      assert(PragmaPackStack.front().Value == SemaObj->PackStack.DefaultValue &&
+             "Expected a default alignment value");
+      SemaObj->PackStack.Stack.emplace_back(
+          PragmaPackStack.front().SlotLabel, SemaObj->PackStack.CurrentValue,
+          SemaObj->PackStack.CurrentPragmaLocation);
+      DropFirst = true;
+    }
+    for (const auto &Entry :
+         llvm::makeArrayRef(PragmaPackStack).drop_front(DropFirst ? 1 : 0))
+      SemaObj->PackStack.Stack.emplace_back(Entry.SlotLabel, Entry.Value,
+                                            Entry.Location);
+    if (PragmaPackCurrentLocation.isInvalid()) {
+      assert(*PragmaPackCurrentValue == SemaObj->PackStack.DefaultValue &&
+             "Expected a default alignment value");
+      // Keep the current values.
+    } else {
+      SemaObj->PackStack.CurrentValue = *PragmaPackCurrentValue;
+      SemaObj->PackStack.CurrentPragmaLocation = PragmaPackCurrentLocation;
+    }
+  }
 }
 
 IdentifierInfo *ASTReader::get(StringRef Name) {
@@ -7833,7 +8050,8 @@
 
   // If there is only a single PCH, return it instead.
   // Chained PCH are not suported.
-  if (ModuleMgr.size() == 1) {
+  const auto &PCHChain = ModuleMgr.pch_modules();
+  if (std::distance(std::begin(PCHChain), std::end(PCHChain))) {
     ModuleFile &MF = ModuleMgr.getPrimaryModule();
     StringRef ModuleName = llvm::sys::path::filename(MF.OriginalSourceFileName);
     StringRef FileName = llvm::sys::path::filename(MF.FileName);
@@ -8493,6 +8711,21 @@
   }
 }
 
+void ASTReader::visitInputFiles(serialization::ModuleFile &MF,
+                                bool IncludeSystem, bool Complain,
+                    llvm::function_ref<void(const serialization::InputFile &IF,
+                                            bool isSystem)> Visitor) {
+  unsigned NumUserInputs = MF.NumUserInputFiles;
+  unsigned NumInputs = MF.InputFilesLoaded.size();
+  assert(NumUserInputs <= NumInputs);
+  unsigned N = IncludeSystem ? NumInputs : NumUserInputs;
+  for (unsigned I = 0; I < N; ++I) {
+    bool IsSystem = I >= NumUserInputs;
+    InputFile IF = getInputFile(MF, I+1, Complain);
+    Visitor(IF, IsSystem);
+  }
+}
+
 std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) {
   // If we know the owning module, use it.
   if (Module *M = D->getImportedOwningModule())
@@ -8905,8 +9138,10 @@
                    : cast<ASTReaderListener>(new PCHValidator(PP, *this))),
       SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()),
       PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP),
-      Context(Context), ModuleMgr(PP.getFileManager(), PCHContainerRdr),
-      DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
+      Context(Context),
+      ModuleMgr(PP.getFileManager(), PP.getPCMCache(), PCHContainerRdr),
+      PCMCache(PP.getPCMCache()), DummyIdResolver(PP),
+      ReadTimer(std::move(ReadTimer)), isysroot(isysroot),
       DisableValidation(DisableValidation),
       AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
       AllowConfigurationMismatch(AllowConfigurationMismatch),
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 707a924..cbf54de 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1112,8 +1112,12 @@
       (ObjCPropertyDecl::PropertyAttributeKind)Record.readInt());
   D->setPropertyImplementation(
       (ObjCPropertyDecl::PropertyControl)Record.readInt());
-  D->setGetterName(Record.readDeclarationName().getObjCSelector());
-  D->setSetterName(Record.readDeclarationName().getObjCSelector());
+  DeclarationName GetterName = Record.readDeclarationName();
+  SourceLocation GetterLoc = ReadSourceLocation();
+  D->setGetterName(GetterName.getObjCSelector(), GetterLoc);
+  DeclarationName SetterName = Record.readDeclarationName();
+  SourceLocation SetterLoc = ReadSourceLocation();
+  D->setSetterName(SetterName.getObjCSelector(), SetterLoc);
   D->setGetterMethodDecl(ReadDeclAs<ObjCMethodDecl>());
   D->setSetterMethodDecl(ReadDeclAs<ObjCMethodDecl>());
   D->setPropertyIvarDecl(ReadDeclAs<ObjCIvarDecl>());
@@ -1126,7 +1130,6 @@
 
 void ASTDeclReader::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
   VisitObjCImplDecl(D);
-  D->setIdentifier(Record.getIdentifierInfo());
   D->CategoryNameLoc = ReadSourceLocation();
 }
 
@@ -3531,12 +3534,37 @@
   // AST consumer might need to know about, queue it.
   // We don't pass it to the consumer immediately because we may be in recursive
   // loading, and some declarations may still be initializing.
-  if (isConsumerInterestedIn(Context, D, Reader.hasPendingBody()))
-    InterestingDecls.push_back(D);
+  PotentiallyInterestingDecls.push_back(
+      InterestingDecl(D, Reader.hasPendingBody()));
 
   return D;
 }
 
+void ASTReader::PassInterestingDeclsToConsumer() {
+  assert(Consumer);
+
+  if (PassingDeclsToConsumer)
+    return;
+
+  // Guard variable to avoid recursively redoing the process of passing
+  // decls to consumer.
+  SaveAndRestore<bool> GuardPassingDeclsToConsumer(PassingDeclsToConsumer,
+                                                   true);
+
+  // Ensure that we've loaded all potentially-interesting declarations
+  // that need to be eagerly loaded.
+  for (auto ID : EagerlyDeserializedDecls)
+    GetDecl(ID);
+  EagerlyDeserializedDecls.clear();
+
+  while (!PotentiallyInterestingDecls.empty()) {
+    InterestingDecl D = PotentiallyInterestingDecls.front();
+    PotentiallyInterestingDecls.pop_front();
+    if (isConsumerInterestedIn(Context, D.getDecl(), D.hasPendingBody()))
+      PassInterestingDeclToConsumer(D.getDecl());
+  }
+}
+
 void ASTReader::loadDeclUpdateRecords(serialization::DeclID ID, Decl *D) {
   // The declaration may have been modified by files later in the chain.
   // If this is the case, read the record containing the updates from each file
@@ -3547,6 +3575,9 @@
     auto UpdateOffsets = std::move(UpdI->second);
     DeclUpdateOffsets.erase(UpdI);
 
+    // FIXME: This call to isConsumerInterestedIn is not safe because
+    // we could be deserializing declarations at the moment. We should
+    // delay calling this in the same way as done in D30793.
     bool WasInteresting = isConsumerInterestedIn(Context, D, false);
     for (auto &FileAndOffset : UpdateOffsets) {
       ModuleFile *F = FileAndOffset.first;
@@ -3568,7 +3599,8 @@
       // we need to hand it off to the consumer.
       if (!WasInteresting &&
           isConsumerInterestedIn(Context, D, Reader.hasPendingBody())) {
-        InterestingDecls.push_back(D);
+        PotentiallyInterestingDecls.push_back(
+            InterestingDecl(D, Reader.hasPendingBody()));
         WasInteresting = true;
       }
     }
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index 686a69b..062fe86 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -665,7 +665,7 @@
   E->setRHS(Record.readSubExpr());
   E->setOpcode((BinaryOperator::Opcode)Record.readInt());
   E->setOperatorLoc(ReadSourceLocation());
-  E->setFPContractable((bool)Record.readInt());
+  E->setFPFeatures(FPOptions(Record.readInt()));
 }
 
 void ASTStmtReader::VisitCompoundAssignOperator(CompoundAssignOperator *E) {
@@ -1220,7 +1220,7 @@
   VisitCallExpr(E);
   E->Operator = (OverloadedOperatorKind)Record.readInt();
   E->Range = Record.readSourceRange();
-  E->setFPContractable((bool)Record.readInt());
+  E->setFPFeatures(FPOptions(Record.readInt()));
 }
 
 void ASTStmtReader::VisitCXXConstructExpr(CXXConstructExpr *E) {
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 886523e..ed7ba0b 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -18,8 +18,8 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTUnresolvedSet.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/DeclContextInternals.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclContextInternals.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
@@ -33,8 +33,9 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileSystemOptions.h"
-#include "clang/Basic/LangOptions.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/Module.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/SourceManager.h"
@@ -64,9 +65,9 @@
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Bitcode/BitCodes.h"
 #include "llvm/Bitcode/BitstreamWriter.h"
@@ -78,6 +79,7 @@
 #include "llvm/Support/OnDiskHashTable.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/Process.h"
+#include "llvm/Support/SHA1.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cassert>
@@ -414,8 +416,10 @@
 void
 ASTTypeWriter::VisitDependentSizedExtVectorType(
                                         const DependentSizedExtVectorType *T) {
-  // FIXME: Serialize this type (C++ only)
-  llvm_unreachable("Cannot serialize dependent sized extended vector types");
+  Record.AddTypeRef(T->getElementType());
+  Record.AddStmt(T->getSizeExpr());
+  Record.AddSourceLocation(T->getAttributeLoc());
+  Code = TYPE_DEPENDENT_SIZED_EXT_VECTOR;
 }
 
 void
@@ -1001,7 +1005,6 @@
   // Control Block.
   BLOCK(CONTROL_BLOCK);
   RECORD(METADATA);
-  RECORD(SIGNATURE);
   RECORD(MODULE_NAME);
   RECORD(MODULE_DIRECTORY);
   RECORD(MODULE_MAP_FILE);
@@ -1014,7 +1017,6 @@
   BLOCK(OPTIONS_BLOCK);
   RECORD(LANGUAGE_OPTIONS);
   RECORD(TARGET_OPTIONS);
-  RECORD(DIAGNOSTIC_OPTIONS);
   RECORD(FILE_SYSTEM_OPTIONS);
   RECORD(HEADER_SEARCH_OPTIONS);
   RECORD(PREPROCESSOR_OPTIONS);
@@ -1049,7 +1051,6 @@
   RECORD(UPDATE_VISIBLE);
   RECORD(DECL_UPDATE_OFFSETS);
   RECORD(DECL_UPDATES);
-  RECORD(DIAG_PRAGMA_MAPPINGS);
   RECORD(CUDA_SPECIAL_DECL_REFS);
   RECORD(HEADER_SEARCH_TABLE);
   RECORD(FP_PRAGMA_OPTIONS);
@@ -1242,6 +1243,11 @@
   BLOCK(EXTENSION_BLOCK);
   RECORD(EXTENSION_METADATA);
 
+  BLOCK(UNHASHED_CONTROL_BLOCK);
+  RECORD(SIGNATURE);
+  RECORD(DIAGNOSTIC_OPTIONS);
+  RECORD(DIAG_PRAGMA_MAPPINGS);
+
 #undef RECORD
 #undef BLOCK
   Stream.ExitBlock();
@@ -1304,21 +1310,73 @@
   return Filename + Pos;
 }
 
-static ASTFileSignature getSignature() {
-  while (true) {
-    if (ASTFileSignature S = llvm::sys::Process::GetRandomNumber())
-      return S;
-    // Rely on GetRandomNumber to eventually return non-zero...
+ASTFileSignature ASTWriter::createSignature(StringRef Bytes) {
+  // Calculate the hash till start of UNHASHED_CONTROL_BLOCK.
+  llvm::SHA1 Hasher;
+  Hasher.update(ArrayRef<uint8_t>(Bytes.bytes_begin(), Bytes.size()));
+  auto Hash = Hasher.result();
+
+  // Convert to an array [5*i32].
+  ASTFileSignature Signature;
+  auto LShift = [&](unsigned char Val, unsigned Shift) {
+    return (uint32_t)Val << Shift;
+  };
+  for (int I = 0; I != 5; ++I)
+    Signature[I] = LShift(Hash[I * 4 + 0], 24) | LShift(Hash[I * 4 + 1], 16) |
+                   LShift(Hash[I * 4 + 2], 8) | LShift(Hash[I * 4 + 3], 0);
+
+  return Signature;
+}
+
+ASTFileSignature ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
+                                                      ASTContext &Context) {
+  // Flush first to prepare the PCM hash (signature).
+  Stream.FlushToWord();
+  auto StartOfUnhashedControl = Stream.GetCurrentBitNo() >> 3;
+
+  // Enter the block and prepare to write records.
+  RecordData Record;
+  Stream.EnterSubblock(UNHASHED_CONTROL_BLOCK_ID, 5);
+
+  // For implicit modules, write the hash of the PCM as its signature.
+  ASTFileSignature Signature;
+  if (WritingModule &&
+      PP.getHeaderSearchInfo().getHeaderSearchOpts().ModulesHashContent) {
+    Signature = createSignature(StringRef(Buffer.begin(), StartOfUnhashedControl));
+    Record.append(Signature.begin(), Signature.end());
+    Stream.EmitRecord(SIGNATURE, Record);
+    Record.clear();
   }
+
+  // Diagnostic options.
+  const auto &Diags = Context.getDiagnostics();
+  const DiagnosticOptions &DiagOpts = Diags.getDiagnosticOptions();
+#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
+#define ENUM_DIAGOPT(Name, Type, Bits, Default)                                \
+  Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
+#include "clang/Basic/DiagnosticOptions.def"
+  Record.push_back(DiagOpts.Warnings.size());
+  for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I)
+    AddString(DiagOpts.Warnings[I], Record);
+  Record.push_back(DiagOpts.Remarks.size());
+  for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I)
+    AddString(DiagOpts.Remarks[I], Record);
+  // Note: we don't serialize the log or serialization file names, because they
+  // are generally transient files and will almost always be overridden.
+  Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
+
+  // Write out the diagnostic/pragma mappings.
+  WritePragmaDiagnosticMappings(Diags, /* IsModule = */ WritingModule);
+
+  // Leave the options block.
+  Stream.ExitBlock();
+  return Signature;
 }
 
 /// \brief Write the control block.
-uint64_t ASTWriter::WriteControlBlock(Preprocessor &PP,
-                                      ASTContext &Context,
-                                      StringRef isysroot,
-                                      const std::string &OutputFile) {
-  ASTFileSignature Signature = 0;
-
+void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
+                                  StringRef isysroot,
+                                  const std::string &OutputFile) {
   using namespace llvm;
   Stream.EnterSubblock(CONTROL_BLOCK_ID, 5);
   RecordData Record;
@@ -1346,15 +1404,6 @@
                               getClangFullRepositoryVersion());
   }
   if (WritingModule) {
-    // For implicit modules we output a signature that we can use to ensure
-    // duplicate module builds don't collide in the cache as their output order
-    // is non-deterministic.
-    // FIXME: Remove this when output is deterministic.
-    if (Context.getLangOpts().ImplicitModules) {
-      Signature = getSignature();
-      RecordData::value_type Record[] = {Signature};
-      Stream.EmitRecord(SIGNATURE, Record);
-    }
 
     // Module name
     auto Abbrev = std::make_shared<BitCodeAbbrev>();
@@ -1420,17 +1469,23 @@
     serialization::ModuleManager &Mgr = Chain->getModuleManager();
     Record.clear();
 
-    for (auto *M : Mgr) {
+    for (ModuleFile &M : Mgr) {
       // Skip modules that weren't directly imported.
-      if (!M->isDirectlyImported())
+      if (!M.isDirectlyImported())
         continue;
 
-      Record.push_back((unsigned)M->Kind); // FIXME: Stable encoding
-      AddSourceLocation(M->ImportLoc, Record);
-      Record.push_back(M->File->getSize());
-      Record.push_back(getTimestampForOutput(M->File));
-      Record.push_back(M->Signature);
-      AddPath(M->FileName, Record);
+      Record.push_back((unsigned)M.Kind); // FIXME: Stable encoding
+      AddSourceLocation(M.ImportLoc, Record);
+
+      // If we have calculated signature, there is no need to store
+      // the size or timestamp.
+      Record.push_back(M.Signature ? 0 : M.File->getSize());
+      Record.push_back(M.Signature ? 0 : getTimestampForOutput(M.File));
+
+      for (auto I : M.Signature)
+        Record.push_back(I);
+
+      AddPath(M.FileName, Record);
     }
     Stream.EmitRecord(IMPORTS, Record);
   }
@@ -1492,24 +1547,6 @@
   }
   Stream.EmitRecord(TARGET_OPTIONS, Record);
 
-  // Diagnostic options.
-  Record.clear();
-  const DiagnosticOptions &DiagOpts
-    = Context.getDiagnostics().getDiagnosticOptions();
-#define DIAGOPT(Name, Bits, Default) Record.push_back(DiagOpts.Name);
-#define ENUM_DIAGOPT(Name, Type, Bits, Default) \
-  Record.push_back(static_cast<unsigned>(DiagOpts.get##Name()));
-#include "clang/Basic/DiagnosticOptions.def"
-  Record.push_back(DiagOpts.Warnings.size());
-  for (unsigned I = 0, N = DiagOpts.Warnings.size(); I != N; ++I)
-    AddString(DiagOpts.Warnings[I], Record);
-  Record.push_back(DiagOpts.Remarks.size());
-  for (unsigned I = 0, N = DiagOpts.Remarks.size(); I != N; ++I)
-    AddString(DiagOpts.Remarks[I], Record);
-  // Note: we don't serialize the log or serialization file names, because they
-  // are generally transient files and will almost always be overridden.
-  Stream.EmitRecord(DIAGNOSTIC_OPTIONS, Record);
-
   // File system options.
   Record.clear();
   const FileSystemOptions &FSOpts =
@@ -1623,7 +1660,6 @@
                   PP.getHeaderSearchInfo().getHeaderSearchOpts(),
                   PP.getLangOpts().Modules);
   Stream.ExitBlock();
-  return Signature;
 }
 
 namespace  {
@@ -2516,7 +2552,8 @@
 
   auto *Top = Mod->getTopLevelModule();
   if (Top != WritingModule &&
-      !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule)))
+      (getLangOpts().CompilingPCH ||
+       !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule))))
     return 0;
 
   return SubmoduleIDs[Mod] = NextSubmoduleID++;
@@ -2558,6 +2595,7 @@
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExplicit
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsExternC
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSwiftInferIAM...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferSubmodules...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExplicit...
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // InferExportWild...
@@ -2652,9 +2690,9 @@
     {
       RecordData::value_type Record[] = {
           SUBMODULE_DEFINITION, ID, ParentID, Mod->IsFramework, Mod->IsExplicit,
-          Mod->IsSystem, Mod->IsExternC, Mod->InferSubmodules,
-          Mod->InferExplicitSubmodules, Mod->InferExportWildcard,
-          Mod->ConfigMacrosExhaustive};
+          Mod->IsSystem, Mod->IsExternC, Mod->IsSwiftInferImportAsMember,
+          Mod->InferSubmodules, Mod->InferExplicitSubmodules,
+          Mod->InferExportWildcard, Mod->ConfigMacrosExhaustive};
       Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name);
     }
 
@@ -2789,38 +2827,43 @@
 
 void ASTWriter::WritePragmaDiagnosticMappings(const DiagnosticsEngine &Diag,
                                               bool isModule) {
-  // Make sure set diagnostic pragmas don't affect the translation unit that
-  // imports the module.
-  // FIXME: Make diagnostic pragma sections work properly with modules.
-  if (isModule)
-    return;
-
   llvm::SmallDenseMap<const DiagnosticsEngine::DiagState *, unsigned, 64>
       DiagStateIDMap;
   unsigned CurrID = 0;
-  DiagStateIDMap[&Diag.DiagStates.front()] = ++CurrID; // the command-line one.
   RecordData Record;
-  for (DiagnosticsEngine::DiagStatePointsTy::const_iterator
-         I = Diag.DiagStatePoints.begin(), E = Diag.DiagStatePoints.end();
-         I != E; ++I) {
-    const DiagnosticsEngine::DiagStatePoint &point = *I;
-    if (point.Loc.isInvalid())
-      continue;
 
-    AddSourceLocation(point.Loc, Record);
-    unsigned &DiagStateID = DiagStateIDMap[point.State];
+  auto AddDiagState = [&](const DiagnosticsEngine::DiagState *State,
+                          bool IncludeNonPragmaStates) {
+    unsigned &DiagStateID = DiagStateIDMap[State];
     Record.push_back(DiagStateID);
-    
+  
     if (DiagStateID == 0) {
       DiagStateID = ++CurrID;
-      for (const auto &I : *(point.State)) {
-        if (I.second.isPragma()) {
+      for (const auto &I : *State) {
+        if (I.second.isPragma() || IncludeNonPragmaStates) {
           Record.push_back(I.first);
           Record.push_back((unsigned)I.second.getSeverity());
         }
       }
-      Record.push_back(-1); // mark the end of the diag/map pairs for this
-                            // location.
+      // Add a sentinel to mark the end of the diag IDs.
+      Record.push_back(unsigned(-1));
+    }
+  };
+
+  AddDiagState(Diag.DiagStatesByLoc.FirstDiagState, isModule);
+  AddSourceLocation(Diag.DiagStatesByLoc.CurDiagStateLoc, Record);
+  AddDiagState(Diag.DiagStatesByLoc.CurDiagState, false);
+
+  for (auto &FileIDAndFile : Diag.DiagStatesByLoc.Files) {
+    if (!FileIDAndFile.first.isValid() ||
+        !FileIDAndFile.second.HasLocalTransitions)
+      continue;
+    AddSourceLocation(Diag.SourceMgr->getLocForStartOfFile(FileIDAndFile.first),
+                      Record);
+    Record.push_back(FileIDAndFile.second.StateTransitions.size());
+    for (auto &StatePoint : FileIDAndFile.second.StateTransitions) {
+      Record.push_back(StatePoint.Offset);
+      AddDiagState(StatePoint.State, false);
     }
   }
 
@@ -3283,8 +3326,6 @@
         NeedDecls(!IsModule || !Writer.getLangOpts().CPlusPlus),
         InterestingIdentifierOffsets(InterestingIdentifierOffsets) {}
 
-  bool needDecls() const { return NeedDecls; }
-
   static hash_value_type ComputeHash(const IdentifierInfo* II) {
     return llvm::HashString(II->getName());
   }
@@ -3434,10 +3475,8 @@
       assert(II && "NULL identifier in identifier table");
       // Write out identifiers if either the ID is local or the identifier has
       // changed since it was loaded.
-      if (ID >= FirstIdentID || !Chain || !II->isFromAST()
-          || II->hasChangedSinceDeserialization() ||
-          (Trait.needDecls() &&
-           II->hasFETokenInfoChangedSinceDeserialization()))
+      if (ID >= FirstIdentID || !Chain || !II->isFromAST() ||
+          II->hasChangedSinceDeserialization())
         Generator.insert(II, ID, Trait);
     }
 
@@ -3931,7 +3970,7 @@
 
 /// \brief Write an FP_PRAGMA_OPTIONS block for the given FPOptions.
 void ASTWriter::WriteFPPragmaOptions(const FPOptions &Opts) {
-  RecordData::value_type Record[] = {Opts.fp_contract};
+  RecordData::value_type Record[] = {Opts.getInt()};
   Stream.EmitRecord(FP_PRAGMA_OPTIONS, Record);
 }
 
@@ -4086,6 +4125,25 @@
   Stream.EmitRecord(POINTERS_TO_MEMBERS_PRAGMA_OPTIONS, Record);
 }
 
+/// \brief Write the state of 'pragma pack' at the end of the module.
+void ASTWriter::WritePackPragmaOptions(Sema &SemaRef) {
+  // Don't serialize pragma pack state for modules, since it should only take
+  // effect on a per-submodule basis.
+  if (WritingModule)
+    return;
+
+  RecordData Record;
+  Record.push_back(SemaRef.PackStack.CurrentValue);
+  AddSourceLocation(SemaRef.PackStack.CurrentPragmaLocation, Record);
+  Record.push_back(SemaRef.PackStack.Stack.size());
+  for (const auto &StackEntry : SemaRef.PackStack.Stack) {
+    Record.push_back(StackEntry.Value);
+    AddSourceLocation(StackEntry.PragmaLocation, Record);
+    AddString(StackEntry.StackSlotLabel, Record);
+  }
+  Stream.EmitRecord(PACK_PRAGMA_OPTIONS, Record);
+}
+
 void ASTWriter::WriteModuleFileExtension(Sema &SemaRef,
                                          ModuleFileExtensionWriter &Writer) {
   // Enter the extension block.
@@ -4223,9 +4281,11 @@
 }
 
 ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream,
+                     SmallVectorImpl<char> &Buffer, MemoryBufferCache &PCMCache,
                      ArrayRef<std::shared_ptr<ModuleFileExtension>> Extensions,
                      bool IncludeTimestamps)
-    : Stream(Stream), IncludeTimestamps(IncludeTimestamps) {
+    : Stream(Stream), Buffer(Buffer), PCMCache(PCMCache),
+      IncludeTimestamps(IncludeTimestamps) {
   for (const auto &Ext : Extensions) {
     if (auto Writer = Ext->createExtensionWriter(*this))
       ModuleFileExtensionWriters.push_back(std::move(Writer));
@@ -4245,9 +4305,10 @@
   return IncludeTimestamps ? E->getModificationTime() : 0;
 }
 
-uint64_t ASTWriter::WriteAST(Sema &SemaRef, const std::string &OutputFile,
-                             Module *WritingModule, StringRef isysroot,
-                             bool hasErrors) {
+ASTFileSignature ASTWriter::WriteAST(Sema &SemaRef,
+                                     const std::string &OutputFile,
+                                     Module *WritingModule, StringRef isysroot,
+                                     bool hasErrors) {
   WritingAST = true;
 
   ASTHasCompilerErrors = hasErrors;
@@ -4271,6 +4332,12 @@
   this->BaseDirectory.clear();
 
   WritingAST = false;
+  if (SemaRef.Context.getLangOpts().ImplicitModules && WritingModule) {
+    // Construct MemoryBuffer and update buffer manager.
+    PCMCache.addBuffer(OutputFile,
+                       llvm::MemoryBuffer::getMemBufferCopy(
+                           StringRef(Buffer.begin(), Buffer.size())));
+  }
   return Signature;
 }
 
@@ -4283,9 +4350,9 @@
   }
 }
 
-uint64_t ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
-                                 const std::string &OutputFile,
-                                 Module *WritingModule) {
+ASTFileSignature ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
+                                         const std::string &OutputFile,
+                                         Module *WritingModule) {
   using namespace llvm;
 
   bool isModule = WritingModule != nullptr;
@@ -4433,7 +4500,7 @@
   }
 
   // Write the control block
-  uint64_t Signature = WriteControlBlock(PP, Context, isysroot, OutputFile);
+  WriteControlBlock(PP, Context, isysroot, OutputFile);
 
   // Write the remaining AST contents.
   Stream.EnterSubblock(AST_BLOCK_ID, 5);
@@ -4573,10 +4640,10 @@
     SmallString<2048> Buffer;
     {
       llvm::raw_svector_ostream Out(Buffer);
-      for (ModuleFile *M : Chain->ModuleMgr) {
+      for (ModuleFile &M : Chain->ModuleMgr) {
         using namespace llvm::support;
         endian::Writer<little> LE(Out);
-        StringRef FileName = M->FileName;
+        StringRef FileName = M.FileName;
         LE.write<uint16_t>(FileName.size());
         Out.write(FileName.data(), FileName.size());
 
@@ -4594,15 +4661,15 @@
 
         // These values should be unique within a chain, since they will be read
         // as keys into ContinuousRangeMaps.
-        writeBaseIDOrNone(M->SLocEntryBaseOffset, M->LocalNumSLocEntries);
-        writeBaseIDOrNone(M->BaseIdentifierID, M->LocalNumIdentifiers);
-        writeBaseIDOrNone(M->BaseMacroID, M->LocalNumMacros);
-        writeBaseIDOrNone(M->BasePreprocessedEntityID,
-                          M->NumPreprocessedEntities);
-        writeBaseIDOrNone(M->BaseSubmoduleID, M->LocalNumSubmodules);
-        writeBaseIDOrNone(M->BaseSelectorID, M->LocalNumSelectors);
-        writeBaseIDOrNone(M->BaseDeclID, M->LocalNumDecls);
-        writeBaseIDOrNone(M->BaseTypeIndex, M->LocalNumTypes);
+        writeBaseIDOrNone(M.SLocEntryBaseOffset, M.LocalNumSLocEntries);
+        writeBaseIDOrNone(M.BaseIdentifierID, M.LocalNumIdentifiers);
+        writeBaseIDOrNone(M.BaseMacroID, M.LocalNumMacros);
+        writeBaseIDOrNone(M.BasePreprocessedEntityID,
+                          M.NumPreprocessedEntities);
+        writeBaseIDOrNone(M.BaseSubmoduleID, M.LocalNumSubmodules);
+        writeBaseIDOrNone(M.BaseSelectorID, M.LocalNumSelectors);
+        writeBaseIDOrNone(M.BaseDeclID, M.LocalNumDecls);
+        writeBaseIDOrNone(M.BaseTypeIndex, M.LocalNumTypes);
       }
     }
     RecordData::value_type Record[] = {MODULE_OFFSET_MAP};
@@ -4650,7 +4717,6 @@
   WriteOpenCLExtensionTypes(SemaRef);
   WriteOpenCLExtensionDecls(SemaRef);
   WriteCUDAPragmas(SemaRef);
-  WritePragmaDiagnosticMappings(Context.getDiagnostics(), isModule);
 
   // If we're emitting a module, write out the submodule information.  
   if (WritingModule)
@@ -4765,6 +4831,7 @@
     WriteMSStructPragmaOptions(SemaRef);
     WriteMSPointersToMembersPragmaOptions(SemaRef);
   }
+  WritePackPragmaOptions(SemaRef);
 
   // Some simple statistics
   RecordData::value_type Record[] = {
@@ -4776,7 +4843,7 @@
   for (const auto &ExtWriter : ModuleFileExtensionWriters)
     WriteModuleFileExtension(SemaRef, *ExtWriter);
 
-  return Signature;
+  return writeUnhashedControlBlock(PP, Context);
 }
 
 void ASTWriter::WriteDeclUpdatesBlocks(RecordDataImpl &OffsetsRecord) {
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index d8466e9..32448cc 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -791,7 +791,9 @@
   // FIXME: stable encoding
   Record.push_back((unsigned)D->getPropertyImplementation());
   Record.AddDeclarationName(D->getGetterName());
+  Record.AddSourceLocation(D->getGetterNameLoc());
   Record.AddDeclarationName(D->getSetterName());
+  Record.AddSourceLocation(D->getSetterNameLoc());
   Record.AddDeclRef(D->getGetterMethodDecl());
   Record.AddDeclRef(D->getSetterMethodDecl());
   Record.AddDeclRef(D->getPropertyIvarDecl());
@@ -806,7 +808,6 @@
 
 void ASTDeclWriter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
   VisitObjCImplDecl(D);
-  Record.AddIdentifierRef(D->getIdentifier());
   Record.AddSourceLocation(D->getCategoryNameLoc());
   Code = serialization::DECL_OBJC_CATEGORY_IMPL;
 }
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 01fd98c..e55da00 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -645,7 +645,7 @@
   Record.AddStmt(E->getRHS());
   Record.push_back(E->getOpcode()); // FIXME: stable encoding
   Record.AddSourceLocation(E->getOperatorLoc());
-  Record.push_back(E->isFPContractable());
+  Record.push_back(E->getFPFeatures().getInt());
   Code = serialization::EXPR_BINARY_OPERATOR;
 }
 
@@ -1213,7 +1213,7 @@
   VisitCallExpr(E);
   Record.push_back(E->getOperator());
   Record.AddSourceRange(E->Range);
-  Record.push_back(E->isFPContractable());
+  Record.push_back(E->getFPFeatures().getInt());
   Code = serialization::EXPR_CXX_OPERATOR_CALL;
 }
 
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index 7f1b750..429ae8e 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -28,7 +28,8 @@
     bool AllowASTWithErrors, bool IncludeTimestamps)
     : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()),
       SemaPtr(nullptr), Buffer(Buffer), Stream(Buffer->Data),
-      Writer(Stream, Extensions, IncludeTimestamps),
+      Writer(Stream, Buffer->Data, PP.getPCMCache(), Extensions,
+             IncludeTimestamps),
       AllowASTWithErrors(AllowASTWithErrors) {
   Buffer->IsComplete = false;
 }
diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index ae5796e..6978e7e 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/lib/Serialization/GlobalModuleIndex.cpp
@@ -376,6 +376,15 @@
     /// \brief The set of modules on which this module depends. Each entry is
     /// a module ID.
     SmallVector<unsigned, 4> Dependencies;
+    ASTFileSignature Signature;
+  };
+
+  struct ImportedModuleFileInfo {
+    off_t StoredSize;
+    time_t StoredModTime;
+    ASTFileSignature StoredSignature;
+    ImportedModuleFileInfo(off_t Size, time_t ModTime, ASTFileSignature Sig)
+        : StoredSize(Size), StoredModTime(ModTime), StoredSignature(Sig) {}
   };
 
   /// \brief Builder that generates the global module index file.
@@ -383,12 +392,20 @@
     FileManager &FileMgr;
     const PCHContainerReader &PCHContainerRdr;
 
-    /// \brief Mapping from files to module file information.
+    /// Mapping from files to module file information.
     typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap;
 
-    /// \brief Information about each of the known module files.
+    /// Information about each of the known module files.
     ModuleFilesMap ModuleFiles;
 
+    /// \brief Mapping from the imported module file to the imported
+    /// information.
+    typedef std::multimap<const FileEntry *, ImportedModuleFileInfo>
+        ImportedModuleFilesMap;
+
+    /// \brief Information about each importing of a module file.
+    ImportedModuleFilesMap ImportedModuleFiles;
+
     /// \brief Mapping from identifiers to the list of module file IDs that
     /// consider this identifier to be interesting.
     typedef llvm::StringMap<SmallVector<unsigned, 2> > InterestingIdentifierMap;
@@ -424,7 +441,8 @@
     bool loadModuleFile(const FileEntry *File);
 
     /// \brief Write the index to the given bitstream.
-    void writeIndex(llvm::BitstreamWriter &Stream);
+    /// \returns true if an error occurred, false otherwise.
+    bool writeIndex(llvm::BitstreamWriter &Stream);
   };
 }
 
@@ -515,7 +533,7 @@
   unsigned ID = getModuleFileInfo(File).ID;
 
   // Search for the blocks and records we care about.
-  enum { Other, ControlBlock, ASTBlock } State = Other;
+  enum { Other, ControlBlock, ASTBlock, DiagnosticOptionsBlock } State = Other;
   bool Done = false;
   while (!Done) {
     llvm::BitstreamEntry Entry = InStream.advance();
@@ -553,6 +571,15 @@
         continue;
       }
 
+      if (Entry.ID == UNHASHED_CONTROL_BLOCK_ID) {
+        if (InStream.EnterSubBlock(UNHASHED_CONTROL_BLOCK_ID))
+          return true;
+
+        // Found the Diagnostic Options block.
+        State = DiagnosticOptionsBlock;
+        continue;
+      }
+
       if (InStream.SkipBlock())
         return true;
 
@@ -587,7 +614,10 @@
 
         // Skip the stored signature.
         // FIXME: we could read the signature out of the import and validate it.
-        Idx++;
+        ASTFileSignature StoredSignature = {
+            {{(uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++], (uint32_t)Record[Idx++],
+              (uint32_t)Record[Idx++]}}};
 
         // Retrieve the imported file name.
         unsigned Length = Record[Idx++];
@@ -599,11 +629,16 @@
         const FileEntry *DependsOnFile
           = FileMgr.getFile(ImportedFile, /*openFile=*/false,
                             /*cacheFailure=*/false);
-        if (!DependsOnFile ||
-            (StoredSize != DependsOnFile->getSize()) ||
-            (StoredModTime != DependsOnFile->getModificationTime()))
+
+        if (!DependsOnFile)
           return true;
 
+        // Save the information in ImportedModuleFileInfo so we can verify after
+        // loading all pcms.
+        ImportedModuleFiles.insert(std::make_pair(
+            DependsOnFile, ImportedModuleFileInfo(StoredSize, StoredModTime,
+                                                  StoredSignature)));
+
         // Record the dependency.
         unsigned DependsOnID = getModuleFileInfo(DependsOnFile).ID;
         getModuleFileInfo(File).Dependencies.push_back(DependsOnID);
@@ -632,6 +667,12 @@
       }
     }
 
+    // Get Signature.
+    if (State == DiagnosticOptionsBlock && Code == SIGNATURE)
+      getModuleFileInfo(File).Signature = {
+          {{(uint32_t)Record[0], (uint32_t)Record[1], (uint32_t)Record[2],
+            (uint32_t)Record[3], (uint32_t)Record[4]}}};
+
     // We don't care about this record.
   }
 
@@ -680,7 +721,20 @@
 
 }
 
-void GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
+bool GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
+  for (auto MapEntry : ImportedModuleFiles) {
+    auto *File = MapEntry.first;
+    ImportedModuleFileInfo &Info = MapEntry.second;
+    if (getModuleFileInfo(File).Signature) {
+      if (getModuleFileInfo(File).Signature != Info.StoredSignature)
+        // Verify Signature.
+        return true;
+    } else if (Info.StoredSize != File->getSize() ||
+               Info.StoredModTime != File->getModificationTime())
+      // Verify Size and ModTime.
+      return true;
+  }
+
   using namespace llvm;
   
   // Emit the file header.
@@ -756,6 +810,7 @@
   }
 
   Stream.ExitBlock();
+  return false;
 }
 
 GlobalModuleIndex::ErrorCode
@@ -816,7 +871,8 @@
   SmallVector<char, 16> OutputBuffer;
   {
     llvm::BitstreamWriter OutputStream(OutputBuffer);
-    Builder.writeIndex(OutputStream);
+    if (Builder.writeIndex(OutputStream))
+      return EC_IOError;
   }
 
   // Write the global index file to a temporary file.
diff --git a/lib/Serialization/Module.cpp b/lib/Serialization/Module.cpp
index 72b0861..5a44d26 100644
--- a/lib/Serialization/Module.cpp
+++ b/lib/Serialization/Module.cpp
@@ -19,28 +19,6 @@
 using namespace serialization;
 using namespace reader;
 
-ModuleFile::ModuleFile(ModuleKind Kind, unsigned Generation)
-  : Kind(Kind), File(nullptr), Signature(0), DirectlyImported(false),
-    Generation(Generation), SizeInBits(0),
-    LocalNumSLocEntries(0), SLocEntryBaseID(0),
-    SLocEntryBaseOffset(0), SLocEntryOffsets(nullptr),
-    LocalNumIdentifiers(0),
-    IdentifierOffsets(nullptr), BaseIdentifierID(0),
-    IdentifierTableData(nullptr), IdentifierLookupTable(nullptr),
-    LocalNumMacros(0), MacroOffsets(nullptr),
-    BasePreprocessedEntityID(0),
-    PreprocessedEntityOffsets(nullptr), NumPreprocessedEntities(0),
-    LocalNumHeaderFileInfos(0), 
-    HeaderFileInfoTableData(nullptr), HeaderFileInfoTable(nullptr),
-    LocalNumSubmodules(0), BaseSubmoduleID(0),
-    LocalNumSelectors(0), SelectorOffsets(nullptr), BaseSelectorID(0),
-    SelectorLookupTableData(nullptr), SelectorLookupTable(nullptr),
-    LocalNumDecls(0), DeclOffsets(nullptr), BaseDeclID(0),
-    FileSortedDecls(nullptr), NumFileSortedDecls(0),
-    ObjCCategoriesMap(nullptr), LocalNumObjCCategoriesInMap(0),
-    LocalNumTypes(0), TypeOffsets(nullptr), BaseTypeIndex(0)
-{}
-
 ModuleFile::~ModuleFile() {
   delete static_cast<ASTIdentifierLookupTable *>(IdentifierLookupTable);
   delete static_cast<HeaderFileInfoLookupTable *>(HeaderFileInfoTable);
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index 722b547..e35a44d 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/lib/Serialization/ModuleManager.cpp
@@ -12,6 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 #include "clang/Serialization/ModuleManager.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/ModuleMap.h"
@@ -52,6 +53,30 @@
   return std::move(InMemoryBuffers[Entry]);
 }
 
+static bool checkSignature(ASTFileSignature Signature,
+                           ASTFileSignature ExpectedSignature,
+                           std::string &ErrorStr) {
+  if (!ExpectedSignature || Signature == ExpectedSignature)
+    return false;
+
+  ErrorStr =
+      Signature ? "signature mismatch" : "could not read module signature";
+  return true;
+}
+
+static void updateModuleImports(ModuleFile &MF, ModuleFile *ImportedBy,
+                                SourceLocation ImportLoc) {
+  if (ImportedBy) {
+    MF.ImportedBy.insert(ImportedBy);
+    ImportedBy->Imports.insert(&MF);
+  } else {
+    if (!MF.DirectlyImported)
+      MF.ImportLoc = ImportLoc;
+
+    MF.DirectlyImported = true;
+  }
+}
+
 ModuleManager::AddModuleResult
 ModuleManager::addModule(StringRef FileName, ModuleKind Type,
                          SourceLocation ImportLoc, ModuleFile *ImportedBy,
@@ -84,141 +109,133 @@
   }
 
   // Check whether we already loaded this module, before
-  ModuleFile *ModuleEntry = Modules[Entry];
-  bool NewModule = false;
-  if (!ModuleEntry) {
-    // Allocate a new module.
-    NewModule = true;
-    ModuleEntry = new ModuleFile(Type, Generation);
-    ModuleEntry->Index = Chain.size();
-    ModuleEntry->FileName = FileName.str();
-    ModuleEntry->File = Entry;
-    ModuleEntry->ImportLoc = ImportLoc;
-    ModuleEntry->InputFilesValidationTimestamp = 0;
-
-    if (ModuleEntry->Kind == MK_ImplicitModule) {
-      std::string TimestampFilename = ModuleEntry->getTimestampFilename();
-      vfs::Status Status;
-      // A cached stat value would be fine as well.
-      if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
-        ModuleEntry->InputFilesValidationTimestamp =
-            llvm::sys::toTimeT(Status.getLastModificationTime());
-    }
-
-    // Load the contents of the module
-    if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
-      // The buffer was already provided for us.
-      ModuleEntry->Buffer = std::move(Buffer);
-    } else {
-      // Open the AST file.
-      llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf(
-          (std::error_code()));
-      if (FileName == "-") {
-        Buf = llvm::MemoryBuffer::getSTDIN();
-      } else {
-        // Leave the FileEntry open so if it gets read again by another
-        // ModuleManager it must be the same underlying file.
-        // FIXME: Because FileManager::getFile() doesn't guarantee that it will
-        // give us an open file, this may not be 100% reliable.
-        Buf = FileMgr.getBufferForFile(ModuleEntry->File,
-                                       /*IsVolatile=*/false,
-                                       /*ShouldClose=*/false);
-      }
-
-      if (!Buf) {
-        ErrorStr = Buf.getError().message();
-        delete ModuleEntry;
-        return Missing;
-      }
-
-      ModuleEntry->Buffer = std::move(*Buf);
-    }
-
-    // Initialize the stream.
-    ModuleEntry->Data = PCHContainerRdr.ExtractPCH(*ModuleEntry->Buffer);
-  }
-
-  if (ExpectedSignature) {
-    // If we've not read the control block yet, read the signature eagerly now
-    // so that we can check it.
-    if (!ModuleEntry->Signature)
-      ModuleEntry->Signature = ReadSignature(ModuleEntry->Data);
-
-    if (ModuleEntry->Signature != ExpectedSignature) {
-      ErrorStr = ModuleEntry->Signature ? "signature mismatch"
-                                        : "could not read module signature";
-
-      if (NewModule)
-        delete ModuleEntry;
+  if (ModuleFile *ModuleEntry = Modules.lookup(Entry)) {
+    // Check the stored signature.
+    if (checkSignature(ModuleEntry->Signature, ExpectedSignature, ErrorStr))
       return OutOfDate;
-    }
-  }
 
-  if (ImportedBy) {
-    ModuleEntry->ImportedBy.insert(ImportedBy);
-    ImportedBy->Imports.insert(ModuleEntry);
-  } else {
-    if (!ModuleEntry->DirectlyImported)
-      ModuleEntry->ImportLoc = ImportLoc;
-    
-    ModuleEntry->DirectlyImported = true;
-  }
-
-  Module = ModuleEntry;
-
-  if (!NewModule)
+    Module = ModuleEntry;
+    updateModuleImports(*ModuleEntry, ImportedBy, ImportLoc);
     return AlreadyLoaded;
+  }
 
-  assert(!Modules[Entry] && "module loaded twice");
-  Modules[Entry] = ModuleEntry;
+  // Allocate a new module.
+  auto NewModule = llvm::make_unique<ModuleFile>(Type, Generation);
+  NewModule->Index = Chain.size();
+  NewModule->FileName = FileName.str();
+  NewModule->File = Entry;
+  NewModule->ImportLoc = ImportLoc;
+  NewModule->InputFilesValidationTimestamp = 0;
 
-  Chain.push_back(ModuleEntry);
-  if (!ModuleEntry->isModule())
-    PCHChain.push_back(ModuleEntry);
+  if (NewModule->Kind == MK_ImplicitModule) {
+    std::string TimestampFilename = NewModule->getTimestampFilename();
+    vfs::Status Status;
+    // A cached stat value would be fine as well.
+    if (!FileMgr.getNoncachedStatValue(TimestampFilename, Status))
+      NewModule->InputFilesValidationTimestamp =
+          llvm::sys::toTimeT(Status.getLastModificationTime());
+  }
+
+  // Load the contents of the module
+  if (std::unique_ptr<llvm::MemoryBuffer> Buffer = lookupBuffer(FileName)) {
+    // The buffer was already provided for us.
+    NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(Buffer));
+  } else if (llvm::MemoryBuffer *Buffer = PCMCache->lookupBuffer(FileName)) {
+    NewModule->Buffer = Buffer;
+  } else {
+    // Open the AST file.
+    llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buf((std::error_code()));
+    if (FileName == "-") {
+      Buf = llvm::MemoryBuffer::getSTDIN();
+    } else {
+      // Leave the FileEntry open so if it gets read again by another
+      // ModuleManager it must be the same underlying file.
+      // FIXME: Because FileManager::getFile() doesn't guarantee that it will
+      // give us an open file, this may not be 100% reliable.
+      Buf = FileMgr.getBufferForFile(NewModule->File,
+                                     /*IsVolatile=*/false,
+                                     /*ShouldClose=*/false);
+    }
+
+    if (!Buf) {
+      ErrorStr = Buf.getError().message();
+      return Missing;
+    }
+
+    NewModule->Buffer = &PCMCache->addBuffer(FileName, std::move(*Buf));
+  }
+
+  // Initialize the stream.
+  NewModule->Data = PCHContainerRdr.ExtractPCH(*NewModule->Buffer);
+
+  // Read the signature eagerly now so that we can check it.  Avoid calling
+  // ReadSignature unless there's something to check though.
+  if (ExpectedSignature && checkSignature(ReadSignature(NewModule->Data),
+                                          ExpectedSignature, ErrorStr)) {
+    // Try to remove the buffer.  If it can't be removed, then it was already
+    // validated by this process.
+    if (!PCMCache->tryToRemoveBuffer(NewModule->FileName))
+      FileMgr.invalidateCache(NewModule->File);
+    return OutOfDate;
+  }
+
+  // We're keeping this module.  Store it everywhere.
+  Module = Modules[Entry] = NewModule.get();
+
+  updateModuleImports(*NewModule, ImportedBy, ImportLoc);
+
+  if (!NewModule->isModule())
+    PCHChain.push_back(NewModule.get());
   if (!ImportedBy)
-    Roots.push_back(ModuleEntry);
+    Roots.push_back(NewModule.get());
 
+  Chain.push_back(std::move(NewModule));
   return NewlyLoaded;
 }
 
 void ModuleManager::removeModules(
-    ModuleIterator first, ModuleIterator last,
+    ModuleIterator First,
     llvm::SmallPtrSetImpl<ModuleFile *> &LoadedSuccessfully,
     ModuleMap *modMap) {
-  if (first == last)
+  auto Last = end();
+  if (First == Last)
     return;
 
+
   // Explicitly clear VisitOrder since we might not notice it is stale.
   VisitOrder.clear();
 
   // Collect the set of module file pointers that we'll be removing.
-  llvm::SmallPtrSet<ModuleFile *, 4> victimSet(first, last);
+  llvm::SmallPtrSet<ModuleFile *, 4> victimSet(
+      (llvm::pointer_iterator<ModuleIterator>(First)),
+      (llvm::pointer_iterator<ModuleIterator>(Last)));
 
   auto IsVictim = [&](ModuleFile *MF) {
     return victimSet.count(MF);
   };
   // Remove any references to the now-destroyed modules.
-  for (unsigned i = 0, n = Chain.size(); i != n; ++i) {
-    Chain[i]->ImportedBy.remove_if(IsVictim);
+  for (auto I = begin(); I != First; ++I) {
+    I->Imports.remove_if(IsVictim);
+    I->ImportedBy.remove_if(IsVictim);
   }
   Roots.erase(std::remove_if(Roots.begin(), Roots.end(), IsVictim),
               Roots.end());
 
   // Remove the modules from the PCH chain.
-  for (auto I = first; I != last; ++I) {
-    if (!(*I)->isModule()) {
-      PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), *I),
+  for (auto I = First; I != Last; ++I) {
+    if (!I->isModule()) {
+      PCHChain.erase(std::find(PCHChain.begin(), PCHChain.end(), &*I),
                      PCHChain.end());
       break;
     }
   }
 
   // Delete the modules and erase them from the various structures.
-  for (ModuleIterator victim = first; victim != last; ++victim) {
-    Modules.erase((*victim)->File);
+  for (ModuleIterator victim = First; victim != Last; ++victim) {
+    Modules.erase(victim->File);
 
     if (modMap) {
-      StringRef ModuleName = (*victim)->ModuleName;
+      StringRef ModuleName = victim->ModuleName;
       if (Module *mod = modMap->findModule(ModuleName)) {
         mod->setASTFile(nullptr);
       }
@@ -227,14 +244,17 @@
     // Files that didn't make it through ReadASTCore successfully will be
     // rebuilt (or there was an error). Invalidate them so that we can load the
     // new files that will be renamed over the old ones.
-    if (LoadedSuccessfully.count(*victim) == 0)
-      FileMgr.invalidateCache((*victim)->File);
-
-    delete *victim;
+    //
+    // The PCMCache tracks whether the module was succesfully loaded in another
+    // thread/context; in that case, it won't need to be rebuilt (and we can't
+    // safely invalidate it anyway).
+    if (LoadedSuccessfully.count(&*victim) == 0 &&
+        !PCMCache->tryToRemoveBuffer(victim->FileName))
+      FileMgr.invalidateCache(victim->File);
   }
 
-  // Remove the modules from the chain.
-  Chain.erase(first, last);
+  // Delete the modules.
+  Chain.erase(Chain.begin() + (First - begin()), Chain.end());
 }
 
 void
@@ -274,11 +294,9 @@
 
   // Notify the global module index about all of the modules we've already
   // loaded.
-  for (unsigned I = 0, N = Chain.size(); I != N; ++I) {
-    if (!GlobalIndex->loadedModuleFile(Chain[I])) {
-      ModulesInCommonWithGlobalIndex.push_back(Chain[I]);
-    }
-  }
+  for (ModuleFile &M : *this)
+    if (!GlobalIndex->loadedModuleFile(&M))
+      ModulesInCommonWithGlobalIndex.push_back(&M);
 }
 
 void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
@@ -288,16 +306,12 @@
   ModulesInCommonWithGlobalIndex.push_back(MF);
 }
 
-ModuleManager::ModuleManager(FileManager &FileMgr,
+ModuleManager::ModuleManager(FileManager &FileMgr, MemoryBufferCache &PCMCache,
                              const PCHContainerReader &PCHContainerRdr)
-    : FileMgr(FileMgr), PCHContainerRdr(PCHContainerRdr), GlobalIndex(),
-      FirstVisitState(nullptr) {}
+    : FileMgr(FileMgr), PCMCache(&PCMCache), PCHContainerRdr(PCHContainerRdr),
+      GlobalIndex(), FirstVisitState(nullptr) {}
 
-ModuleManager::~ModuleManager() {
-  for (unsigned i = 0, e = Chain.size(); i != e; ++i)
-    delete Chain[e - i - 1];
-  delete FirstVisitState;
-}
+ModuleManager::~ModuleManager() { delete FirstVisitState; }
 
 void ModuleManager::visit(llvm::function_ref<bool(ModuleFile &M)> Visitor,
                           llvm::SmallPtrSetImpl<ModuleFile *> *ModuleFilesHit) {
@@ -314,11 +328,11 @@
     Queue.reserve(N);
     llvm::SmallVector<unsigned, 4> UnusedIncomingEdges;
     UnusedIncomingEdges.resize(size());
-    for (ModuleFile *M : llvm::reverse(*this)) {
-      unsigned Size = M->ImportedBy.size();
-      UnusedIncomingEdges[M->Index] = Size;
+    for (ModuleFile &M : llvm::reverse(*this)) {
+      unsigned Size = M.ImportedBy.size();
+      UnusedIncomingEdges[M.Index] = Size;
       if (!Size)
-        Queue.push_back(M);
+        Queue.push_back(&M);
     }
 
     // Traverse the graph, making sure to visit a module before visiting any
@@ -433,7 +447,7 @@
   struct GraphTraits<ModuleManager> {
     typedef ModuleFile *NodeRef;
     typedef llvm::SetVector<ModuleFile *>::const_iterator ChildIteratorType;
-    typedef ModuleManager::ModuleConstIterator nodes_iterator;
+    typedef pointer_iterator<ModuleManager::ModuleConstIterator> nodes_iterator;
 
     static ChildIteratorType child_begin(NodeRef Node) {
       return Node->Imports.begin();
@@ -444,11 +458,11 @@
     }
     
     static nodes_iterator nodes_begin(const ModuleManager &Manager) {
-      return Manager.begin();
+      return nodes_iterator(Manager.begin());
     }
     
     static nodes_iterator nodes_end(const ModuleManager &Manager) {
-      return Manager.end();
+      return nodes_iterator(Manager.end());
     }
   };
   
diff --git a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
index e6592a2..90d5c0e 100644
--- a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
@@ -24,16 +24,29 @@
 
 namespace {
 
-class AnalysisOrderChecker : public Checker< check::PreStmt<CastExpr>,
-                                             check::PostStmt<CastExpr>,
-                                             check::PreStmt<ArraySubscriptExpr>,
-                                             check::PostStmt<ArraySubscriptExpr>> {
-  bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const {
-    AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions();
+class AnalysisOrderChecker
+    : public Checker<check::PreStmt<CastExpr>,
+                     check::PostStmt<CastExpr>,
+                     check::PreStmt<ArraySubscriptExpr>,
+                     check::PostStmt<ArraySubscriptExpr>,
+                     check::Bind,
+                     check::RegionChanges> {
+  bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const {
     return Opts.getBooleanOption("*", false, this) ||
         Opts.getBooleanOption(CallbackName, false, this);
   }
 
+  bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const {
+    AnalyzerOptions &Opts = C.getAnalysisManager().getAnalyzerOptions();
+    return isCallbackEnabled(Opts, CallbackName);
+  }
+
+  bool isCallbackEnabled(ProgramStateRef State, StringRef CallbackName) const {
+    AnalyzerOptions &Opts = State->getStateManager().getOwningEngine()
+                                 ->getAnalysisManager().getAnalyzerOptions();
+    return isCallbackEnabled(Opts, CallbackName);
+  }
+
 public:
   void checkPreStmt(const CastExpr *CE, CheckerContext &C) const {
     if (isCallbackEnabled(C, "PreStmtCastExpr"))
@@ -47,17 +60,35 @@
                    << ")\n";
   }
 
-  void checkPreStmt(const ArraySubscriptExpr *SubExpr, CheckerContext &C) const {
+  void checkPreStmt(const ArraySubscriptExpr *SubExpr,
+                    CheckerContext &C) const {
     if (isCallbackEnabled(C, "PreStmtArraySubscriptExpr"))
       llvm::errs() << "PreStmt<ArraySubscriptExpr>\n";
   }
 
-  void checkPostStmt(const ArraySubscriptExpr *SubExpr, CheckerContext &C) const {
+  void checkPostStmt(const ArraySubscriptExpr *SubExpr,
+                     CheckerContext &C) const {
     if (isCallbackEnabled(C, "PostStmtArraySubscriptExpr"))
       llvm::errs() << "PostStmt<ArraySubscriptExpr>\n";
   }
+
+  void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const {
+    if (isCallbackEnabled(C, "Bind"))
+      llvm::errs() << "Bind\n";
+  }
+
+  ProgramStateRef
+  checkRegionChanges(ProgramStateRef State,
+                     const InvalidatedSymbols *Invalidated,
+                     ArrayRef<const MemRegion *> ExplicitRegions,
+                     ArrayRef<const MemRegion *> Regions,
+                     const LocationContext *LCtx, const CallEvent *Call) const {
+    if (isCallbackEnabled(State, "RegionChanges"))
+      llvm::errs() << "RegionChanges\n";
+    return State;
+  }
 };
-}
+} // end anonymous namespace
 
 //===----------------------------------------------------------------------===//
 // Registration.
diff --git a/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
index 082a487..d19630e 100644
--- a/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
@@ -29,7 +29,9 @@
 class BlockInCriticalSectionChecker : public Checker<check::PostCall,
                                                      check::PreCall> {
 
-  CallDescription LockFn, UnlockFn, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn;
+  CallDescription LockFn, UnlockFn, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn,
+                  PthreadLockFn, PthreadTryLockFn, PthreadUnlockFn,
+                  MtxLock, MtxTimedLock, MtxTryLock, MtxUnlock;
 
   std::unique_ptr<BugType> BlockInCritSectionBugType;
 
@@ -40,6 +42,10 @@
 public:
   BlockInCriticalSectionChecker();
 
+  bool isBlockingFunction(const CallEvent &Call) const;
+  bool isLockFunction(const CallEvent &Call) const;
+  bool isUnlockFunction(const CallEvent &Call) const;
+
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
 
   /// Process unlock.
@@ -55,34 +61,69 @@
 
 BlockInCriticalSectionChecker::BlockInCriticalSectionChecker()
     : LockFn("lock"), UnlockFn("unlock"), SleepFn("sleep"), GetcFn("getc"),
-      FgetsFn("fgets"), ReadFn("read"), RecvFn("recv") {
+      FgetsFn("fgets"), ReadFn("read"), RecvFn("recv"),
+      PthreadLockFn("pthread_mutex_lock"),
+      PthreadTryLockFn("pthread_mutex_trylock"),
+      PthreadUnlockFn("pthread_mutex_unlock"),
+      MtxLock("mtx_lock"),
+      MtxTimedLock("mtx_timedlock"),
+      MtxTryLock("mtx_trylock"),
+      MtxUnlock("mtx_unlock") {
   // Initialize the bug type.
   BlockInCritSectionBugType.reset(
       new BugType(this, "Call to blocking function in critical section",
                         "Blocking Error"));
 }
 
+bool BlockInCriticalSectionChecker::isBlockingFunction(const CallEvent &Call) const {
+  if (Call.isCalled(SleepFn)
+      || Call.isCalled(GetcFn)
+      || Call.isCalled(FgetsFn)
+      || Call.isCalled(ReadFn)
+      || Call.isCalled(RecvFn)) {
+    return true;
+  }
+  return false;
+}
+
+bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) const {
+  if (Call.isCalled(LockFn)
+      || Call.isCalled(PthreadLockFn)
+      || Call.isCalled(PthreadTryLockFn)
+      || Call.isCalled(MtxLock)
+      || Call.isCalled(MtxTimedLock)
+      || Call.isCalled(MtxTryLock)) {
+    return true;
+  }
+  return false;
+}
+
+bool BlockInCriticalSectionChecker::isUnlockFunction(const CallEvent &Call) const {
+  if (Call.isCalled(UnlockFn)
+       || Call.isCalled(PthreadUnlockFn)
+       || Call.isCalled(MtxUnlock)) {
+    return true;
+  }
+  return false;
+}
+
 void BlockInCriticalSectionChecker::checkPreCall(const CallEvent &Call,
                                                  CheckerContext &C) const {
 }
 
 void BlockInCriticalSectionChecker::checkPostCall(const CallEvent &Call,
                                                   CheckerContext &C) const {
-  if (!Call.isCalled(LockFn)
-      && !Call.isCalled(SleepFn)
-      && !Call.isCalled(GetcFn)
-      && !Call.isCalled(FgetsFn)
-      && !Call.isCalled(ReadFn)
-      && !Call.isCalled(RecvFn)
-      && !Call.isCalled(UnlockFn))
+  if (!isBlockingFunction(Call)
+      && !isLockFunction(Call)
+      && !isUnlockFunction(Call))
     return;
 
   ProgramStateRef State = C.getState();
   unsigned mutexCount = State->get<MutexCounter>();
-  if (Call.isCalled(UnlockFn) && mutexCount > 0) {
+  if (isUnlockFunction(Call) && mutexCount > 0) {
     State = State->set<MutexCounter>(--mutexCount);
     C.addTransition(State);
-  } else if (Call.isCalled(LockFn)) {
+  } else if (isLockFunction(Call)) {
     State = State->set<MutexCounter>(++mutexCount);
     C.addTransition(State);
   } else if (mutexCount > 0) {
@@ -97,8 +138,11 @@
   if (!ErrNode)
     return;
 
-  auto R = llvm::make_unique<BugReport>(*BlockInCritSectionBugType,
-      "A blocking function %s is called inside a critical section.", ErrNode);
+  std::string msg;
+  llvm::raw_string_ostream os(msg);
+  os << "Call to blocking function '" << Call.getCalleeIdentifier()->getName()
+     << "' inside of critical section";
+  auto R = llvm::make_unique<BugReport>(*BlockInCritSectionBugType, os.str(), ErrNode);
   R->addRange(Call.getSourceRange());
   R->markInteresting(BlockDescSym);
   C.emitReport(std::move(R));
diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 05505ec..60d60bc 100644
--- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -48,6 +48,7 @@
   MallocChecker.cpp
   MallocOverflowSecurityChecker.cpp
   MallocSizeofChecker.cpp
+  MisusedMovedObjectChecker.cpp
   MPI-Checker/MPIBugReporter.cpp
   MPI-Checker/MPIChecker.cpp
   MPI-Checker/MPIFunctionClassifier.cpp
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 238032c8..32e3ce9 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -68,6 +68,7 @@
                        const InvalidatedSymbols *,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) const;
 
   typedef void (CStringChecker::*FnCheck)(CheckerContext &,
@@ -1943,8 +1944,12 @@
     // Overwrite the search string pointer. The new value is either an address
     // further along in the same string, or NULL if there are no more tokens.
     State = State->bindLoc(*SearchStrLoc,
-                           SVB.conjureSymbolVal(getTag(), CE, LCtx, CharPtrTy,
-                                                C.blockCount()));
+                           SVB.conjureSymbolVal(getTag(),
+                                                CE,
+                                                LCtx,
+                                                CharPtrTy,
+                                                C.blockCount()),
+                           LCtx);
   } else {
     assert(SearchStrVal.isUnknown());
     // Conjure a symbolic value. It's the best we can do.
@@ -2116,6 +2121,7 @@
                                    const InvalidatedSymbols *,
                                    ArrayRef<const MemRegion *> ExplicitRegions,
                                    ArrayRef<const MemRegion *> Regions,
+                                   const LocationContext *LCtx,
                                    const CallEvent *Call) const {
   CStringLengthTy Entries = state->get<CStringLength>();
   if (Entries.isEmpty())
diff --git a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
index 3db1994..391b843 100644
--- a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
@@ -36,25 +36,24 @@
   AnalysisDeclContext* AC;
 
   /// Check if two expressions refer to the same declaration.
-  inline bool sameDecl(const Expr *A1, const Expr *A2) {
-    if (const DeclRefExpr *D1 = dyn_cast<DeclRefExpr>(A1->IgnoreParenCasts()))
-      if (const DeclRefExpr *D2 = dyn_cast<DeclRefExpr>(A2->IgnoreParenCasts()))
+  bool sameDecl(const Expr *A1, const Expr *A2) {
+    if (const auto *D1 = dyn_cast<DeclRefExpr>(A1->IgnoreParenCasts()))
+      if (const auto *D2 = dyn_cast<DeclRefExpr>(A2->IgnoreParenCasts()))
         return D1->getDecl() == D2->getDecl();
     return false;
   }
 
   /// Check if the expression E is a sizeof(WithArg).
-  inline bool isSizeof(const Expr *E, const Expr *WithArg) {
-    if (const UnaryExprOrTypeTraitExpr *UE =
-    dyn_cast<UnaryExprOrTypeTraitExpr>(E))
-      if (UE->getKind() == UETT_SizeOf)
+  bool isSizeof(const Expr *E, const Expr *WithArg) {
+    if (const auto *UE = dyn_cast<UnaryExprOrTypeTraitExpr>(E))
+      if (UE->getKind() == UETT_SizeOf && !UE->isArgumentType())
         return sameDecl(UE->getArgumentExpr(), WithArg);
     return false;
   }
 
   /// Check if the expression E is a strlen(WithArg).
-  inline bool isStrlen(const Expr *E, const Expr *WithArg) {
-    if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
+  bool isStrlen(const Expr *E, const Expr *WithArg) {
+    if (const auto *CE = dyn_cast<CallExpr>(E)) {
       const FunctionDecl *FD = CE->getDirectCallee();
       if (!FD)
         return false;
@@ -65,14 +64,14 @@
   }
 
   /// Check if the expression is an integer literal with value 1.
-  inline bool isOne(const Expr *E) {
-    if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(E))
+  bool isOne(const Expr *E) {
+    if (const auto *IL = dyn_cast<IntegerLiteral>(E))
       return (IL->getValue().isIntN(1));
     return false;
   }
 
-  inline StringRef getPrintableName(const Expr *E) {
-    if (const DeclRefExpr *D = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
+  StringRef getPrintableName(const Expr *E) {
+    if (const auto *D = dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
       return D->getDecl()->getName();
     return StringRef();
   }
@@ -82,8 +81,8 @@
   bool containsBadStrncatPattern(const CallExpr *CE);
 
 public:
-  WalkAST(const CheckerBase *checker, BugReporter &br, AnalysisDeclContext *ac)
-      : Checker(checker), BR(br), AC(ac) {}
+  WalkAST(const CheckerBase *Checker, BugReporter &BR, AnalysisDeclContext *AC)
+      : Checker(Checker), BR(BR), AC(AC) {}
 
   // Statement visitor methods.
   void VisitChildren(Stmt *S);
@@ -108,8 +107,7 @@
   const Expr *LenArg = CE->getArg(2);
 
   // Identify wrong size expressions, which are commonly used instead.
-  if (const BinaryOperator *BE =
-              dyn_cast<BinaryOperator>(LenArg->IgnoreParenCasts())) {
+  if (const auto *BE = dyn_cast<BinaryOperator>(LenArg->IgnoreParenCasts())) {
     // - sizeof(dst) - strlen(dst)
     if (BE->getOpcode() == BO_Sub) {
       const Expr *L = BE->getLHS();
diff --git a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
index 7631322..668e772 100644
--- a/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp
@@ -51,9 +51,9 @@
       State->getSVal(SVB.getCXXThis(MD, LCtx->getCurrentStackFrame()));
   auto Param = SVB.makeLoc(State->getRegion(MD->getParamDecl(0), LCtx));
   auto ParamVal = State->getSVal(Param);
-  ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal);
+  ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal, LCtx);
   C.addTransition(SelfAssignState);
-  ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal);
+  ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal, LCtx);
   C.addTransition(NonSelfAssignState);
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index f474857..07285d2 100644
--- a/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -21,6 +21,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -71,7 +72,7 @@
 
 private:
   bool PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange ArgRange,
-                          const Expr *ArgEx, bool IsFirstArgument,
+                          const Expr *ArgEx, int ArgumentNumber,
                           bool CheckUninitFields, const CallEvent &Call,
                           std::unique_ptr<BugType> &BT,
                           const ParmVarDecl *ParamDecl) const;
@@ -89,9 +90,10 @@
       BT.reset(new BuiltinBug(this, desc));
   }
   bool uninitRefOrPointer(CheckerContext &C, const SVal &V,
-                          SourceRange ArgRange,
-                          const Expr *ArgEx, std::unique_ptr<BugType> &BT,
-                          const ParmVarDecl *ParamDecl, const char *BD) const;
+                          SourceRange ArgRange, const Expr *ArgEx,
+                          std::unique_ptr<BugType> &BT,
+                          const ParmVarDecl *ParamDecl, const char *BD,
+                          int ArgumentNumber) const;
 };
 } // end anonymous namespace
 
@@ -111,38 +113,45 @@
   C.emitReport(std::move(R));
 }
 
-static StringRef describeUninitializedArgumentInCall(const CallEvent &Call,
-                                                     bool IsFirstArgument) {
+static void describeUninitializedArgumentInCall(const CallEvent &Call,
+                                                int ArgumentNumber,
+                                                llvm::raw_svector_ostream &Os) {
   switch (Call.getKind()) {
   case CE_ObjCMessage: {
     const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
     switch (Msg.getMessageKind()) {
     case OCM_Message:
-      return "Argument in message expression is an uninitialized value";
+      Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+         << " argument in message expression is an uninitialized value";
+      return;
     case OCM_PropertyAccess:
       assert(Msg.isSetter() && "Getters have no args");
-      return "Argument for property setter is an uninitialized value";
+      Os << "Argument for property setter is an uninitialized value";
+      return;
     case OCM_Subscript:
-      if (Msg.isSetter() && IsFirstArgument)
-        return "Argument for subscript setter is an uninitialized value";
-      return "Subscript index is an uninitialized value";
+      if (Msg.isSetter() && (ArgumentNumber == 0))
+        Os << "Argument for subscript setter is an uninitialized value";
+      else
+        Os << "Subscript index is an uninitialized value";
+      return;
     }
     llvm_unreachable("Unknown message kind.");
   }
   case CE_Block:
-    return "Block call argument is an uninitialized value";
+    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+       << " block call argument is an uninitialized value";
+    return;
   default:
-    return "Function call argument is an uninitialized value";
+    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+       << " function call argument is an uninitialized value";
+    return;
   }
 }
 
-bool CallAndMessageChecker::uninitRefOrPointer(CheckerContext &C,
-                                               const SVal &V,
-                                               SourceRange ArgRange,
-                                               const Expr *ArgEx,
-                                               std::unique_ptr<BugType> &BT,
-                                               const ParmVarDecl *ParamDecl,
-                                               const char *BD) const {
+bool CallAndMessageChecker::uninitRefOrPointer(
+    CheckerContext &C, const SVal &V, SourceRange ArgRange, const Expr *ArgEx,
+    std::unique_ptr<BugType> &BT, const ParmVarDecl *ParamDecl, const char *BD,
+    int ArgumentNumber) const {
   if (!Filter.Check_CallAndMessageUnInitRefArg)
     return false;
 
@@ -153,12 +162,15 @@
   // If parameter is declared as pointer to const in function declaration,
   // then check if corresponding argument in function call is
   // pointing to undefined symbol value (uninitialized memory).
-  StringRef Message;
+  SmallString<200> Buf;
+  llvm::raw_svector_ostream Os(Buf);
 
   if (ParamDecl->getType()->isPointerType()) {
-    Message = "Function call argument is a pointer to uninitialized value";
+    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+       << " function call argument is a pointer to uninitialized value";
   } else if (ParamDecl->getType()->isReferenceType()) {
-    Message = "Function call argument is an uninitialized value";
+    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
+       << " function call argument is an uninitialized value";
   } else
     return false;
 
@@ -171,7 +183,7 @@
     if (PSV.isUndef()) {
       if (ExplodedNode *N = C.generateErrorNode()) {
         LazyInit_BT(BD, BT);
-        auto R = llvm::make_unique<BugReport>(*BT, Message, N);
+        auto R = llvm::make_unique<BugReport>(*BT, Os.str(), N);
         R->addRange(ArgRange);
         if (ArgEx) {
           bugreporter::trackNullOrUndefValue(N, ArgEx, *R);
@@ -188,7 +200,7 @@
                                                SVal V,
                                                SourceRange ArgRange,
                                                const Expr *ArgEx,
-                                               bool IsFirstArgument,
+                                               int ArgumentNumber,
                                                bool CheckUninitFields,
                                                const CallEvent &Call,
                                                std::unique_ptr<BugType> &BT,
@@ -196,17 +208,19 @@
                                                ) const {
   const char *BD = "Uninitialized argument value";
 
-  if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD))
+  if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD,
+                         ArgumentNumber))
     return true;
 
   if (V.isUndef()) {
     if (ExplodedNode *N = C.generateErrorNode()) {
       LazyInit_BT(BD, BT);
-
       // Generate a report for this bug.
-      StringRef Desc =
-          describeUninitializedArgumentInCall(Call, IsFirstArgument);
-      auto R = llvm::make_unique<BugReport>(*BT, Desc, N);
+      SmallString<200> Buf;
+      llvm::raw_svector_ostream Os(Buf);
+      describeUninitializedArgumentInCall(Call, ArgumentNumber, Os);
+      auto R = llvm::make_unique<BugReport>(*BT, Os.str(), N);
+
       R->addRange(ArgRange);
       if (ArgEx)
         bugreporter::trackNullOrUndefValue(N, ArgEx, *R);
@@ -435,7 +449,7 @@
     if(FD && i < FD->getNumParams())
       ParamDecl = FD->getParamDecl(i);
     if (PreVisitProcessArg(C, Call.getArgSVal(i), Call.getArgSourceRange(i),
-                           Call.getArgExpr(i), /*IsFirstArgument=*/i == 0,
+                           Call.getArgExpr(i), i,
                            checkUninitFields, Call, *BT, ParamDecl))
       return;
   }
diff --git a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
index 16a475a..65e8131 100644
--- a/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp
@@ -84,6 +84,10 @@
     if (!VD || VD->getType()->isReferenceType())
       return true;
 
+    if (ToPointeeTy->isIncompleteType() ||
+        OrigPointeeTy->isIncompleteType())
+      return true;
+
     // Warn when there is widening cast.
     unsigned ToWidth = Ctx.getTypeInfo(ToPointeeTy).Width;
     unsigned OrigWidth = Ctx.getTypeInfo(OrigPointeeTy).Width;
diff --git a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
index 86764c9..95b6c4d 100644
--- a/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckerDocumentation.cpp
@@ -231,14 +231,6 @@
   /// check::LiveSymbols
   void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SR) const {}
 
-  /// \brief Called to determine if the checker currently needs to know if when
-  /// contents of any regions change.
-  ///
-  /// Since it is not necessarily cheap to compute which regions are being
-  /// changed, this allows the analyzer core to skip the more expensive
-  /// #checkRegionChanges when no checkers are tracking any state.
-  bool wantsRegionChangeUpdate(ProgramStateRef St) const { return true; }
-
   /// \brief Called when the contents of one or more regions change.
   ///
   /// This can occur in many different ways: an explicit bind, a blanket
@@ -255,18 +247,18 @@
   ///        by this change. For a simple bind, this list will be the same as
   ///        \p ExplicitRegions, since a bind does not affect the contents of
   ///        anything accessible through the base region.
+  /// \param LCtx LocationContext that is useful for getting various contextual
+  ///        info, like callstack, CFG etc.
   /// \param Call The opaque call triggering this invalidation. Will be 0 if the
   ///        change was not triggered by a call.
   ///
-  /// Note that this callback will not be invoked unless
-  /// #wantsRegionChangeUpdate returns \c true.
-  ///
   /// check::RegionChanges
   ProgramStateRef
     checkRegionChanges(ProgramStateRef State,
                        const InvalidatedSymbols *Invalidated,
                        ArrayRef<const MemRegion *> ExplicitRegions,
                        ArrayRef<const MemRegion *> Regions,
+                       const LocationContext *LCtx,
                        const CallEvent *Call) const {
     return State;
   }
diff --git a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
index 6fa5732..1885b0e 100644
--- a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
@@ -38,14 +38,15 @@
   void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
                                  AnalysisManager &Mgr, BugReporter &BR) const;
 
-  /// \brief Reports all clones to the user.
+  /// Reports all clones to the user.
   void reportClones(BugReporter &BR, AnalysisManager &Mgr,
-                    int MinComplexity) const;
+                    std::vector<CloneDetector::CloneGroup> &CloneGroups) const;
 
-  /// \brief Reports only suspicious clones to the user along with informaton
-  ///        that explain why they are suspicious.
-  void reportSuspiciousClones(BugReporter &BR, AnalysisManager &Mgr,
-                              int MinComplexity) const;
+  /// Reports only suspicious clones to the user along with informaton
+  /// that explain why they are suspicious.
+  void reportSuspiciousClones(
+      BugReporter &BR, AnalysisManager &Mgr,
+      std::vector<CloneDetector::CloneGroup> &CloneGroups) const;
 };
 } // end anonymous namespace
 
@@ -72,11 +73,30 @@
   bool ReportNormalClones = Mgr.getAnalyzerOptions().getBooleanOption(
       "ReportNormalClones", true, this);
 
-  if (ReportSuspiciousClones)
-    reportSuspiciousClones(BR, Mgr, MinComplexity);
+  // Let the CloneDetector create a list of clones from all the analyzed
+  // statements. We don't filter for matching variable patterns at this point
+  // because reportSuspiciousClones() wants to search them for errors.
+  std::vector<CloneDetector::CloneGroup> AllCloneGroups;
 
-  if (ReportNormalClones)
-    reportClones(BR, Mgr, MinComplexity);
+  Detector.findClones(AllCloneGroups, RecursiveCloneTypeIIConstraint(),
+                      MinComplexityConstraint(MinComplexity),
+                      MinGroupSizeConstraint(2), OnlyLargestCloneConstraint());
+
+  if (ReportSuspiciousClones)
+    reportSuspiciousClones(BR, Mgr, AllCloneGroups);
+
+  // We are done for this translation unit unless we also need to report normal
+  // clones.
+  if (!ReportNormalClones)
+    return;
+
+  // Now that the suspicious clone detector has checked for pattern errors,
+  // we also filter all clones who don't have matching patterns
+  CloneDetector::constrainClones(AllCloneGroups,
+                                 MatchingVariablePatternConstraint(),
+                                 MinGroupSizeConstraint(2));
+
+  reportClones(BR, Mgr, AllCloneGroups);
 }
 
 static PathDiagnosticLocation makeLocation(const StmtSequence &S,
@@ -87,37 +107,55 @@
       Mgr.getAnalysisDeclContext(ACtx.getTranslationUnitDecl()));
 }
 
-void CloneChecker::reportClones(BugReporter &BR, AnalysisManager &Mgr,
-                                int MinComplexity) const {
-
-  std::vector<CloneDetector::CloneGroup> CloneGroups;
-  Detector.findClones(CloneGroups, MinComplexity);
+void CloneChecker::reportClones(
+    BugReporter &BR, AnalysisManager &Mgr,
+    std::vector<CloneDetector::CloneGroup> &CloneGroups) const {
 
   if (!BT_Exact)
     BT_Exact.reset(new BugType(this, "Exact code clone", "Code clone"));
 
-  for (CloneDetector::CloneGroup &Group : CloneGroups) {
+  for (const CloneDetector::CloneGroup &Group : CloneGroups) {
     // We group the clones by printing the first as a warning and all others
     // as a note.
-    auto R = llvm::make_unique<BugReport>(
-        *BT_Exact, "Duplicate code detected",
-        makeLocation(Group.Sequences.front(), Mgr));
-    R->addRange(Group.Sequences.front().getSourceRange());
+    auto R = llvm::make_unique<BugReport>(*BT_Exact, "Duplicate code detected",
+                                          makeLocation(Group.front(), Mgr));
+    R->addRange(Group.front().getSourceRange());
 
-    for (unsigned i = 1; i < Group.Sequences.size(); ++i)
-      R->addNote("Similar code here",
-                      makeLocation(Group.Sequences[i], Mgr),
-                      Group.Sequences[i].getSourceRange());
+    for (unsigned i = 1; i < Group.size(); ++i)
+      R->addNote("Similar code here", makeLocation(Group[i], Mgr),
+                 Group[i].getSourceRange());
     BR.emitReport(std::move(R));
   }
 }
 
-void CloneChecker::reportSuspiciousClones(BugReporter &BR,
-                                          AnalysisManager &Mgr,
-                                          int MinComplexity) const {
+void CloneChecker::reportSuspiciousClones(
+    BugReporter &BR, AnalysisManager &Mgr,
+    std::vector<CloneDetector::CloneGroup> &CloneGroups) const {
+  std::vector<VariablePattern::SuspiciousClonePair> Pairs;
 
-  std::vector<CloneDetector::SuspiciousClonePair> Clones;
-  Detector.findSuspiciousClones(Clones, MinComplexity);
+  for (const CloneDetector::CloneGroup &Group : CloneGroups) {
+    for (unsigned i = 0; i < Group.size(); ++i) {
+      VariablePattern PatternA(Group[i]);
+
+      for (unsigned j = i + 1; j < Group.size(); ++j) {
+        VariablePattern PatternB(Group[j]);
+
+        VariablePattern::SuspiciousClonePair ClonePair;
+        // For now, we only report clones which break the variable pattern just
+        // once because multiple differences in a pattern are an indicator that
+        // those differences are maybe intended (e.g. because it's actually a
+        // different algorithm).
+        // FIXME: In very big clones even multiple variables can be unintended,
+        // so replacing this number with a percentage could better handle such
+        // cases. On the other hand it could increase the false-positive rate
+        // for all clones if the percentage is too high.
+        if (PatternA.countPatternDifferences(PatternB, &ClonePair) == 1) {
+          Pairs.push_back(ClonePair);
+          break;
+        }
+      }
+    }
+  }
 
   if (!BT_Suspicious)
     BT_Suspicious.reset(
@@ -128,7 +166,7 @@
   AnalysisDeclContext *ADC =
       Mgr.getAnalysisDeclContext(ACtx.getTranslationUnitDecl());
 
-  for (CloneDetector::SuspiciousClonePair &Pair : Clones) {
+  for (VariablePattern::SuspiciousClonePair &Pair : Pairs) {
     // FIXME: We are ignoring the suggestions currently, because they are
     // only 50% accurate (even if the second suggestion is unavailable),
     // which may confuse the user.
diff --git a/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp b/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
index 2bb9e85..ea894c8 100644
--- a/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
@@ -41,7 +41,8 @@
   mutable std::unique_ptr<BuiltinBug> BT;
 
   // Is there loss of precision
-  bool isLossOfPrecision(const ImplicitCastExpr *Cast, CheckerContext &C) const;
+  bool isLossOfPrecision(const ImplicitCastExpr *Cast, QualType DestType,
+                         CheckerContext &C) const;
 
   // Is there loss of sign
   bool isLossOfSign(const ImplicitCastExpr *Cast, CheckerContext &C) const;
@@ -73,16 +74,30 @@
   // Loss of sign/precision in binary operation.
   if (const auto *B = dyn_cast<BinaryOperator>(Parent)) {
     BinaryOperator::Opcode Opc = B->getOpcode();
-    if (Opc == BO_Assign || Opc == BO_AddAssign || Opc == BO_SubAssign ||
-        Opc == BO_MulAssign) {
+    if (Opc == BO_Assign) {
       LossOfSign = isLossOfSign(Cast, C);
-      LossOfPrecision = isLossOfPrecision(Cast, C);
+      LossOfPrecision = isLossOfPrecision(Cast, Cast->getType(), C);
+    } else if (Opc == BO_AddAssign || Opc == BO_SubAssign) {
+      // No loss of sign.
+      LossOfPrecision = isLossOfPrecision(Cast, B->getLHS()->getType(), C);
+    } else if (Opc == BO_MulAssign) {
+      LossOfSign = isLossOfSign(Cast, C);
+      LossOfPrecision = isLossOfPrecision(Cast, B->getLHS()->getType(), C);
+    } else if (Opc == BO_DivAssign || Opc == BO_RemAssign) {
+      LossOfSign = isLossOfSign(Cast, C);
+      // No loss of precision.
+    } else if (Opc == BO_AndAssign) {
+      LossOfSign = isLossOfSign(Cast, C);
+      // No loss of precision.
+    } else if (Opc == BO_OrAssign || Opc == BO_XorAssign) {
+      LossOfSign = isLossOfSign(Cast, C);
+      LossOfPrecision = isLossOfPrecision(Cast, B->getLHS()->getType(), C);
     } else if (B->isRelationalOp() || B->isMultiplicativeOp()) {
       LossOfSign = isLossOfSign(Cast, C);
     }
   } else if (isa<DeclStmt>(Parent)) {
     LossOfSign = isLossOfSign(Cast, C);
-    LossOfPrecision = isLossOfPrecision(Cast, C);
+    LossOfPrecision = isLossOfPrecision(Cast, Cast->getType(), C);
   }
 
   if (LossOfSign || LossOfPrecision) {
@@ -113,6 +128,13 @@
                            unsigned long long Val) {
   ProgramStateRef State = C.getState();
   SVal EVal = C.getSVal(E);
+  if (EVal.isUnknownOrUndef())
+    return false;
+  if (!EVal.getAs<NonLoc>() && EVal.getAs<Loc>()) {
+    ProgramStateManager &Mgr = C.getStateManager();
+    EVal =
+        Mgr.getStoreManager().getBinding(State->getStore(), EVal.castAs<Loc>());
+  }
   if (EVal.isUnknownOrUndef() || !EVal.getAs<NonLoc>())
     return false;
 
@@ -153,22 +175,22 @@
 }
 
 bool ConversionChecker::isLossOfPrecision(const ImplicitCastExpr *Cast,
-                                        CheckerContext &C) const {
+                                          QualType DestType,
+                                          CheckerContext &C) const {
   // Don't warn about explicit loss of precision.
   if (Cast->isEvaluatable(C.getASTContext()))
     return false;
 
-  QualType CastType = Cast->getType();
   QualType SubType = Cast->IgnoreParenImpCasts()->getType();
 
-  if (!CastType->isIntegerType() || !SubType->isIntegerType())
+  if (!DestType->isIntegerType() || !SubType->isIntegerType())
     return false;
 
-  if (C.getASTContext().getIntWidth(CastType) >=
+  if (C.getASTContext().getIntWidth(DestType) >=
       C.getASTContext().getIntWidth(SubType))
     return false;
 
-  unsigned W = C.getASTContext().getIntWidth(CastType);
+  unsigned W = C.getASTContext().getIntWidth(DestType);
   if (W == 1 || W >= 64U)
     return false;
 
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 0891ea8..26fd83f 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -626,7 +626,7 @@
       : public RecursiveASTVisitor<IsObjCTypeParamDependentTypeVisitor> {
   public:
     IsObjCTypeParamDependentTypeVisitor() : Result(false) {}
-    bool VisitObjCTypeParamType(const ObjCTypeParamType *Type) {
+    bool VisitTypedefType(const TypedefType *Type) {
       if (isa<ObjCTypeParamDecl>(Type->getDecl())) {
         Result = true;
         return false;
diff --git a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
index 2d5cb60..32040e7 100644
--- a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -13,6 +13,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Checkers/SValExplainer.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/ScopedPrinter.h"
 
 using namespace clang;
 using namespace ento;
@@ -71,8 +72,8 @@
           &ExprInspectionChecker::analyzerWarnIfReached)
     .Case("clang_analyzer_warnOnDeadSymbol",
           &ExprInspectionChecker::analyzerWarnOnDeadSymbol)
-    .Case("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain)
-    .Case("clang_analyzer_dump", &ExprInspectionChecker::analyzerDump)
+    .StartsWith("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain)
+    .StartsWith("clang_analyzer_dump", &ExprInspectionChecker::analyzerDump)
     .Case("clang_analyzer_getExtent", &ExprInspectionChecker::analyzerGetExtent)
     .Case("clang_analyzer_printState",
           &ExprInspectionChecker::analyzerPrintState)
@@ -269,7 +270,7 @@
     unsigned NumTimesReached = Item.second.NumTimesReached;
     ExplodedNode *N = Item.second.ExampleNode;
 
-    reportBug(std::to_string(NumTimesReached), BR, N);
+    reportBug(llvm::to_string(NumTimesReached), BR, N);
   }
 }
 
diff --git a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index 8c8acc6..b1a54e7 100644
--- a/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -65,6 +65,18 @@
   /// and thus, is tainted.
   static bool isStdin(const Expr *E, CheckerContext &C);
 
+  /// This is called from getPointedToSymbol() to resolve symbol references for
+  /// the region underlying a LazyCompoundVal. This is the default binding
+  /// for the LCV, which could be a conjured symbol from a function call that
+  /// initialized the region. It only returns the conjured symbol if the LCV
+  /// covers the entire region, e.g. we avoid false positives by not returning
+  /// a default bindingc for an entire struct if the symbol for only a single
+  /// field or element within it is requested.
+  // TODO: Return an appropriate symbol for sub-fields/elements of an LCV so
+  // that they are also appropriately tainted.
+  static SymbolRef getLCVSymbol(CheckerContext &C,
+                                nonloc::LazyCompoundVal &LCV);
+
   /// \brief Given a pointer argument, get the symbol of the value it contains
   /// (points to).
   static SymbolRef getPointedToSymbol(CheckerContext &C, const Expr *Arg);
@@ -101,6 +113,22 @@
   bool generateReportIfTainted(const Expr *E, const char Msg[],
                                CheckerContext &C) const;
 
+  /// The bug visitor prints a diagnostic message at the location where a given
+  /// variable was tainted.
+  class TaintBugVisitor
+      : public BugReporterVisitorImpl<TaintBugVisitor> {
+  private:
+    const SVal V;
+
+  public:
+    TaintBugVisitor(const SVal V) : V(V) {}
+    void Profile(llvm::FoldingSetNodeID &ID) const override { ID.Add(V); }
+
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
+  };
 
   typedef SmallVector<unsigned, 2> ArgVector;
 
@@ -194,6 +222,28 @@
 /// points to data, which should be tainted on return.
 REGISTER_SET_WITH_PROGRAMSTATE(TaintArgsOnPostVisit, unsigned)
 
+std::shared_ptr<PathDiagnosticPiece>
+GenericTaintChecker::TaintBugVisitor::VisitNode(const ExplodedNode *N,
+    const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) {
+
+  // Find the ExplodedNode where the taint was first introduced
+  if (!N->getState()->isTainted(V) || PrevN->getState()->isTainted(V))
+    return nullptr;
+
+  const Stmt *S = PathDiagnosticLocation::getStmt(N);
+  if (!S)
+    return nullptr;
+
+  const LocationContext *NCtx = N->getLocationContext();
+  PathDiagnosticLocation L =
+      PathDiagnosticLocation::createBegin(S, BRC.getSourceManager(), NCtx);
+  if (!L.isValid() || !L.asLocation().isValid())
+    return nullptr;
+
+  return std::make_shared<PathDiagnosticEventPiece>(
+      L, "Taint originated here");
+}
+
 GenericTaintChecker::TaintPropagationRule
 GenericTaintChecker::TaintPropagationRule::getTaintPropagationRule(
                                                      const FunctionDecl *FDecl,
@@ -423,6 +473,27 @@
   return false;
 }
 
+SymbolRef GenericTaintChecker::getLCVSymbol(CheckerContext &C,
+                                            nonloc::LazyCompoundVal &LCV) {
+  StoreManager &StoreMgr = C.getStoreManager();
+
+  // getLCVSymbol() is reached in a PostStmt so we can always expect a default
+  // binding to exist if one is present.
+  if (Optional<SVal> binding = StoreMgr.getDefaultBinding(LCV)) {
+    SymbolRef Sym = binding->getAsSymbol();
+    if (!Sym)
+      return nullptr;
+
+    // If the LCV covers an entire base region return the default conjured symbol.
+    if (LCV.getRegion() == LCV.getRegion()->getBaseRegion())
+      return Sym;
+  }
+
+  // Otherwise, return a nullptr as there's not yet a functional way to taint
+  // sub-regions of LCVs.
+  return nullptr;
+}
+
 SymbolRef GenericTaintChecker::getPointedToSymbol(CheckerContext &C,
                                                   const Expr* Arg) {
   ProgramStateRef State = C.getState();
@@ -438,6 +509,10 @@
     dyn_cast<PointerType>(Arg->getType().getCanonicalType().getTypePtr());
   SVal Val = State->getSVal(*AddrLoc,
                             ArgTy ? ArgTy->getPointeeType(): QualType());
+
+  if (auto LCV = Val.getAs<nonloc::LazyCompoundVal>())
+    return getLCVSymbol(C, *LCV);
+
   return Val.getAsSymbol();
 }
 
@@ -635,8 +710,13 @@
 
   // Check for taint.
   ProgramStateRef State = C.getState();
-  if (!State->isTainted(getPointedToSymbol(C, E)) &&
-      !State->isTainted(E, C.getLocationContext()))
+  const SymbolRef PointedToSym = getPointedToSymbol(C, E);
+  SVal TaintedSVal;
+  if (State->isTainted(PointedToSym))
+    TaintedSVal = nonloc::SymbolVal(PointedToSym);
+  else if (State->isTainted(E, C.getLocationContext()))
+    TaintedSVal = C.getSVal(E);
+  else
     return false;
 
   // Generate diagnostic.
@@ -644,6 +724,7 @@
     initBugType();
     auto report = llvm::make_unique<BugReport>(*BT, Msg, N);
     report->addRange(E->getSourceRange());
+    report->addVisitor(llvm::make_unique<TaintBugVisitor>(TaintedSVal));
     C.emitReport(std::move(report));
     return true;
   }
diff --git a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
index c667b9e..696cf39 100644
--- a/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
@@ -153,9 +153,9 @@
   MemRegionManager *const RegionManager = MR->getMemRegionManager();
 
   if (FuncClassifier->isMPI_Waitall(CE.getCalleeIdentifier())) {
-    const MemRegion *SuperRegion{nullptr};
+    const SubRegion *SuperRegion{nullptr};
     if (const ElementRegion *const ER = MR->getAs<ElementRegion>()) {
-      SuperRegion = ER->getSuperRegion();
+      SuperRegion = cast<SubRegion>(ER->getSuperRegion());
     }
 
     // A single request is passed to MPI_Waitall.
diff --git a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
index f1aa163..f8473db 100644
--- a/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MacOSKeychainAPIChecker.cpp
@@ -28,7 +28,8 @@
 namespace {
 class MacOSKeychainAPIChecker : public Checker<check::PreStmt<CallExpr>,
                                                check::PostStmt<CallExpr>,
-                                               check::DeadSymbols> {
+                                               check::DeadSymbols,
+                                               eval::Assume> {
   mutable std::unique_ptr<BugType> BT;
 
 public:
@@ -57,6 +58,10 @@
   void checkPreStmt(const CallExpr *S, CheckerContext &C) const;
   void checkPostStmt(const CallExpr *S, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
+  ProgramStateRef evalAssume(ProgramStateRef state, SVal Cond,
+                             bool Assumption) const;
+  void printState(raw_ostream &Out, ProgramStateRef State,
+                  const char *NL, const char *Sep) const;
 
 private:
   typedef std::pair<SymbolRef, const AllocationState*> AllocationPair;
@@ -106,19 +111,6 @@
   std::unique_ptr<BugReport> generateAllocatedDataNotReleasedReport(
       const AllocationPair &AP, ExplodedNode *N, CheckerContext &C) const;
 
-  /// Check if RetSym evaluates to an error value in the current state.
-  bool definitelyReturnedError(SymbolRef RetSym,
-                               ProgramStateRef State,
-                               SValBuilder &Builder,
-                               bool noError = false) const;
-
-  /// Check if RetSym evaluates to a NoErr value in the current state.
-  bool definitelyDidnotReturnError(SymbolRef RetSym,
-                                   ProgramStateRef State,
-                                   SValBuilder &Builder) const {
-    return definitelyReturnedError(RetSym, State, Builder, true);
-  }
-
   /// Mark an AllocationPair interesting for diagnostic reporting.
   void markInteresting(BugReport *R, const AllocationPair &AP) const {
     R->markInteresting(AP.first);
@@ -221,24 +213,6 @@
   return nullptr;
 }
 
-// When checking for error code, we need to consider the following cases:
-// 1) noErr / [0]
-// 2) someErr / [1, inf]
-// 3) unknown
-// If noError, returns true iff (1).
-// If !noError, returns true iff (2).
-bool MacOSKeychainAPIChecker::definitelyReturnedError(SymbolRef RetSym,
-                                                      ProgramStateRef State,
-                                                      SValBuilder &Builder,
-                                                      bool noError) const {
-  DefinedOrUnknownSVal NoErrVal = Builder.makeIntVal(NoErr,
-    Builder.getSymbolManager().getType(RetSym));
-  DefinedOrUnknownSVal NoErr = Builder.evalEQ(State, NoErrVal,
-                                                     nonloc::SymbolVal(RetSym));
-  ProgramStateRef ErrState = State->assume(NoErr, noError);
-  return ErrState == State;
-}
-
 // Report deallocator mismatch. Remove the region from tracking - reporting a
 // missing free error after this one is redundant.
 void MacOSKeychainAPIChecker::
@@ -289,27 +263,25 @@
     const Expr *ArgExpr = CE->getArg(paramIdx);
     if (SymbolRef V = getAsPointeeSymbol(ArgExpr, C))
       if (const AllocationState *AS = State->get<AllocatedData>(V)) {
-        if (!definitelyReturnedError(AS->Region, State, C.getSValBuilder())) {
-          // Remove the value from the state. The new symbol will be added for
-          // tracking when the second allocator is processed in checkPostStmt().
-          State = State->remove<AllocatedData>(V);
-          ExplodedNode *N = C.generateNonFatalErrorNode(State);
-          if (!N)
-            return;
-          initBugType();
-          SmallString<128> sbuf;
-          llvm::raw_svector_ostream os(sbuf);
-          unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx;
-          os << "Allocated data should be released before another call to "
-              << "the allocator: missing a call to '"
-              << FunctionsToTrack[DIdx].Name
-              << "'.";
-          auto Report = llvm::make_unique<BugReport>(*BT, os.str(), N);
-          Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(V));
-          Report->addRange(ArgExpr->getSourceRange());
-          Report->markInteresting(AS->Region);
-          C.emitReport(std::move(Report));
-        }
+        // Remove the value from the state. The new symbol will be added for
+        // tracking when the second allocator is processed in checkPostStmt().
+        State = State->remove<AllocatedData>(V);
+        ExplodedNode *N = C.generateNonFatalErrorNode(State);
+        if (!N)
+          return;
+        initBugType();
+        SmallString<128> sbuf;
+        llvm::raw_svector_ostream os(sbuf);
+        unsigned int DIdx = FunctionsToTrack[AS->AllocatorIdx].DeallocatorIdx;
+        os << "Allocated data should be released before another call to "
+            << "the allocator: missing a call to '"
+            << FunctionsToTrack[DIdx].Name
+            << "'.";
+        auto Report = llvm::make_unique<BugReport>(*BT, os.str(), N);
+        Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(V));
+        Report->addRange(ArgExpr->getSourceRange());
+        Report->markInteresting(AS->Region);
+        C.emitReport(std::move(Report));
       }
     return;
   }
@@ -344,13 +316,12 @@
 
   // Is the argument to the call being tracked?
   const AllocationState *AS = State->get<AllocatedData>(ArgSM);
-  if (!AS && FunctionsToTrack[idx].Kind != ValidAPI) {
+  if (!AS)
     return;
-  }
-  // If trying to free data which has not been allocated yet, report as a bug.
-  // TODO: We might want a more precise diagnostic for double free
+
+  // TODO: We might want to report double free here.
   // (that would involve tracking all the freed symbols in the checker state).
-  if (!AS || RegionArgIsBad) {
+  if (RegionArgIsBad) {
     // It is possible that this is a false positive - the argument might
     // have entered as an enclosing function parameter.
     if (isEnclosingFunctionParam(ArgExpr))
@@ -418,23 +389,6 @@
     return;
   }
 
-  // If the buffer can be null and the return status can be an error,
-  // report a bad call to free.
-  if (State->assume(ArgSVal.castAs<DefinedSVal>(), false) &&
-      !definitelyDidnotReturnError(AS->Region, State, C.getSValBuilder())) {
-    ExplodedNode *N = C.generateNonFatalErrorNode(State);
-    if (!N)
-      return;
-    initBugType();
-    auto Report = llvm::make_unique<BugReport>(
-        *BT, "Only call free if a valid (non-NULL) buffer was returned.", N);
-    Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(ArgSM));
-    Report->addRange(ArgExpr->getSourceRange());
-    Report->markInteresting(AS->Region);
-    C.emitReport(std::move(Report));
-    return;
-  }
-
   C.addTransition(State);
 }
 
@@ -540,27 +494,63 @@
   return Report;
 }
 
+/// If the return symbol is assumed to be error, remove the allocated info
+/// from consideration.
+ProgramStateRef MacOSKeychainAPIChecker::evalAssume(ProgramStateRef State,
+                                                    SVal Cond,
+                                                    bool Assumption) const {
+  AllocatedDataTy AMap = State->get<AllocatedData>();
+  if (AMap.isEmpty())
+    return State;
+
+  auto *CondBSE = dyn_cast_or_null<BinarySymExpr>(Cond.getAsSymExpr());
+  if (!CondBSE)
+    return State;
+  BinaryOperator::Opcode OpCode = CondBSE->getOpcode();
+  if (OpCode != BO_EQ && OpCode != BO_NE)
+    return State;
+
+  // Match for a restricted set of patterns for cmparison of error codes.
+  // Note, the comparisons of type '0 == st' are transformed into SymIntExpr.
+  SymbolRef ReturnSymbol = nullptr;
+  if (auto *SIE = dyn_cast<SymIntExpr>(CondBSE)) {
+    const llvm::APInt &RHS = SIE->getRHS();
+    bool ErrorIsReturned = (OpCode == BO_EQ && RHS != NoErr) ||
+                           (OpCode == BO_NE && RHS == NoErr);
+    if (!Assumption)
+      ErrorIsReturned = !ErrorIsReturned;
+    if (ErrorIsReturned)
+      ReturnSymbol = SIE->getLHS();
+  }
+
+  if (ReturnSymbol)
+    for (auto I = AMap.begin(), E = AMap.end(); I != E; ++I) {
+      if (ReturnSymbol == I->second.Region)
+        State = State->remove<AllocatedData>(I->first);
+    }
+
+  return State;
+}
+
 void MacOSKeychainAPIChecker::checkDeadSymbols(SymbolReaper &SR,
                                                CheckerContext &C) const {
   ProgramStateRef State = C.getState();
-  AllocatedDataTy ASet = State->get<AllocatedData>();
-  if (ASet.isEmpty())
+  AllocatedDataTy AMap = State->get<AllocatedData>();
+  if (AMap.isEmpty())
     return;
 
   bool Changed = false;
   AllocationPairVec Errors;
-  for (AllocatedDataTy::iterator I = ASet.begin(), E = ASet.end(); I != E; ++I) {
-    if (SR.isLive(I->first))
+  for (auto I = AMap.begin(), E = AMap.end(); I != E; ++I) {
+    if (!SR.isDead(I->first))
       continue;
 
     Changed = true;
     State = State->remove<AllocatedData>(I->first);
-    // If the allocated symbol is null or if the allocation call might have
-    // returned an error, do not report.
+    // If the allocated symbol is null do not report.
     ConstraintManager &CMgr = State->getConstraintManager();
     ConditionTruthVal AllocFailed = CMgr.isNull(State, I.getKey());
-    if (AllocFailed.isConstrainedTrue() ||
-        definitelyReturnedError(I->second.Region, State, C.getSValBuilder()))
+    if (AllocFailed.isConstrainedTrue())
       continue;
     Errors.push_back(std::make_pair(I->first, &I->second));
   }
@@ -612,6 +602,22 @@
                                                     "Data is allocated here.");
 }
 
+void MacOSKeychainAPIChecker::printState(raw_ostream &Out,
+                                         ProgramStateRef State,
+                                         const char *NL,
+                                         const char *Sep) const {
+
+  AllocatedDataTy AMap = State->get<AllocatedData>();
+
+  if (!AMap.isEmpty()) {
+    Out << Sep << "KeychainAPIChecker :" << NL;
+    for (auto I = AMap.begin(), E = AMap.end(); I != E; ++I) {
+      I.getKey()->dumpToStream(Out);
+    }
+  }
+}
+
+
 void ento::registerMacOSKeychainAPIChecker(CheckerManager &mgr) {
   mgr.registerChecker<MacOSKeychainAPIChecker>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 8e839a1..d1a2837 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -19,6 +19,7 @@
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
@@ -174,7 +175,10 @@
         II_valloc(nullptr), II_reallocf(nullptr), II_strndup(nullptr),
         II_strdup(nullptr), II_win_strdup(nullptr), II_kmalloc(nullptr),
         II_if_nameindex(nullptr), II_if_freenameindex(nullptr),
-        II_wcsdup(nullptr), II_win_wcsdup(nullptr) {}
+        II_wcsdup(nullptr), II_win_wcsdup(nullptr), II_g_malloc(nullptr),
+        II_g_malloc0(nullptr), II_g_realloc(nullptr), II_g_try_malloc(nullptr), 
+        II_g_try_malloc0(nullptr), II_g_try_realloc(nullptr), 
+        II_g_free(nullptr), II_g_memdup(nullptr) {}
 
   /// In pessimistic mode, the checker assumes that it does not know which
   /// functions might free the memory.
@@ -236,7 +240,9 @@
                          *II_realloc, *II_calloc, *II_valloc, *II_reallocf,
                          *II_strndup, *II_strdup, *II_win_strdup, *II_kmalloc,
                          *II_if_nameindex, *II_if_freenameindex, *II_wcsdup,
-                         *II_win_wcsdup;
+                         *II_win_wcsdup, *II_g_malloc, *II_g_malloc0, 
+                         *II_g_realloc, *II_g_try_malloc, *II_g_try_malloc0, 
+                         *II_g_try_realloc, *II_g_free, *II_g_memdup;
   mutable Optional<uint64_t> KernelZeroFlagVal;
 
   void initIdentifierInfo(ASTContext &C) const;
@@ -554,6 +560,16 @@
   II_win_strdup = &Ctx.Idents.get("_strdup");
   II_win_wcsdup = &Ctx.Idents.get("_wcsdup");
   II_win_alloca = &Ctx.Idents.get("_alloca");
+
+  // Glib
+  II_g_malloc = &Ctx.Idents.get("g_malloc");
+  II_g_malloc0 = &Ctx.Idents.get("g_malloc0");
+  II_g_realloc = &Ctx.Idents.get("g_realloc");
+  II_g_try_malloc = &Ctx.Idents.get("g_try_malloc");
+  II_g_try_malloc0 = &Ctx.Idents.get("g_try_malloc0");
+  II_g_try_realloc = &Ctx.Idents.get("g_try_realloc");
+  II_g_free = &Ctx.Idents.get("g_free");
+  II_g_memdup = &Ctx.Idents.get("g_memdup");
 }
 
 bool MallocChecker::isMemFunction(const FunctionDecl *FD, ASTContext &C) const {
@@ -589,7 +605,8 @@
     initIdentifierInfo(C);
 
     if (Family == AF_Malloc && CheckFree) {
-      if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf)
+      if (FunI == II_free || FunI == II_realloc || FunI == II_reallocf || 
+          FunI == II_g_free)
         return true;
     }
 
@@ -597,7 +614,11 @@
       if (FunI == II_malloc || FunI == II_realloc || FunI == II_reallocf ||
           FunI == II_calloc || FunI == II_valloc || FunI == II_strdup ||
           FunI == II_win_strdup || FunI == II_strndup || FunI == II_wcsdup ||
-          FunI == II_win_wcsdup || FunI == II_kmalloc)
+          FunI == II_win_wcsdup || FunI == II_kmalloc ||
+          FunI == II_g_malloc || FunI == II_g_malloc0 || 
+          FunI == II_g_realloc || FunI == II_g_try_malloc || 
+          FunI == II_g_try_malloc0 || FunI == II_g_try_realloc ||
+          FunI == II_g_memdup)
         return true;
     }
 
@@ -762,7 +783,7 @@
     initIdentifierInfo(C.getASTContext());
     IdentifierInfo *FunI = FD->getIdentifier();
 
-    if (FunI == II_malloc) {
+    if (FunI == II_malloc || FunI == II_g_malloc || FunI == II_g_try_malloc) {
       if (CE->getNumArgs() < 1)
         return;
       if (CE->getNumArgs() < 3) {
@@ -791,7 +812,8 @@
         return;
       State = MallocMemAux(C, CE, CE->getArg(0), UndefinedVal(), State);
       State = ProcessZeroAllocation(C, CE, 0, State);
-    } else if (FunI == II_realloc) {
+    } else if (FunI == II_realloc || FunI == II_g_realloc || 
+               FunI == II_g_try_realloc) {
       State = ReallocMem(C, CE, false, State);
       State = ProcessZeroAllocation(C, CE, 1, State);
     } else if (FunI == II_reallocf) {
@@ -801,7 +823,7 @@
       State = CallocMem(C, CE, State);
       State = ProcessZeroAllocation(C, CE, 0, State);
       State = ProcessZeroAllocation(C, CE, 1, State);
-    } else if (FunI == II_free) {
+    } else if (FunI == II_free || FunI == II_g_free) {
       State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
     } else if (FunI == II_strdup || FunI == II_win_strdup ||
                FunI == II_wcsdup || FunI == II_win_wcsdup) {
@@ -841,6 +863,18 @@
                            AF_IfNameIndex);
     } else if (FunI == II_if_freenameindex) {
       State = FreeMemAux(C, CE, State, 0, false, ReleasedAllocatedMemory);
+    } else if (FunI == II_g_malloc0 || FunI == II_g_try_malloc0) {
+      if (CE->getNumArgs() < 1)
+        return;
+      SValBuilder &svalBuilder = C.getSValBuilder();
+      SVal zeroVal = svalBuilder.makeZeroVal(svalBuilder.getContext().CharTy);
+      State = MallocMemAux(C, CE, CE->getArg(0), zeroVal, State);
+      State = ProcessZeroAllocation(C, CE, 0, State);
+    } else if (FunI == II_g_memdup) {
+      if (CE->getNumArgs() < 2)
+        return;
+      State = MallocMemAux(C, CE, CE->getArg(1), UndefinedVal(), State);
+      State = ProcessZeroAllocation(C, CE, 1, State);
     }
   }
 
@@ -1154,7 +1188,7 @@
   State = State->BindExpr(CE, C.getLocationContext(), RetVal);
 
   // Fill the region with the initialization value.
-  State = State->bindDefault(RetVal, Init);
+  State = State->bindDefault(RetVal, Init, LCtx);
 
   // Set the region's extent equal to the Size parameter.
   const SymbolicRegion *R =
@@ -1664,8 +1698,8 @@
 
   if (ExplodedNode *N = C.generateErrorNode()) {
     if (!BT_BadFree[*CheckKind])
-      BT_BadFree[*CheckKind].reset(
-          new BugType(CheckNames[*CheckKind], "Bad free", "Memory Error"));
+      BT_BadFree[*CheckKind].reset(new BugType(
+          CheckNames[*CheckKind], "Bad free", categories::MemoryError));
 
     SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
@@ -1709,8 +1743,8 @@
 
   if (ExplodedNode *N = C.generateErrorNode()) {
     if (!BT_FreeAlloca[*CheckKind])
-      BT_FreeAlloca[*CheckKind].reset(
-          new BugType(CheckNames[*CheckKind], "Free alloca()", "Memory Error"));
+      BT_FreeAlloca[*CheckKind].reset(new BugType(
+          CheckNames[*CheckKind], "Free alloca()", categories::MemoryError));
 
     auto R = llvm::make_unique<BugReport>(
         *BT_FreeAlloca[*CheckKind],
@@ -1735,7 +1769,7 @@
     if (!BT_MismatchedDealloc)
       BT_MismatchedDealloc.reset(
           new BugType(CheckNames[CK_MismatchedDeallocatorChecker],
-                      "Bad deallocator", "Memory Error"));
+                      "Bad deallocator", categories::MemoryError));
 
     SmallString<100> buf;
     llvm::raw_svector_ostream os(buf);
@@ -1795,8 +1829,8 @@
     return;
 
   if (!BT_OffsetFree[*CheckKind])
-    BT_OffsetFree[*CheckKind].reset(
-        new BugType(CheckNames[*CheckKind], "Offset free", "Memory Error"));
+    BT_OffsetFree[*CheckKind].reset(new BugType(
+        CheckNames[*CheckKind], "Offset free", categories::MemoryError));
 
   SmallString<100> buf;
   llvm::raw_svector_ostream os(buf);
@@ -1847,7 +1881,7 @@
   if (ExplodedNode *N = C.generateErrorNode()) {
     if (!BT_UseFree[*CheckKind])
       BT_UseFree[*CheckKind].reset(new BugType(
-          CheckNames[*CheckKind], "Use-after-free", "Memory Error"));
+          CheckNames[*CheckKind], "Use-after-free", categories::MemoryError));
 
     auto R = llvm::make_unique<BugReport>(*BT_UseFree[*CheckKind],
                                          "Use of memory after it is freed", N);
@@ -1873,8 +1907,8 @@
 
   if (ExplodedNode *N = C.generateErrorNode()) {
     if (!BT_DoubleFree[*CheckKind])
-      BT_DoubleFree[*CheckKind].reset(
-          new BugType(CheckNames[*CheckKind], "Double free", "Memory Error"));
+      BT_DoubleFree[*CheckKind].reset(new BugType(
+          CheckNames[*CheckKind], "Double free", categories::MemoryError));
 
     auto R = llvm::make_unique<BugReport>(
         *BT_DoubleFree[*CheckKind],
@@ -1902,7 +1936,8 @@
   if (ExplodedNode *N = C.generateErrorNode()) {
     if (!BT_DoubleDelete)
       BT_DoubleDelete.reset(new BugType(CheckNames[CK_NewDeleteChecker],
-                                        "Double delete", "Memory Error"));
+                                        "Double delete",
+                                        categories::MemoryError));
 
     auto R = llvm::make_unique<BugReport>(
         *BT_DoubleDelete, "Attempt to delete released memory", N);
@@ -1928,8 +1963,9 @@
 
   if (ExplodedNode *N = C.generateErrorNode()) {
     if (!BT_UseZerroAllocated[*CheckKind])
-      BT_UseZerroAllocated[*CheckKind].reset(new BugType(
-          CheckNames[*CheckKind], "Use of zero allocated", "Memory Error"));
+      BT_UseZerroAllocated[*CheckKind].reset(
+          new BugType(CheckNames[*CheckKind], "Use of zero allocated",
+                      categories::MemoryError));
 
     auto R = llvm::make_unique<BugReport>(*BT_UseZerroAllocated[*CheckKind],
                                          "Use of zero-allocated memory", N);
@@ -2131,8 +2167,8 @@
 
   assert(N);
   if (!BT_Leak[*CheckKind]) {
-    BT_Leak[*CheckKind].reset(
-        new BugType(CheckNames[*CheckKind], "Memory leak", "Memory Error"));
+    BT_Leak[*CheckKind].reset(new BugType(CheckNames[*CheckKind], "Memory leak",
+                                          categories::MemoryError));
     // Leaks should not be reported if they are post-dominated by a sink:
     // (1) Sinks are higher importance bugs.
     // (2) NoReturnFunctionChecker uses sink nodes to represent paths ending
diff --git a/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp b/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp
new file mode 100644
index 0000000..decc552
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp
@@ -0,0 +1,481 @@
+// MisusedMovedObjectChecker.cpp - Check use of moved-from objects. - C++ -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This defines checker which checks for potential misuses of a moved-from
+// object. That means method calls on the object or copying it in moved-from
+// state.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/AST/ExprCXX.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+struct RegionState {
+private:
+  enum Kind { Moved, Reported } K;
+  RegionState(Kind InK) : K(InK) {}
+
+public:
+  bool isReported() const { return K == Reported; }
+  bool isMoved() const { return K == Moved; }
+
+  static RegionState getReported() { return RegionState(Reported); }
+  static RegionState getMoved() { return RegionState(Moved); }
+
+  bool operator==(const RegionState &X) const { return K == X.K; }
+  void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(K); }
+};
+
+class MisusedMovedObjectChecker
+    : public Checker<check::PreCall, check::PostCall, check::EndFunction,
+                     check::DeadSymbols, check::RegionChanges> {
+public:
+  void checkEndFunction(CheckerContext &C) const;
+  void checkPreCall(const CallEvent &MC, CheckerContext &C) const;
+  void checkPostCall(const CallEvent &MC, CheckerContext &C) const;
+  void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
+  ProgramStateRef
+  checkRegionChanges(ProgramStateRef State,
+                     const InvalidatedSymbols *Invalidated,
+                     ArrayRef<const MemRegion *> ExplicitRegions,
+                     ArrayRef<const MemRegion *> Regions,
+                     const LocationContext *LCtx, const CallEvent *Call) const;
+
+private:
+  class MovedBugVisitor : public BugReporterVisitorImpl<MovedBugVisitor> {
+  public:
+    MovedBugVisitor(const MemRegion *R) : Region(R), Found(false) {}
+
+    void Profile(llvm::FoldingSetNodeID &ID) const override {
+      static int X = 0;
+      ID.AddPointer(&X);
+      ID.AddPointer(Region);
+    }
+
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
+
+  private:
+    // The tracked region.
+    const MemRegion *Region;
+    bool Found;
+  };
+
+  mutable std::unique_ptr<BugType> BT;
+  ExplodedNode *reportBug(const MemRegion *Region, const CallEvent &Call,
+                          CheckerContext &C, bool isCopy) const;
+  bool isInMoveSafeContext(const LocationContext *LC) const;
+  bool isStateResetMethod(const CXXMethodDecl *MethodDec) const;
+  bool isMoveSafeMethod(const CXXMethodDecl *MethodDec) const;
+  const ExplodedNode *getMoveLocation(const ExplodedNode *N,
+                                      const MemRegion *Region,
+                                      CheckerContext &C) const;
+};
+} // end anonymous namespace
+
+REGISTER_MAP_WITH_PROGRAMSTATE(TrackedRegionMap, const MemRegion *, RegionState)
+
+// If a region is removed all of the subregions needs to be removed too.
+static ProgramStateRef removeFromState(ProgramStateRef State,
+                                       const MemRegion *Region) {
+  if (!Region)
+    return State;
+  // Note: The isSubRegionOf function is not reflexive.
+  State = State->remove<TrackedRegionMap>(Region);
+  for (auto &E : State->get<TrackedRegionMap>()) {
+    if (E.first->isSubRegionOf(Region))
+      State = State->remove<TrackedRegionMap>(E.first);
+  }
+  return State;
+}
+
+static bool isAnyBaseRegionReported(ProgramStateRef State,
+                                    const MemRegion *Region) {
+  for (auto &E : State->get<TrackedRegionMap>()) {
+    if (Region->isSubRegionOf(E.first) && E.second.isReported())
+      return true;
+  }
+  return false;
+}
+
+std::shared_ptr<PathDiagnosticPiece>
+MisusedMovedObjectChecker::MovedBugVisitor::VisitNode(const ExplodedNode *N,
+                                                      const ExplodedNode *PrevN,
+                                                      BugReporterContext &BRC,
+                                                      BugReport &BR) {
+  // We need only the last move of the reported object's region.
+  // The visitor walks the ExplodedGraph backwards.
+  if (Found)
+    return nullptr;
+  ProgramStateRef State = N->getState();
+  ProgramStateRef StatePrev = PrevN->getState();
+  const RegionState *TrackedObject = State->get<TrackedRegionMap>(Region);
+  const RegionState *TrackedObjectPrev =
+      StatePrev->get<TrackedRegionMap>(Region);
+  if (!TrackedObject)
+    return nullptr;
+  if (TrackedObjectPrev && TrackedObject)
+    return nullptr;
+
+  // Retrieve the associated statement.
+  const Stmt *S = PathDiagnosticLocation::getStmt(N);
+  if (!S)
+    return nullptr;
+  Found = true;
+
+  std::string ObjectName;
+  if (const auto DecReg = Region->getAs<DeclRegion>()) {
+    const auto *RegionDecl = dyn_cast<NamedDecl>(DecReg->getDecl());
+    ObjectName = RegionDecl->getNameAsString();
+  }
+  std::string InfoText;
+  if (ObjectName != "")
+    InfoText = "'" + ObjectName + "' became 'moved-from' here";
+  else
+    InfoText = "Became 'moved-from' here";
+
+  // Generate the extra diagnostic.
+  PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
+                             N->getLocationContext());
+  return std::make_shared<PathDiagnosticEventPiece>(Pos, InfoText, true);
+}
+
+const ExplodedNode *MisusedMovedObjectChecker::getMoveLocation(
+    const ExplodedNode *N, const MemRegion *Region, CheckerContext &C) const {
+  // Walk the ExplodedGraph backwards and find the first node that referred to
+  // the tracked region.
+  const ExplodedNode *MoveNode = N;
+
+  while (N) {
+    ProgramStateRef State = N->getState();
+    if (!State->get<TrackedRegionMap>(Region))
+      break;
+    MoveNode = N;
+    N = N->pred_empty() ? nullptr : *(N->pred_begin());
+  }
+  return MoveNode;
+}
+
+ExplodedNode *MisusedMovedObjectChecker::reportBug(const MemRegion *Region,
+                                                   const CallEvent &Call,
+                                                   CheckerContext &C,
+                                                   bool isCopy = false) const {
+  if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
+    if (!BT)
+      BT.reset(new BugType(this, "Usage of a 'moved-from' object",
+                           "C++ move semantics"));
+
+    // Uniqueing report to the same object.
+    PathDiagnosticLocation LocUsedForUniqueing;
+    const ExplodedNode *MoveNode = getMoveLocation(N, Region, C);
+
+    if (const Stmt *MoveStmt = PathDiagnosticLocation::getStmt(MoveNode))
+      LocUsedForUniqueing = PathDiagnosticLocation::createBegin(
+          MoveStmt, C.getSourceManager(), MoveNode->getLocationContext());
+
+    // Creating the error message.
+    std::string ErrorMessage;
+    if (isCopy)
+      ErrorMessage = "Copying a 'moved-from' object";
+    else
+      ErrorMessage = "Method call on a 'moved-from' object";
+    if (const auto DecReg = Region->getAs<DeclRegion>()) {
+      const auto *RegionDecl = dyn_cast<NamedDecl>(DecReg->getDecl());
+      ErrorMessage += " '" + RegionDecl->getNameAsString() + "'";
+    }
+
+    auto R =
+        llvm::make_unique<BugReport>(*BT, ErrorMessage, N, LocUsedForUniqueing,
+                                     MoveNode->getLocationContext()->getDecl());
+    R->addVisitor(llvm::make_unique<MovedBugVisitor>(Region));
+    C.emitReport(std::move(R));
+    return N;
+  }
+  return nullptr;
+}
+
+// Removing the function parameters' MemRegion from the state. This is needed
+// for PODs where the trivial destructor does not even created nor executed.
+void MisusedMovedObjectChecker::checkEndFunction(CheckerContext &C) const {
+  auto State = C.getState();
+  TrackedRegionMapTy Objects = State->get<TrackedRegionMap>();
+  if (Objects.isEmpty())
+    return;
+
+  auto LC = C.getLocationContext();
+
+  const auto LD = dyn_cast_or_null<FunctionDecl>(LC->getDecl());
+  if (!LD)
+    return;
+  llvm::SmallSet<const MemRegion *, 8> InvalidRegions;
+
+  for (auto Param : LD->parameters()) {
+    auto Type = Param->getType().getTypePtrOrNull();
+    if (!Type)
+      continue;
+    if (!Type->isPointerType() && !Type->isReferenceType()) {
+      InvalidRegions.insert(State->getLValue(Param, LC).getAsRegion());
+    }
+  }
+
+  if (InvalidRegions.empty())
+    return;
+
+  for (const auto &E : State->get<TrackedRegionMap>()) {
+    if (InvalidRegions.count(E.first->getBaseRegion()))
+      State = State->remove<TrackedRegionMap>(E.first);
+  }
+
+  C.addTransition(State);
+}
+
+void MisusedMovedObjectChecker::checkPostCall(const CallEvent &Call,
+                                              CheckerContext &C) const {
+  const auto *AFC = dyn_cast<AnyFunctionCall>(&Call);
+  if (!AFC)
+    return;
+
+  ProgramStateRef State = C.getState();
+  const auto MethodDecl = dyn_cast_or_null<CXXMethodDecl>(AFC->getDecl());
+  if (!MethodDecl)
+    return;
+
+  const auto *ConstructorDecl = dyn_cast<CXXConstructorDecl>(MethodDecl);
+
+  const auto *CC = dyn_cast_or_null<CXXConstructorCall>(&Call);
+  // Check if an object became moved-from.
+  // Object can become moved from after a call to move assignment operator or
+  // move constructor .
+  if (ConstructorDecl && !ConstructorDecl->isMoveConstructor())
+    return;
+
+  if (!ConstructorDecl && !MethodDecl->isMoveAssignmentOperator())
+    return;
+
+  const auto ArgRegion = AFC->getArgSVal(0).getAsRegion();
+  if (!ArgRegion)
+    return;
+
+  // Skip moving the object to itself.
+  if (CC && CC->getCXXThisVal().getAsRegion() == ArgRegion)
+    return;
+  if (const auto *IC = dyn_cast<CXXInstanceCall>(AFC))
+    if (IC->getCXXThisVal().getAsRegion() == ArgRegion)
+      return;
+
+  const MemRegion *BaseRegion = ArgRegion->getBaseRegion();
+  // Skip temp objects because of their short lifetime.
+  if (BaseRegion->getAs<CXXTempObjectRegion>() ||
+      AFC->getArgExpr(0)->isRValue())
+    return;
+  // If it has already been reported do not need to modify the state.
+
+  if (State->get<TrackedRegionMap>(ArgRegion))
+    return;
+  // Mark object as moved-from.
+  State = State->set<TrackedRegionMap>(ArgRegion, RegionState::getMoved());
+  C.addTransition(State);
+}
+
+bool MisusedMovedObjectChecker::isMoveSafeMethod(
+    const CXXMethodDecl *MethodDec) const {
+  // We abandon the cases where bool/void/void* conversion happens.
+  if (const auto *ConversionDec =
+          dyn_cast_or_null<CXXConversionDecl>(MethodDec)) {
+    const Type *Tp = ConversionDec->getConversionType().getTypePtrOrNull();
+    if (!Tp)
+      return false;
+    if (Tp->isBooleanType() || Tp->isVoidType() || Tp->isVoidPointerType())
+      return true;
+  }
+  // Function call `empty` can be skipped.
+  if (MethodDec && MethodDec->getDeclName().isIdentifier() &&
+      (MethodDec->getName().lower() == "empty" ||
+       MethodDec->getName().lower() == "isempty"))
+    return true;
+
+  return false;
+}
+
+bool MisusedMovedObjectChecker::isStateResetMethod(
+    const CXXMethodDecl *MethodDec) const {
+  if (MethodDec && MethodDec->getDeclName().isIdentifier()) {
+    std::string MethodName = MethodDec->getName().lower();
+    if (MethodName == "reset" || MethodName == "clear" ||
+        MethodName == "destroy")
+      return true;
+  }
+  return false;
+}
+
+// Don't report an error inside a move related operation.
+// We assume that the programmer knows what she does.
+bool MisusedMovedObjectChecker::isInMoveSafeContext(
+    const LocationContext *LC) const {
+  do {
+    const auto *CtxDec = LC->getDecl();
+    auto *CtorDec = dyn_cast_or_null<CXXConstructorDecl>(CtxDec);
+    auto *DtorDec = dyn_cast_or_null<CXXDestructorDecl>(CtxDec);
+    auto *MethodDec = dyn_cast_or_null<CXXMethodDecl>(CtxDec);
+    if (DtorDec || (CtorDec && CtorDec->isCopyOrMoveConstructor()) ||
+        (MethodDec && MethodDec->isOverloadedOperator() &&
+         MethodDec->getOverloadedOperator() == OO_Equal) ||
+        isStateResetMethod(MethodDec) || isMoveSafeMethod(MethodDec))
+      return true;
+  } while ((LC = LC->getParent()));
+  return false;
+}
+
+void MisusedMovedObjectChecker::checkPreCall(const CallEvent &Call,
+                                             CheckerContext &C) const {
+  ProgramStateRef State = C.getState();
+  const LocationContext *LC = C.getLocationContext();
+  ExplodedNode *N = nullptr;
+
+  // Remove the MemRegions from the map on which a ctor/dtor call or assignement
+  // happened.
+
+  // Checking constructor calls.
+  if (const auto *CC = dyn_cast<CXXConstructorCall>(&Call)) {
+    State = removeFromState(State, CC->getCXXThisVal().getAsRegion());
+    auto CtorDec = CC->getDecl();
+    // Check for copying a moved-from object and report the bug.
+    if (CtorDec && CtorDec->isCopyOrMoveConstructor()) {
+      const MemRegion *ArgRegion = CC->getArgSVal(0).getAsRegion();
+      const RegionState *ArgState = State->get<TrackedRegionMap>(ArgRegion);
+      if (ArgState && ArgState->isMoved()) {
+        if (!isInMoveSafeContext(LC)) {
+          N = reportBug(ArgRegion, Call, C, /*isCopy=*/true);
+          State = State->set<TrackedRegionMap>(ArgRegion,
+                                               RegionState::getReported());
+        }
+      }
+    }
+    C.addTransition(State, N);
+    return;
+  }
+
+  const auto IC = dyn_cast<CXXInstanceCall>(&Call);
+  if (!IC)
+    return;
+  // In case of destructor call we do not track the object anymore.
+  const MemRegion *ThisRegion = IC->getCXXThisVal().getAsRegion();
+  if (dyn_cast_or_null<CXXDestructorDecl>(Call.getDecl())) {
+    State = removeFromState(State, IC->getCXXThisVal().getAsRegion());
+    C.addTransition(State);
+    return;
+  }
+
+  const auto MethodDecl = dyn_cast_or_null<CXXMethodDecl>(IC->getDecl());
+  if (!MethodDecl)
+    return;
+  // Checking assignment operators.
+  bool OperatorEq = MethodDecl->isOverloadedOperator() &&
+                    MethodDecl->getOverloadedOperator() == OO_Equal;
+  // Remove the tracked object for every assignment operator, but report bug
+  // only for move or copy assignment's argument.
+  if (OperatorEq) {
+    State = removeFromState(State, ThisRegion);
+    if (MethodDecl->isCopyAssignmentOperator() ||
+        MethodDecl->isMoveAssignmentOperator()) {
+      const RegionState *ArgState =
+          State->get<TrackedRegionMap>(IC->getArgSVal(0).getAsRegion());
+      if (ArgState && ArgState->isMoved() && !isInMoveSafeContext(LC)) {
+        const MemRegion *ArgRegion = IC->getArgSVal(0).getAsRegion();
+        N = reportBug(ArgRegion, Call, C, /*isCopy=*/true);
+        State =
+            State->set<TrackedRegionMap>(ArgRegion, RegionState::getReported());
+      }
+    }
+    C.addTransition(State, N);
+    return;
+  }
+
+  // The remaining part is check only for method call on a moved-from object.
+  if (isMoveSafeMethod(MethodDecl))
+    return;
+
+  if (isStateResetMethod(MethodDecl)) {
+    State = State->remove<TrackedRegionMap>(ThisRegion);
+    C.addTransition(State);
+    return;
+  }
+
+  // If it is already reported then we dont report the bug again.
+  const RegionState *ThisState = State->get<TrackedRegionMap>(ThisRegion);
+  if (!(ThisState && ThisState->isMoved()))
+    return;
+
+  // Dont report it in case if any base region is already reported
+  if (isAnyBaseRegionReported(State, ThisRegion))
+    return;
+
+  if (isInMoveSafeContext(LC))
+    return;
+
+  N = reportBug(ThisRegion, Call, C);
+  State = State->set<TrackedRegionMap>(ThisRegion, RegionState::getReported());
+  C.addTransition(State, N);
+}
+
+void MisusedMovedObjectChecker::checkDeadSymbols(SymbolReaper &SymReaper,
+                                                 CheckerContext &C) const {
+  ProgramStateRef State = C.getState();
+  TrackedRegionMapTy TrackedRegions = State->get<TrackedRegionMap>();
+  for (TrackedRegionMapTy::value_type E : TrackedRegions) {
+    const MemRegion *Region = E.first;
+    bool IsRegDead = !SymReaper.isLiveRegion(Region);
+
+    // Remove the dead regions from the region map.
+    if (IsRegDead) {
+      State = State->remove<TrackedRegionMap>(Region);
+    }
+  }
+  C.addTransition(State);
+}
+
+ProgramStateRef MisusedMovedObjectChecker::checkRegionChanges(
+    ProgramStateRef State, const InvalidatedSymbols *Invalidated,
+    ArrayRef<const MemRegion *> ExplicitRegions,
+    ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx,
+    const CallEvent *Call) const {
+  // In case of an InstanceCall don't remove the ThisRegion from the GDM since
+  // it is handled in checkPreCall and checkPostCall.
+  const MemRegion *ThisRegion = nullptr;
+  if (const auto *IC = dyn_cast_or_null<CXXInstanceCall>(Call)) {
+    ThisRegion = IC->getCXXThisVal().getAsRegion();
+  }
+
+  for (ArrayRef<const MemRegion *>::iterator I = ExplicitRegions.begin(),
+                                             E = ExplicitRegions.end();
+       I != E; ++I) {
+    const auto *Region = *I;
+    if (ThisRegion != Region) {
+      State = removeFromState(State, Region);
+    }
+  }
+
+  return State;
+}
+
+void ento::registerMisusedMovedObjectChecker(CheckerManager &mgr) {
+  mgr.registerChecker<MisusedMovedObjectChecker>();
+}
diff --git a/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
index c14a87c..33d3c1f 100644
--- a/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp
@@ -178,7 +178,7 @@
                  const MemRegion *Region, BugReporter &BR,
                  const Stmt *ValueExpr = nullptr) const {
     if (!BT)
-      BT.reset(new BugType(this, "Nullability", "Memory error"));
+      BT.reset(new BugType(this, "Nullability", categories::MemoryError));
 
     auto R = llvm::make_unique<BugReport>(*BT, Msg, N);
     if (Region) {
diff --git a/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp
index b9857e5..dfd2c9a 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCPropertyChecker.cpp
@@ -58,8 +58,7 @@
   if (const ObjCInterfaceDecl *IntD =
           dyn_cast<ObjCInterfaceDecl>(D->getDeclContext())) {
     ImplD = IntD->getImplementation();
-  } else {
-    const ObjCCategoryDecl *CatD = cast<ObjCCategoryDecl>(D->getDeclContext());
+  } else if (auto *CatD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext())) {
     ImplD = CatD->getClassInterface()->getImplementation();
   }
 
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index eb101e1..3f6ae62 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -2661,6 +2661,7 @@
                      const InvalidatedSymbols *invalidated,
                      ArrayRef<const MemRegion *> ExplicitRegions,
                      ArrayRef<const MemRegion *> Regions,
+                     const LocationContext* LCtx,
                      const CallEvent *Call) const;
 
   void checkPreStmt(const ReturnStmt *S, CheckerContext &C) const;
@@ -3647,7 +3648,7 @@
       // same state.
       SVal StoredVal = state->getSVal(regionLoc->getRegion());
       if (StoredVal != val)
-        escapes = (state == (state->bindLoc(*regionLoc, val)));
+        escapes = (state == (state->bindLoc(*regionLoc, val, C.getLocationContext())));
     }
     if (!escapes) {
       // Case 4: We do not currently model what happens when a symbol is
@@ -3714,10 +3715,11 @@
 
 ProgramStateRef
 RetainCountChecker::checkRegionChanges(ProgramStateRef state,
-                                    const InvalidatedSymbols *invalidated,
-                                    ArrayRef<const MemRegion *> ExplicitRegions,
-                                    ArrayRef<const MemRegion *> Regions,
-                                    const CallEvent *Call) const {
+                                       const InvalidatedSymbols *invalidated,
+                                       ArrayRef<const MemRegion *> ExplicitRegions,
+                                       ArrayRef<const MemRegion *> Regions,
+                                       const LocationContext *LCtx,
+                                       const CallEvent *Call) const {
   if (!invalidated)
     return state;
 
diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
index 38d2aa6..f3c2ffc 100644
--- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -35,6 +35,30 @@
 };
 } // end anonymous namespace
 
+static bool isArrayIndexOutOfBounds(CheckerContext &C, const Expr *Ex) {
+  ProgramStateRef state = C.getState();
+  const LocationContext *LCtx = C.getLocationContext();
+
+  if (!isa<ArraySubscriptExpr>(Ex))
+    return false;
+
+  SVal Loc = state->getSVal(Ex, LCtx);
+  if (!Loc.isValid())
+    return false;
+
+  const MemRegion *MR = Loc.castAs<loc::MemRegionVal>().getRegion();
+  const ElementRegion *ER = dyn_cast<ElementRegion>(MR);
+  if (!ER)
+    return false;
+
+  DefinedOrUnknownSVal Idx = ER->getIndex().castAs<DefinedOrUnknownSVal>();
+  DefinedOrUnknownSVal NumElements = C.getStoreManager().getSizeInElements(
+      state, ER->getSuperRegion(), ER->getValueType());
+  ProgramStateRef StInBound = state->assumeInBound(Idx, NumElements, true);
+  ProgramStateRef StOutBound = state->assumeInBound(Idx, NumElements, false);
+  return StOutBound && !StInBound;
+}
+
 void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
                                        CheckerContext &C) const {
   ProgramStateRef state = C.getState();
@@ -77,6 +101,8 @@
          << " operand of '"
          << BinaryOperator::getOpcodeStr(B->getOpcode())
          << "' is a garbage value";
+      if (isArrayIndexOutOfBounds(C, Ex))
+        OS << " due to array index out of bounds";
     }
     else {
       // Neither operand was undefined, but the result is undefined.
diff --git a/lib/StaticAnalyzer/Checkers/ValistChecker.cpp b/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
index 0b7a486..06c4ef7 100644
--- a/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ValistChecker.cpp
@@ -54,11 +54,11 @@
   void checkDeadSymbols(SymbolReaper &SR, CheckerContext &C) const;
 
 private:
-  const MemRegion *getVAListAsRegion(SVal SV, CheckerContext &C) const;
+  const MemRegion *getVAListAsRegion(SVal SV, const Expr *VAExpr,
+                                     bool &IsSymbolic, CheckerContext &C) const;
   StringRef getVariableNameFromRegion(const MemRegion *Reg) const;
   const ExplodedNode *getStartCallSite(const ExplodedNode *N,
-                                       const MemRegion *Reg,
-                                       CheckerContext &C) const;
+                                       const MemRegion *Reg) const;
 
   void reportUninitializedAccess(const MemRegion *VAList, StringRef Msg,
                                  CheckerContext &C) const;
@@ -138,14 +138,21 @@
     for (auto FuncInfo : VAListAccepters) {
       if (!Call.isCalled(FuncInfo.Func))
         continue;
+      bool Symbolic;
       const MemRegion *VAList =
-          getVAListAsRegion(Call.getArgSVal(FuncInfo.VAListPos), C);
+          getVAListAsRegion(Call.getArgSVal(FuncInfo.VAListPos),
+                            Call.getArgExpr(FuncInfo.VAListPos), Symbolic, C);
       if (!VAList)
         return;
 
       if (C.getState()->contains<InitializedVALists>(VAList))
         return;
 
+      // We did not see va_start call, but the source of the region is unknown.
+      // Be conservative and assume the best.
+      if (Symbolic)
+        return;
+
       SmallString<80> Errmsg("Function '");
       Errmsg += FuncInfo.Func.getFunctionName();
       Errmsg += "' is called with an uninitialized va_list argument";
@@ -155,13 +162,41 @@
   }
 }
 
+const MemRegion *ValistChecker::getVAListAsRegion(SVal SV, const Expr *E,
+                                                  bool &IsSymbolic,
+                                                  CheckerContext &C) const {
+  const MemRegion *Reg = SV.getAsRegion();
+  if (!Reg)
+    return nullptr;
+  // TODO: In the future this should be abstracted away by the analyzer.
+  bool VaListModelledAsArray = false;
+  if (const auto *Cast = dyn_cast<CastExpr>(E)) {
+    QualType Ty = Cast->getType();
+    VaListModelledAsArray =
+        Ty->isPointerType() && Ty->getPointeeType()->isRecordType();
+  }
+  if (const auto *DeclReg = Reg->getAs<DeclRegion>()) {
+    if (isa<ParmVarDecl>(DeclReg->getDecl()))
+      Reg = C.getState()->getSVal(SV.castAs<Loc>()).getAsRegion();
+  }
+  IsSymbolic = Reg && Reg->getAs<SymbolicRegion>();
+  // Some VarRegion based VA lists reach here as ElementRegions.
+  const auto *EReg = dyn_cast_or_null<ElementRegion>(Reg);
+  return (EReg && VaListModelledAsArray) ? EReg->getSuperRegion() : Reg;
+}
+
 void ValistChecker::checkPreStmt(const VAArgExpr *VAA,
                                  CheckerContext &C) const {
   ProgramStateRef State = C.getState();
-  SVal VAListSVal = State->getSVal(VAA->getSubExpr(), C.getLocationContext());
-  const MemRegion *VAList = getVAListAsRegion(VAListSVal, C);
+  const Expr *VASubExpr = VAA->getSubExpr();
+  SVal VAListSVal = State->getSVal(VASubExpr, C.getLocationContext());
+  bool Symbolic;
+  const MemRegion *VAList =
+      getVAListAsRegion(VAListSVal, VASubExpr, Symbolic, C);
   if (!VAList)
     return;
+  if (Symbolic)
+    return;
   if (!State->contains<InitializedVALists>(VAList))
     reportUninitializedAccess(
         VAList, "va_arg() is called on an uninitialized va_list", C);
@@ -183,22 +218,13 @@
                         N);
 }
 
-const MemRegion *ValistChecker::getVAListAsRegion(SVal SV,
-                                                  CheckerContext &C) const {
-  const MemRegion *Reg = SV.getAsRegion();
-  const auto *TReg = dyn_cast_or_null<TypedValueRegion>(Reg);
-  // Some VarRegion based VLAs reach here as ElementRegions.
-  const auto *EReg = dyn_cast_or_null<ElementRegion>(TReg);
-  return EReg ? EReg->getSuperRegion() : TReg;
-}
-
 // This function traverses the exploded graph backwards and finds the node where
 // the va_list is initialized. That node is used for uniquing the bug paths.
 // It is not likely that there are several different va_lists that belongs to
 // different stack frames, so that case is not yet handled.
-const ExplodedNode *ValistChecker::getStartCallSite(const ExplodedNode *N,
-                                                    const MemRegion *Reg,
-                                                    CheckerContext &C) const {
+const ExplodedNode *
+ValistChecker::getStartCallSite(const ExplodedNode *N,
+                                const MemRegion *Reg) const {
   const LocationContext *LeakContext = N->getLocationContext();
   const ExplodedNode *StartCallNode = N;
 
@@ -230,7 +256,7 @@
     if (!BT_uninitaccess)
       BT_uninitaccess.reset(new BugType(CheckNames[CK_Uninitialized],
                                         "Uninitialized va_list",
-                                        "Memory Error"));
+                                        categories::MemoryError));
     auto R = llvm::make_unique<BugReport>(*BT_uninitaccess, Msg, N);
     R->markInteresting(VAList);
     R->addVisitor(llvm::make_unique<ValistBugVisitor>(VAList));
@@ -248,11 +274,12 @@
   for (auto Reg : LeakedVALists) {
     if (!BT_leakedvalist) {
       BT_leakedvalist.reset(new BugType(CheckNames[CK_Unterminated],
-                                        "Leaked va_list", "Memory Error"));
+                                        "Leaked va_list",
+                                        categories::MemoryError));
       BT_leakedvalist->setSuppressOnSink(true);
     }
 
-    const ExplodedNode *StartNode = getStartCallSite(N, Reg, C);
+    const ExplodedNode *StartNode = getStartCallSite(N, Reg);
     PathDiagnosticLocation LocUsedForUniqueing;
 
     if (const Stmt *StartCallStmt = PathDiagnosticLocation::getStmt(StartNode))
@@ -278,13 +305,17 @@
 
 void ValistChecker::checkVAListStartCall(const CallEvent &Call,
                                          CheckerContext &C, bool IsCopy) const {
-  const MemRegion *VAList = getVAListAsRegion(Call.getArgSVal(0), C);
-  ProgramStateRef State = C.getState();
+  bool Symbolic;
+  const MemRegion *VAList =
+      getVAListAsRegion(Call.getArgSVal(0), Call.getArgExpr(0), Symbolic, C);
   if (!VAList)
     return;
 
+  ProgramStateRef State = C.getState();
+
   if (IsCopy) {
-    const MemRegion *Arg2 = getVAListAsRegion(Call.getArgSVal(1), C);
+    const MemRegion *Arg2 =
+        getVAListAsRegion(Call.getArgSVal(1), Call.getArgExpr(1), Symbolic, C);
     if (Arg2) {
       if (ChecksEnabled[CK_CopyToSelf] && VAList == Arg2) {
         RegionVector LeakedVALists{VAList};
@@ -292,7 +323,7 @@
           reportLeakedVALists(LeakedVALists, "va_list",
                               " is copied onto itself", C, N, true);
         return;
-      } else if (!State->contains<InitializedVALists>(Arg2)) {
+      } else if (!State->contains<InitializedVALists>(Arg2) && !Symbolic) {
         if (State->contains<InitializedVALists>(VAList)) {
           State = State->remove<InitializedVALists>(VAList);
           RegionVector LeakedVALists{VAList};
@@ -321,10 +352,17 @@
 
 void ValistChecker::checkVAListEndCall(const CallEvent &Call,
                                        CheckerContext &C) const {
-  const MemRegion *VAList = getVAListAsRegion(Call.getArgSVal(0), C);
+  bool Symbolic;
+  const MemRegion *VAList =
+      getVAListAsRegion(Call.getArgSVal(0), Call.getArgExpr(0), Symbolic, C);
   if (!VAList)
     return;
 
+  // We did not see va_start call, but the source of the region is unknown.
+  // Be conservative and assume the best.
+  if (Symbolic)
+    return;
+
   if (!C.getState()->contains<InitializedVALists>(VAList)) {
     reportUninitializedAccess(
         VAList, "va_end() is called on an uninitialized va_list", C);
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index 1542263..45ef612 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -230,7 +230,7 @@
 bool AnalyzerOptions::shouldSuppressFromCXXStandardLibrary() {
   return getBooleanOption(SuppressFromCXXStandardLibrary,
                           "suppress-c++-stdlib",
-                          /* Default = */ false);
+                          /* Default = */ true);
 }
 
 bool AnalyzerOptions::shouldReportIssuesInMainSourceFile() {
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index c3c3f2f..f7abbbc 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -961,6 +961,26 @@
   const Expr *Inner = nullptr;
   if (const Expr *Ex = dyn_cast<Expr>(S)) {
     Ex = Ex->IgnoreParenCasts();
+
+    // Performing operator `&' on an lvalue expression is essentially a no-op.
+    // Then, if we are taking addresses of fields or elements, these are also
+    // unlikely to matter.
+    // FIXME: There's a hack in our Store implementation that always computes
+    // field offsets around null pointers as if they are always equal to 0.
+    // The idea here is to report accesses to fields as null dereferences
+    // even though the pointer value that's being dereferenced is actually
+    // the offset of the field rather than exactly 0.
+    // See the FIXME in StoreManager's getLValueFieldOrIvar() method.
+    // This code interacts heavily with this hack; otherwise the value
+    // would not be null at all for most fields, so we'd be unable to track it.
+    if (const auto *Op = dyn_cast<UnaryOperator>(Ex))
+      if (Op->getOpcode() == UO_AddrOf && Op->getSubExpr()->isLValue()) {
+        Ex = Op->getSubExpr()->IgnoreParenCasts();
+        while (const auto *ME = dyn_cast<MemberExpr>(Ex)) {
+          Ex = ME->getBase()->IgnoreParenCasts();
+        }
+      }
+
     if (ExplodedGraph::isInterestingLValueExpr(Ex) || CallEvent::isCallStmt(Ex))
       Inner = Ex;
   }
diff --git a/lib/StaticAnalyzer/Core/CMakeLists.txt b/lib/StaticAnalyzer/Core/CMakeLists.txt
index aaffb0b..85878f5 100644
--- a/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -1,5 +1,12 @@
 set(LLVM_LINK_COMPONENTS support)
 
+# Link Z3 if the user wants to build it.
+if(CLANG_ANALYZER_WITH_Z3)
+  set(Z3_LINK_FILES ${Z3_LIBRARIES})
+else()
+  set(Z3_LINK_FILES "")
+endif()
+
 add_clang_library(clangStaticAnalyzerCore
   APSIntType.cpp
   AnalysisManager.cpp
@@ -34,6 +41,7 @@
   PlistDiagnostics.cpp
   ProgramState.cpp
   RangeConstraintManager.cpp
+  RangedConstraintManager.cpp
   RegionStore.cpp
   SValBuilder.cpp
   SVals.cpp
@@ -42,6 +50,7 @@
   Store.cpp
   SubEngine.cpp
   SymbolManager.cpp
+  Z3ConstraintManager.cpp
 
   LINK_LIBS
   clangAST
@@ -49,4 +58,12 @@
   clangBasic
   clangLex
   clangRewrite
+  ${Z3_LINK_FILES}
   )
+
+if(CLANG_ANALYZER_WITH_Z3)
+  target_include_directories(clangStaticAnalyzerCore SYSTEM
+    PRIVATE
+    ${Z3_INCLUDE_DIR}
+    )
+endif()
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 420e2a6..ee76168 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -212,9 +212,12 @@
 
 bool CallEvent::isCalled(const CallDescription &CD) const {
   assert(getKind() != CE_ObjCMessage && "Obj-C methods are not supported");
-  if (!CD.II)
+  if (!CD.IsLookupDone) {
+    CD.IsLookupDone = true;
     CD.II = &getState()->getStateManager().getContext().Idents.get(CD.FuncName);
-  if (getCalleeIdentifier() != CD.II)
+  }
+  const IdentifierInfo *II = getCalleeIdentifier();
+  if (!II || II != CD.II)
     return false;
   return (CD.RequiredArgs == CallDescription::NoArgRequirement ||
           CD.RequiredArgs == getNumArgs());
@@ -692,13 +695,15 @@
   if (const ObjCPropertyDecl *PropDecl = getAccessedProperty()) {
     if (const ObjCIvarDecl *PropIvar = PropDecl->getPropertyIvarDecl()) {
       SVal IvarLVal = getState()->getLValue(PropIvar, getReceiverSVal());
-      const MemRegion *IvarRegion = IvarLVal.getAsRegion();
-      ETraits->setTrait(
+      if (const MemRegion *IvarRegion = IvarLVal.getAsRegion()) {
+        ETraits->setTrait(
           IvarRegion,
           RegionAndSymbolInvalidationTraits::TK_DoNotInvalidateSuperRegion);
-      ETraits->setTrait(IvarRegion,
-                        RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
-      Values.push_back(IvarLVal);
+        ETraits->setTrait(
+          IvarRegion,
+          RegionAndSymbolInvalidationTraits::TK_SuppressEscape);
+        Values.push_back(IvarLVal);
+      }
       return;
     }
   }
@@ -896,6 +901,38 @@
   llvm_unreachable("The while loop should always terminate.");
 }
 
+static const ObjCMethodDecl *findDefiningRedecl(const ObjCMethodDecl *MD) {
+  if (!MD)
+    return MD;
+
+  // Find the redeclaration that defines the method.
+  if (!MD->hasBody()) {
+    for (auto I : MD->redecls())
+      if (I->hasBody())
+        MD = cast<ObjCMethodDecl>(I);
+  }
+  return MD;
+}
+
+static bool isCallToSelfClass(const ObjCMessageExpr *ME) {
+  const Expr* InstRec = ME->getInstanceReceiver();
+  if (!InstRec)
+    return false;
+  const auto *InstRecIg = dyn_cast<DeclRefExpr>(InstRec->IgnoreParenImpCasts());
+
+  // Check that receiver is called 'self'.
+  if (!InstRecIg || !InstRecIg->getFoundDecl() ||
+      !InstRecIg->getFoundDecl()->getName().equals("self"))
+    return false;
+
+  // Check that the method name is 'class'.
+  if (ME->getSelector().getNumArgs() != 0 ||
+      !ME->getSelector().getNameForSlot(0).equals("class"))
+    return false;
+
+  return true;
+}
+
 RuntimeDefinition ObjCMethodCall::getRuntimeDefinition() const {
   const ObjCMessageExpr *E = getOriginExpr();
   assert(E);
@@ -910,6 +947,7 @@
     const MemRegion *Receiver = nullptr;
 
     if (!SupersType.isNull()) {
+      // The receiver is guaranteed to be 'super' in this case.
       // Super always means the type of immediate predecessor to the method
       // where the call occurs.
       ReceiverT = cast<ObjCObjectPointerType>(SupersType);
@@ -921,7 +959,7 @@
       DynamicTypeInfo DTI = getDynamicTypeInfo(getState(), Receiver);
       QualType DynType = DTI.getType();
       CanBeSubClassed = DTI.canBeASubClass();
-      ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType);
+      ReceiverT = dyn_cast<ObjCObjectPointerType>(DynType.getCanonicalType());
 
       if (ReceiverT && CanBeSubClassed)
         if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl())
@@ -929,7 +967,32 @@
             CanBeSubClassed = false;
     }
 
-    // Lookup the method implementation.
+    // Handle special cases of '[self classMethod]' and
+    // '[[self class] classMethod]', which are treated by the compiler as
+    // instance (not class) messages. We will statically dispatch to those.
+    if (auto *PT = dyn_cast_or_null<ObjCObjectPointerType>(ReceiverT)) {
+      // For [self classMethod], return the compiler visible declaration.
+      if (PT->getObjectType()->isObjCClass() &&
+          Receiver == getSelfSVal().getAsRegion())
+        return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
+
+      // Similarly, handle [[self class] classMethod].
+      // TODO: We are currently doing a syntactic match for this pattern with is
+      // limiting as the test cases in Analysis/inlining/InlineObjCClassMethod.m
+      // shows. A better way would be to associate the meta type with the symbol
+      // using the dynamic type info tracking and use it here. We can add a new
+      // SVal for ObjC 'Class' values that know what interface declaration they
+      // come from. Then 'self' in a class method would be filled in with
+      // something meaningful in ObjCMethodCall::getReceiverSVal() and we could
+      // do proper dynamic dispatch for class methods just like we do for
+      // instance methods now.
+      if (E->getInstanceReceiver())
+        if (const auto *M = dyn_cast<ObjCMessageExpr>(E->getInstanceReceiver()))
+          if (isCallToSelfClass(M))
+            return RuntimeDefinition(findDefiningRedecl(E->getMethodDecl()));
+    }
+
+    // Lookup the instance method implementation.
     if (ReceiverT)
       if (ObjCInterfaceDecl *IDecl = ReceiverT->getInterfaceDecl()) {
         // Repeatedly calling lookupPrivateMethod() is expensive, especially
diff --git a/lib/StaticAnalyzer/Core/CheckerManager.cpp b/lib/StaticAnalyzer/Core/CheckerManager.cpp
index 79e204c..49f3ede 100644
--- a/lib/StaticAnalyzer/Core/CheckerManager.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerManager.cpp
@@ -521,17 +521,19 @@
 /// \brief Run checkers for region changes.
 ProgramStateRef
 CheckerManager::runCheckersForRegionChanges(ProgramStateRef state,
-                                    const InvalidatedSymbols *invalidated,
-                                    ArrayRef<const MemRegion *> ExplicitRegions,
-                                    ArrayRef<const MemRegion *> Regions,
-                                    const CallEvent *Call) {
+                                            const InvalidatedSymbols *invalidated,
+                                            ArrayRef<const MemRegion *> ExplicitRegions,
+                                            ArrayRef<const MemRegion *> Regions,
+                                            const LocationContext *LCtx,
+                                            const CallEvent *Call) {
   for (unsigned i = 0, e = RegionChangesCheckers.size(); i != e; ++i) {
     // If any checker declares the state infeasible (or if it starts that way),
     // bail out.
     if (!state)
       return nullptr;
     state = RegionChangesCheckers[i](state, invalidated,
-                                     ExplicitRegions, Regions, Call);
+                                     ExplicitRegions, Regions,
+                                     LCtx, Call);
   }
   return state;
 }
diff --git a/lib/StaticAnalyzer/Core/CommonBugCategories.cpp b/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
index 3cb9323..421dfa4 100644
--- a/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
+++ b/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
@@ -16,5 +16,6 @@
 const char * const LogicError = "Logic error";
 const char * const MemoryCoreFoundationObjectiveC =
   "Memory (Core Foundation/Objective-C)";
+const char * const MemoryError = "Memory error";
 const char * const UnixAPI = "Unix API";
 }}}
diff --git a/lib/StaticAnalyzer/Core/ConstraintManager.cpp b/lib/StaticAnalyzer/Core/ConstraintManager.cpp
index b7db833..8de2b0e 100644
--- a/lib/StaticAnalyzer/Core/ConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/ConstraintManager.cpp
@@ -20,8 +20,8 @@
 
 static DefinedSVal getLocFromSymbol(const ProgramStateRef &State,
                                     SymbolRef Sym) {
-  const MemRegion *R = State->getStateManager().getRegionManager()
-                                               .getSymbolicRegion(Sym);
+  const MemRegion *R =
+      State->getStateManager().getRegionManager().getSymbolicRegion(Sym);
   return loc::MemRegionVal(R);
 }
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index d563f8e..4f177c8 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -182,19 +182,25 @@
 ProgramStateRef
 ExprEngine::createTemporaryRegionIfNeeded(ProgramStateRef State,
                                           const LocationContext *LC,
-                                          const Expr *Ex,
+                                          const Expr *InitWithAdjustments,
                                           const Expr *Result) {
-  SVal V = State->getSVal(Ex, LC);
+  // FIXME: This function is a hack that works around the quirky AST
+  // we're often having with respect to C++ temporaries. If only we modelled
+  // the actual execution order of statements properly in the CFG,
+  // all the hassle with adjustments would not be necessary,
+  // and perhaps the whole function would be removed.
+  SVal InitValWithAdjustments = State->getSVal(InitWithAdjustments, LC);
   if (!Result) {
     // If we don't have an explicit result expression, we're in "if needed"
     // mode. Only create a region if the current value is a NonLoc.
-    if (!V.getAs<NonLoc>())
+    if (!InitValWithAdjustments.getAs<NonLoc>())
       return State;
-    Result = Ex;
+    Result = InitWithAdjustments;
   } else {
     // We need to create a region no matter what. For sanity, make sure we don't
     // try to stuff a Loc into a non-pointer temporary region.
-    assert(!V.getAs<Loc>() || Loc::isLocType(Result->getType()) ||
+    assert(!InitValWithAdjustments.getAs<Loc>() ||
+           Loc::isLocType(Result->getType()) ||
            Result->getType()->isMemberPointerType());
   }
 
@@ -226,7 +232,8 @@
   SmallVector<const Expr *, 2> CommaLHSs;
   SmallVector<SubobjectAdjustment, 2> Adjustments;
 
-  const Expr *Init = Ex->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
+  const Expr *Init = InitWithAdjustments->skipRValueSubobjectAdjustments(
+      CommaLHSs, Adjustments);
 
   const TypedValueRegion *TR = nullptr;
   if (const MaterializeTemporaryExpr *MT =
@@ -241,6 +248,7 @@
     TR = MRMgr.getCXXTempObjectRegion(Init, LC);
 
   SVal Reg = loc::MemRegionVal(TR);
+  SVal BaseReg = Reg;
 
   // Make the necessary adjustments to obtain the sub-object.
   for (auto I = Adjustments.rbegin(), E = Adjustments.rend(); I != E; ++I) {
@@ -254,19 +262,47 @@
       break;
     case SubobjectAdjustment::MemberPointerAdjustment:
       // FIXME: Unimplemented.
-      State->bindDefault(Reg, UnknownVal());
+      State = State->bindDefault(Reg, UnknownVal(), LC);
       return State;
     }
   }
 
-  // Try to recover some path sensitivity in case we couldn't compute the value.
-  if (V.isUnknown())
-    V = getSValBuilder().conjureSymbolVal(Result, LC, TR->getValueType(),
-                                          currBldrCtx->blockCount());
-  // Bind the value of the expression to the sub-object region, and then bind
-  // the sub-object region to our expression.
-  State = State->bindLoc(Reg, V);
+  // What remains is to copy the value of the object to the new region.
+  // FIXME: In other words, what we should always do is copy value of the
+  // Init expression (which corresponds to the bigger object) to the whole
+  // temporary region TR. However, this value is often no longer present
+  // in the Environment. If it has disappeared, we instead invalidate TR.
+  // Still, what we can do is assign the value of expression Ex (which
+  // corresponds to the sub-object) to the TR's sub-region Reg. At least,
+  // values inside Reg would be correct.
+  SVal InitVal = State->getSVal(Init, LC);
+  if (InitVal.isUnknown()) {
+    InitVal = getSValBuilder().conjureSymbolVal(Result, LC, Init->getType(),
+                                                currBldrCtx->blockCount());
+    State = State->bindLoc(BaseReg.castAs<Loc>(), InitVal, LC, false);
+
+    // Then we'd need to take the value that certainly exists and bind it over.
+    if (InitValWithAdjustments.isUnknown()) {
+      // Try to recover some path sensitivity in case we couldn't
+      // compute the value.
+      InitValWithAdjustments = getSValBuilder().conjureSymbolVal(
+          Result, LC, InitWithAdjustments->getType(),
+          currBldrCtx->blockCount());
+    }
+    State =
+        State->bindLoc(Reg.castAs<Loc>(), InitValWithAdjustments, LC, false);
+  } else {
+    State = State->bindLoc(BaseReg.castAs<Loc>(), InitVal, LC, false);
+  }
+
+  // The result expression would now point to the correct sub-region of the
+  // newly created temporary region. Do this last in order to getSVal of Init
+  // correctly in case (Result == Init).
   State = State->BindExpr(Result, LC, Reg);
+
+  // Notify checkers once for two bindLoc()s.
+  State = processRegionChange(State, TR, LC);
+
   return State;
 }
 
@@ -286,9 +322,11 @@
                                  const InvalidatedSymbols *invalidated,
                                  ArrayRef<const MemRegion *> Explicits,
                                  ArrayRef<const MemRegion *> Regions,
+                                 const LocationContext *LCtx,
                                  const CallEvent *Call) {
   return getCheckerManager().runCheckersForRegionChanges(state, invalidated,
-                                                      Explicits, Regions, Call);
+                                                         Explicits, Regions,
+                                                         LCtx, Call);
 }
 
 void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
@@ -613,7 +651,15 @@
   const MemRegion *Region = dest.castAs<loc::MemRegionVal>().getRegion();
 
   if (varType->isReferenceType()) {
-    Region = state->getSVal(Region).getAsRegion()->getBaseRegion();
+    const MemRegion *ValueRegion = state->getSVal(Region).getAsRegion();
+    if (!ValueRegion) {
+      // FIXME: This should not happen. The language guarantees a presence
+      // of a valid initializer here, so the reference shall not be undefined.
+      // It seems that we're calling destructors over variables that
+      // were not initialized yet.
+      return;
+    }
+    Region = ValueRegion->getBaseRegion();
     varType = cast<TypedValueRegion>(Region)->getValueType();
   }
 
@@ -1856,8 +1902,8 @@
 
     // Evaluate the LHS of the case value.
     llvm::APSInt V1 = Case->getLHS()->EvaluateKnownConstInt(getContext());
-    assert(V1.getBitWidth() == getContext().getTypeSize(CondE->getType()));
-
+    assert(V1.getBitWidth() == getContext().getIntWidth(CondE->getType()));
+    
     // Get the RHS of the case, if it exists.
     llvm::APSInt V2;
     if (const Expr *E = Case->getRHS())
@@ -2165,7 +2211,9 @@
 // (3) We are binding to a MemRegion with stack storage that the store
 //     does not understand.
 ProgramStateRef ExprEngine::processPointerEscapedOnBind(ProgramStateRef State,
-                                                        SVal Loc, SVal Val) {
+                                                        SVal Loc,
+                                                        SVal Val,
+                                                        const LocationContext *LCtx) {
   // Are we storing to something that causes the value to "escape"?
   bool escapes = true;
 
@@ -2181,7 +2229,7 @@
       // same state.
       SVal StoredVal = State->getSVal(regionLoc->getRegion());
       if (StoredVal != Val)
-        escapes = (State == (State->bindLoc(*regionLoc, Val)));
+        escapes = (State == (State->bindLoc(*regionLoc, Val, LCtx)));
     }
   }
 
@@ -2278,7 +2326,7 @@
     const ProgramPoint L = PostStore(StoreE, LC, /*Loc*/nullptr,
                                      /*tag*/nullptr);
     ProgramStateRef state = Pred->getState();
-    state = processPointerEscapedOnBind(state, location, Val);
+    state = processPointerEscapedOnBind(state, location, Val, LC);
     Bldr.generateNode(L, state, Pred);
     return;
   }
@@ -2288,13 +2336,13 @@
     ExplodedNode *PredI = *I;
     ProgramStateRef state = PredI->getState();
 
-    state = processPointerEscapedOnBind(state, location, Val);
+    state = processPointerEscapedOnBind(state, location, Val, LC);
 
     // When binding the value, pass on the hint that this is a initialization.
     // For initializations, we do not need to inform clients of region
     // changes.
     state = state->bindLoc(location.castAs<Loc>(),
-                           Val, /* notifyChanges = */ !atDeclInit);
+                           Val, LC, /* notifyChanges = */ !atDeclInit);
 
     const MemRegion *LocReg = nullptr;
     if (Optional<loc::MemRegionVal> LocRegVal =
@@ -2520,7 +2568,7 @@
     assert (!X.getAs<NonLoc>());  // Should be an Lval, or unknown, undef.
 
     if (Optional<Loc> LV = X.getAs<Loc>())
-      state = state->bindLoc(*LV, UnknownVal());
+      state = state->bindLoc(*LV, UnknownVal(), Pred->getLocationContext());
   }
 
   Bldr.generateNode(A, Pred, state);
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 89fab1d..8f720a2 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -227,12 +227,13 @@
 
       if (capturedR != originalR) {
         SVal originalV;
+        const LocationContext *LCtx = Pred->getLocationContext();
         if (copyExpr) {
-          originalV = State->getSVal(copyExpr, Pred->getLocationContext());
+          originalV = State->getSVal(copyExpr, LCtx);
         } else {
           originalV = State->getSVal(loc::MemRegionVal(originalR));
         }
-        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV);
+        State = State->bindLoc(loc::MemRegionVal(capturedR), originalV, LCtx);
       }
     }
   }
@@ -534,7 +535,7 @@
   } else {
     assert(isa<InitListExpr>(Init));
     Loc CLLoc = State->getLValue(CL, LCtx);
-    State = State->bindLoc(CLLoc, V);
+    State = State->bindLoc(CLLoc, V, LCtx);
 
     if (CL->isGLValue())
       V = CLLoc;
@@ -1053,7 +1054,7 @@
     // Conjure a new symbol if necessary to recover precision.
     if (Result.isUnknown()){
       DefinedOrUnknownSVal SymVal =
-        svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
+        svalBuilder.conjureSymbolVal(nullptr, U, LCtx,
                                      currBldrCtx->blockCount());
       Result = SymVal;
 
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index 7e9b203..03e0095 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -317,7 +317,7 @@
         // actually make things worse. Placement new makes this tricky as well,
         // since it's then possible to be initializing one part of a multi-
         // dimensional array.
-        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
+        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal, LCtx);
         Bldr.generateNode(CE, *I, State, /*tag=*/nullptr,
                           ProgramPoint::PreStmtKind);
       }
@@ -512,7 +512,8 @@
   if (CNE->isArray()) {
     // FIXME: allocating an array requires simulating the constructors.
     // For now, just return a symbolicated region.
-    const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
+    const SubRegion *NewReg =
+        symVal.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>();
     QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
     const ElementRegion *EleReg =
       getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
@@ -572,7 +573,7 @@
   SVal V = svalBuilder.conjureSymbolVal(CS, LCtx, VD->getType(),
                                         currBldrCtx->blockCount());
   ProgramStateRef state = Pred->getState();
-  state = state->bindLoc(state->getLValue(VD, LCtx), V);
+  state = state->bindLoc(state->getLValue(VD, LCtx), V, LCtx);
 
   StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   Bldr.generateNode(CS, Pred, state);
@@ -627,7 +628,7 @@
       InitVal = State->getSVal(SizeExpr, LocCtxt);
     }
 
-    State = State->bindLoc(FieldLoc, InitVal);
+    State = State->bindLoc(FieldLoc, InitVal, LocCtxt);
   }
 
   // Decay the Loc into an RValue, because there might be a
diff --git a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
index 92c5fe6..f5e64f4 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineObjC.cpp
@@ -115,11 +115,11 @@
         SymbolRef Sym = SymMgr.conjureSymbol(elem, LCtx, T,
                                              currBldrCtx->blockCount());
         SVal V = svalBuilder.makeLoc(Sym);
-        hasElems = hasElems->bindLoc(elementV, V);
+        hasElems = hasElems->bindLoc(elementV, V, LCtx);
 
         // Bind the location to 'nil' on the false branch.
         SVal nilV = svalBuilder.makeIntVal(0, T);
-        noElems = noElems->bindLoc(elementV, nilV);
+        noElems = noElems->bindLoc(elementV, nilV, LCtx);
       }
 
     // Create the new nodes.
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index d6e8fe5..7bc186d 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -31,54 +31,56 @@
 // MemRegion Construction.
 //===----------------------------------------------------------------------===//
 
-template <typename RegionTy, typename A1>
-RegionTy* MemRegionManager::getSubRegion(const A1 a1,
-                                         const MemRegion *superRegion) {
+template <typename RegionTy, typename SuperTy, typename Arg1Ty>
+RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1,
+                                         const SuperTy *superRegion) {
   llvm::FoldingSetNodeID ID;
-  RegionTy::ProfileRegion(ID, a1, superRegion);
+  RegionTy::ProfileRegion(ID, arg1, superRegion);
   void *InsertPos;
   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
                                                                    InsertPos));
 
   if (!R) {
     R = A.Allocate<RegionTy>();
-    new (R) RegionTy(a1, superRegion);
+    new (R) RegionTy(arg1, superRegion);
     Regions.InsertNode(R, InsertPos);
   }
 
   return R;
 }
 
-template <typename RegionTy, typename A1, typename A2>
-RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
-                                         const MemRegion *superRegion) {
+template <typename RegionTy, typename SuperTy, typename Arg1Ty, typename Arg2Ty>
+RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+                                         const SuperTy *superRegion) {
   llvm::FoldingSetNodeID ID;
-  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
+  RegionTy::ProfileRegion(ID, arg1, arg2, superRegion);
   void *InsertPos;
   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
                                                                    InsertPos));
 
   if (!R) {
     R = A.Allocate<RegionTy>();
-    new (R) RegionTy(a1, a2, superRegion);
+    new (R) RegionTy(arg1, arg2, superRegion);
     Regions.InsertNode(R, InsertPos);
   }
 
   return R;
 }
 
-template <typename RegionTy, typename A1, typename A2, typename A3>
-RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
-                                         const MemRegion *superRegion) {
+template <typename RegionTy, typename SuperTy,
+          typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
+RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+                                         const Arg3Ty arg3,
+                                         const SuperTy *superRegion) {
   llvm::FoldingSetNodeID ID;
-  RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
+  RegionTy::ProfileRegion(ID, arg1, arg2, arg3, superRegion);
   void *InsertPos;
   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
                                                                    InsertPos));
 
   if (!R) {
     R = A.Allocate<RegionTy>();
-    new (R) RegionTy(a1, a2, a3, superRegion);
+    new (R) RegionTy(arg1, arg2, arg3, superRegion);
     Regions.InsertNode(R, InsertPos);
   }
 
@@ -180,8 +182,8 @@
                                 svalBuilder.getArrayIndexType());
 }
 
-ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
-  : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
+ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
+    : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
 
 const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
   return cast<ObjCIvarDecl>(D);
@@ -379,10 +381,8 @@
 //===----------------------------------------------------------------------===//
 
 void GlobalsSpaceRegion::anchor() { }
-void HeapSpaceRegion::anchor() { }
-void UnknownSpaceRegion::anchor() { }
-void StackLocalsSpaceRegion::anchor() { }
-void StackArgumentsSpaceRegion::anchor() { }
+void NonStaticGlobalSpaceRegion::anchor() { }
+void StackSpaceRegion::anchor() { }
 void TypedRegion::anchor() { }
 void TypedValueRegion::anchor() { }
 void CodeTextRegion::anchor() { }
@@ -737,12 +737,14 @@
 // Constructing regions.
 //===----------------------------------------------------------------------===//
 const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
-  return getSubRegion<StringRegion>(Str, getGlobalsRegion());
+  return getSubRegion<StringRegion>(
+      Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
 }
 
 const ObjCStringRegion *
 MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
-  return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
+  return getSubRegion<ObjCStringRegion>(
+      Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
 }
 
 /// Look through a chain of LocationContexts to either find the
@@ -871,7 +873,7 @@
 MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
                                      const LocationContext *LC,
                                      unsigned blockCount) {
-  const MemRegion *sReg = nullptr;
+  const MemSpaceRegion *sReg = nullptr;
   const BlockDecl *BD = BC->getDecl();
   if (!BD->hasCaptures()) {
     // This handles 'static' blocks.
@@ -904,7 +906,7 @@
 const CompoundLiteralRegion*
 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
                                            const LocationContext *LC) {
-  const MemRegion *sReg = nullptr;
+  const MemSpaceRegion *sReg = nullptr;
 
   if (CL->isFileScope())
     sReg = getGlobalsRegion();
@@ -919,7 +921,7 @@
 
 const ElementRegion*
 MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
-                                   const MemRegion* superRegion,
+                                   const SubRegion* superRegion,
                                    ASTContext &Ctx){
   QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
 
@@ -962,13 +964,13 @@
 
 const FieldRegion*
 MemRegionManager::getFieldRegion(const FieldDecl *d,
-                                 const MemRegion* superRegion){
+                                 const SubRegion* superRegion){
   return getSubRegion<FieldRegion>(d, superRegion);
 }
 
 const ObjCIvarRegion*
 MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
-                                    const MemRegion* superRegion) {
+                                    const SubRegion* superRegion) {
   return getSubRegion<ObjCIvarRegion>(d, superRegion);
 }
 
@@ -1004,7 +1006,7 @@
 
 const CXXBaseObjectRegion *
 MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
-                                         const MemRegion *Super,
+                                         const SubRegion *Super,
                                          bool IsVirtual) {
   if (isa<TypedValueRegion>(Super)) {
     assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual));
@@ -1015,7 +1017,7 @@
       // are different.
       while (const CXXBaseObjectRegion *Base =
                dyn_cast<CXXBaseObjectRegion>(Super)) {
-        Super = Base->getSuperRegion();
+        Super = cast<SubRegion>(Base->getSuperRegion());
       }
       assert(Super && !isa<MemSpaceRegion>(Super));
     }
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 03ace35..31556c7 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -111,24 +111,29 @@
   return ConstraintMgr->removeDeadBindings(Result, SymReaper);
 }
 
-ProgramStateRef ProgramState::bindLoc(Loc LV, SVal V, bool notifyChanges) const {
+ProgramStateRef ProgramState::bindLoc(Loc LV,
+                                      SVal V,
+                                      const LocationContext *LCtx,
+                                      bool notifyChanges) const {
   ProgramStateManager &Mgr = getStateManager();
   ProgramStateRef newState = makeWithStore(Mgr.StoreMgr->Bind(getStore(),
                                                              LV, V));
   const MemRegion *MR = LV.getAsRegion();
   if (MR && Mgr.getOwningEngine() && notifyChanges)
-    return Mgr.getOwningEngine()->processRegionChange(newState, MR);
+    return Mgr.getOwningEngine()->processRegionChange(newState, MR, LCtx);
 
   return newState;
 }
 
-ProgramStateRef ProgramState::bindDefault(SVal loc, SVal V) const {
+ProgramStateRef ProgramState::bindDefault(SVal loc,
+                                          SVal V,
+                                          const LocationContext *LCtx) const {
   ProgramStateManager &Mgr = getStateManager();
   const MemRegion *R = loc.castAs<loc::MemRegionVal>().getRegion();
   const StoreRef &newStore = Mgr.StoreMgr->BindDefault(getStore(), R, V);
   ProgramStateRef new_state = makeWithStore(newStore);
   return Mgr.getOwningEngine() ?
-           Mgr.getOwningEngine()->processRegionChange(new_state, R) :
+           Mgr.getOwningEngine()->processRegionChange(new_state, R, LCtx) :
            new_state;
 }
 
@@ -202,7 +207,7 @@
     }
 
     return Eng->processRegionChanges(newState, IS, TopLevelInvalidated,
-                                     Invalidated, Call);
+                                     Invalidated, LCtx, Call);
   }
 
   const StoreRef &newStore =
diff --git a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index 15073bb8..e0ad2d8 100644
--- a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -12,7 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "SimpleConstraintManager.h"
+#include "RangedConstraintManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
@@ -282,12 +282,31 @@
                                                              RangeSet))
 
 namespace {
-class RangeConstraintManager : public SimpleConstraintManager {
-  RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
-
+class RangeConstraintManager : public RangedConstraintManager {
 public:
   RangeConstraintManager(SubEngine *SE, SValBuilder &SVB)
-      : SimpleConstraintManager(SE, SVB) {}
+      : RangedConstraintManager(SE, SVB) {}
+
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from ConstraintManager.
+  //===------------------------------------------------------------------===//
+
+  bool canReasonAbout(SVal X) const override;
+
+  ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
+
+  const llvm::APSInt *getSymVal(ProgramStateRef State,
+                                SymbolRef Sym) const override;
+
+  ProgramStateRef removeDeadBindings(ProgramStateRef State,
+                                     SymbolReaper &SymReaper) override;
+
+  void print(ProgramStateRef State, raw_ostream &Out, const char *nl,
+             const char *sep) override;
+
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from RangedConstraintManager.
+  //===------------------------------------------------------------------===//
 
   ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
                               const llvm::APSInt &V,
@@ -313,26 +332,19 @@
                               const llvm::APSInt &V,
                               const llvm::APSInt &Adjustment) override;
 
-  ProgramStateRef assumeSymbolWithinInclusiveRange(
+  ProgramStateRef assumeSymWithinInclusiveRange(
       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
 
-  ProgramStateRef assumeSymbolOutOfInclusiveRange(
+  ProgramStateRef assumeSymOutsideInclusiveRange(
       ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
       const llvm::APSInt &To, const llvm::APSInt &Adjustment) override;
 
-  const llvm::APSInt *getSymVal(ProgramStateRef St,
-                                SymbolRef Sym) const override;
-  ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
-
-  ProgramStateRef removeDeadBindings(ProgramStateRef St,
-                                     SymbolReaper &SymReaper) override;
-
-  void print(ProgramStateRef St, raw_ostream &Out, const char *nl,
-             const char *sep) override;
-
 private:
   RangeSet::Factory F;
+
+  RangeSet getRange(ProgramStateRef State, SymbolRef Sym);
+
   RangeSet getSymLTRange(ProgramStateRef St, SymbolRef Sym,
                          const llvm::APSInt &Int,
                          const llvm::APSInt &Adjustment);
@@ -356,10 +368,46 @@
   return llvm::make_unique<RangeConstraintManager>(Eng, StMgr.getSValBuilder());
 }
 
-const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
-                                                      SymbolRef Sym) const {
-  const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(Sym);
-  return T ? T->getConcreteValue() : nullptr;
+bool RangeConstraintManager::canReasonAbout(SVal X) const {
+  Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
+  if (SymVal && SymVal->isExpression()) {
+    const SymExpr *SE = SymVal->getSymbol();
+
+    if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
+      switch (SIE->getOpcode()) {
+      // We don't reason yet about bitwise-constraints on symbolic values.
+      case BO_And:
+      case BO_Or:
+      case BO_Xor:
+        return false;
+      // We don't reason yet about these arithmetic constraints on
+      // symbolic values.
+      case BO_Mul:
+      case BO_Div:
+      case BO_Rem:
+      case BO_Shl:
+      case BO_Shr:
+        return false;
+      // All other cases.
+      default:
+        return true;
+      }
+    }
+
+    if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
+      if (BinaryOperator::isComparisonOp(SSE->getOpcode())) {
+        // We handle Loc <> Loc comparisons, but not (yet) NonLoc <> NonLoc.
+        if (Loc::isLocType(SSE->getLHS()->getType())) {
+          assert(Loc::isLocType(SSE->getRHS()->getType()));
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
+  return true;
 }
 
 ConditionTruthVal RangeConstraintManager::checkNull(ProgramStateRef State,
@@ -386,6 +434,12 @@
   return ConditionTruthVal();
 }
 
+const llvm::APSInt *RangeConstraintManager::getSymVal(ProgramStateRef St,
+                                                      SymbolRef Sym) const {
+  const ConstraintRangeTy::data_type *T = St->get<ConstraintRange>(Sym);
+  return T ? T->getConcreteValue() : nullptr;
+}
+
 /// Scan all symbols referenced by the constraints. If the symbol is not alive
 /// as marked in LSymbols, mark it as dead in DSymbols.
 ProgramStateRef
@@ -429,7 +483,7 @@
 }
 
 //===------------------------------------------------------------------------===
-// assumeSymX methods: public interface for RangeConstraintManager.
+// assumeSymX methods: protected interface for RangeConstraintManager.
 //===------------------------------------------------------------------------===/
 
 // The syntax for ranges below is mathematical, using [x, y] for closed ranges
@@ -646,7 +700,7 @@
   return New.isEmpty() ? nullptr : St->set<ConstraintRange>(Sym, New);
 }
 
-ProgramStateRef RangeConstraintManager::assumeSymbolWithinInclusiveRange(
+ProgramStateRef RangeConstraintManager::assumeSymWithinInclusiveRange(
     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
   RangeSet New = getSymGERange(State, Sym, From, Adjustment);
@@ -656,7 +710,7 @@
   return New.isEmpty() ? nullptr : State->set<ConstraintRange>(Sym, New);
 }
 
-ProgramStateRef RangeConstraintManager::assumeSymbolOutOfInclusiveRange(
+ProgramStateRef RangeConstraintManager::assumeSymOutsideInclusiveRange(
     ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
     const llvm::APSInt &To, const llvm::APSInt &Adjustment) {
   RangeSet RangeLT = getSymLTRange(State, Sym, From, Adjustment);
diff --git a/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
new file mode 100644
index 0000000..1304116
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/RangedConstraintManager.cpp
@@ -0,0 +1,204 @@
+//== RangedConstraintManager.cpp --------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines RangedConstraintManager, a class that provides a
+//  range-based constraint manager interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RangedConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+
+namespace clang {
+
+namespace ento {
+
+RangedConstraintManager::~RangedConstraintManager() {}
+
+ProgramStateRef RangedConstraintManager::assumeSym(ProgramStateRef State,
+                                                   SymbolRef Sym,
+                                                   bool Assumption) {
+  // Handle SymbolData.
+  if (isa<SymbolData>(Sym)) {
+    return assumeSymUnsupported(State, Sym, Assumption);
+
+    // Handle symbolic expression.
+  } else if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(Sym)) {
+    // We can only simplify expressions whose RHS is an integer.
+
+    BinaryOperator::Opcode op = SIE->getOpcode();
+    if (BinaryOperator::isComparisonOp(op)) {
+      if (!Assumption)
+        op = BinaryOperator::negateComparisonOp(op);
+
+      return assumeSymRel(State, SIE->getLHS(), op, SIE->getRHS());
+    }
+
+  } else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
+    // Translate "a != b" to "(b - a) != 0".
+    // We invert the order of the operands as a heuristic for how loop
+    // conditions are usually written ("begin != end") as compared to length
+    // calculations ("end - begin"). The more correct thing to do would be to
+    // canonicalize "a - b" and "b - a", which would allow us to treat
+    // "a != b" and "b != a" the same.
+    SymbolManager &SymMgr = getSymbolManager();
+    BinaryOperator::Opcode Op = SSE->getOpcode();
+    assert(BinaryOperator::isComparisonOp(Op));
+
+    // For now, we only support comparing pointers.
+    assert(Loc::isLocType(SSE->getLHS()->getType()));
+    assert(Loc::isLocType(SSE->getRHS()->getType()));
+    QualType DiffTy = SymMgr.getContext().getPointerDiffType();
+    SymbolRef Subtraction =
+        SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub, SSE->getLHS(), DiffTy);
+
+    const llvm::APSInt &Zero = getBasicVals().getValue(0, DiffTy);
+    Op = BinaryOperator::reverseComparisonOp(Op);
+    if (!Assumption)
+      Op = BinaryOperator::negateComparisonOp(Op);
+    return assumeSymRel(State, Subtraction, Op, Zero);
+  }
+
+  // If we get here, there's nothing else we can do but treat the symbol as
+  // opaque.
+  return assumeSymUnsupported(State, Sym, Assumption);
+}
+
+ProgramStateRef RangedConstraintManager::assumeSymInclusiveRange(
+    ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+    const llvm::APSInt &To, bool InRange) {
+  // Get the type used for calculating wraparound.
+  BasicValueFactory &BVF = getBasicVals();
+  APSIntType WraparoundType = BVF.getAPSIntType(Sym->getType());
+
+  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
+  SymbolRef AdjustedSym = Sym;
+  computeAdjustment(AdjustedSym, Adjustment);
+
+  // Convert the right-hand side integer as necessary.
+  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(From));
+  llvm::APSInt ConvertedFrom = ComparisonType.convert(From);
+  llvm::APSInt ConvertedTo = ComparisonType.convert(To);
+
+  // Prefer unsigned comparisons.
+  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
+      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
+    Adjustment.setIsSigned(false);
+
+  if (InRange)
+    return assumeSymWithinInclusiveRange(State, AdjustedSym, ConvertedFrom,
+                                         ConvertedTo, Adjustment);
+  return assumeSymOutsideInclusiveRange(State, AdjustedSym, ConvertedFrom,
+                                        ConvertedTo, Adjustment);
+}
+
+ProgramStateRef
+RangedConstraintManager::assumeSymUnsupported(ProgramStateRef State,
+                                              SymbolRef Sym, bool Assumption) {
+  BasicValueFactory &BVF = getBasicVals();
+  QualType T = Sym->getType();
+
+  // Non-integer types are not supported.
+  if (!T->isIntegralOrEnumerationType())
+    return State;
+
+  // Reverse the operation and add directly to state.
+  const llvm::APSInt &Zero = BVF.getValue(0, T);
+  if (Assumption)
+    return assumeSymNE(State, Sym, Zero, Zero);
+  else
+    return assumeSymEQ(State, Sym, Zero, Zero);
+}
+
+ProgramStateRef RangedConstraintManager::assumeSymRel(ProgramStateRef State,
+                                                      SymbolRef Sym,
+                                                      BinaryOperator::Opcode Op,
+                                                      const llvm::APSInt &Int) {
+  assert(BinaryOperator::isComparisonOp(Op) &&
+         "Non-comparison ops should be rewritten as comparisons to zero.");
+
+  // Simplification: translate an assume of a constraint of the form
+  // "(exp comparison_op expr) != 0" to true into an assume of
+  // "exp comparison_op expr" to true. (And similarly, an assume of the form
+  // "(exp comparison_op expr) == 0" to true into an assume of
+  // "exp comparison_op expr" to false.)
+  if (Int == 0 && (Op == BO_EQ || Op == BO_NE)) {
+    if (const BinarySymExpr *SE = dyn_cast<BinarySymExpr>(Sym))
+      if (BinaryOperator::isComparisonOp(SE->getOpcode()))
+        return assumeSym(State, Sym, (Op == BO_NE ? true : false));
+  }
+
+  // Get the type used for calculating wraparound.
+  BasicValueFactory &BVF = getBasicVals();
+  APSIntType WraparoundType = BVF.getAPSIntType(Sym->getType());
+
+  // We only handle simple comparisons of the form "$sym == constant"
+  // or "($sym+constant1) == constant2".
+  // The adjustment is "constant1" in the above expression. It's used to
+  // "slide" the solution range around for modular arithmetic. For example,
+  // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
+  // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
+  // the subclasses of SimpleConstraintManager to handle the adjustment.
+  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
+  computeAdjustment(Sym, Adjustment);
+
+  // Convert the right-hand side integer as necessary.
+  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(Int));
+  llvm::APSInt ConvertedInt = ComparisonType.convert(Int);
+
+  // Prefer unsigned comparisons.
+  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
+      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
+    Adjustment.setIsSigned(false);
+
+  switch (Op) {
+  default:
+    llvm_unreachable("invalid operation not caught by assertion above");
+
+  case BO_EQ:
+    return assumeSymEQ(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_NE:
+    return assumeSymNE(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_GT:
+    return assumeSymGT(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_GE:
+    return assumeSymGE(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_LT:
+    return assumeSymLT(State, Sym, ConvertedInt, Adjustment);
+
+  case BO_LE:
+    return assumeSymLE(State, Sym, ConvertedInt, Adjustment);
+  } // end switch
+}
+
+void RangedConstraintManager::computeAdjustment(SymbolRef &Sym,
+                                                llvm::APSInt &Adjustment) {
+  // Is it a "($sym+constant1)" expression?
+  if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(Sym)) {
+    BinaryOperator::Opcode Op = SE->getOpcode();
+    if (Op == BO_Add || Op == BO_Sub) {
+      Sym = SE->getLHS();
+      Adjustment = APSIntType(Adjustment).convert(SE->getRHS());
+
+      // Don't forget to negate the adjustment if it's being subtracted.
+      // This should happen /after/ promotion, in case the value being
+      // subtracted is, say, CHAR_MIN, and the promoted type is 'int'.
+      if (Op == BO_Sub)
+        Adjustment = -Adjustment;
+    }
+  }
+}
+
+} // end of namespace ento
+
+} // end of namespace clang
diff --git a/lib/StaticAnalyzer/Core/RangedConstraintManager.h b/lib/StaticAnalyzer/Core/RangedConstraintManager.h
new file mode 100644
index 0000000..a4e6062
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/RangedConstraintManager.h
@@ -0,0 +1,102 @@
+//== RangedConstraintManager.h ----------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  Ranged constraint manager, built on SimpleConstraintManager.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CORE_RANGEDCONSTRAINTMANAGER_H
+#define LLVM_CLANG_LIB_STATICANALYZER_CORE_RANGEDCONSTRAINTMANAGER_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h"
+
+namespace clang {
+
+namespace ento {
+
+class RangedConstraintManager : public SimpleConstraintManager {
+public:
+  RangedConstraintManager(SubEngine *SE, SValBuilder &SB)
+      : SimpleConstraintManager(SE, SB) {}
+
+  ~RangedConstraintManager() override;
+
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from SimpleConstraintManager.
+  //===------------------------------------------------------------------===//
+
+  ProgramStateRef assumeSym(ProgramStateRef State, SymbolRef Sym,
+                            bool Assumption) override;
+
+  ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State, SymbolRef Sym,
+                                          const llvm::APSInt &From,
+                                          const llvm::APSInt &To,
+                                          bool InRange) override;
+
+  ProgramStateRef assumeSymUnsupported(ProgramStateRef State, SymbolRef Sym,
+                                       bool Assumption) override;
+
+protected:
+  /// Assume a constraint between a symbolic expression and a concrete integer.
+  virtual ProgramStateRef assumeSymRel(ProgramStateRef State, SymbolRef Sym,
+                               BinaryOperator::Opcode op,
+                               const llvm::APSInt &Int);
+
+  //===------------------------------------------------------------------===//
+  // Interface that subclasses must implement.
+  //===------------------------------------------------------------------===//
+
+  // Each of these is of the form "$Sym+Adj <> V", where "<>" is the comparison
+  // operation for the method being invoked.
+
+  virtual ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymEQ(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymLT(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymGT(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymLE(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymGE(ProgramStateRef State, SymbolRef Sym,
+                                      const llvm::APSInt &V,
+                                      const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymWithinInclusiveRange(
+      ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+      const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
+
+  virtual ProgramStateRef assumeSymOutsideInclusiveRange(
+      ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+      const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
+
+  //===------------------------------------------------------------------===//
+  // Internal implementation.
+  //===------------------------------------------------------------------===//
+private:
+  static void computeAdjustment(SymbolRef &Sym, llvm::APSInt &Adjustment);
+};
+
+} // end GR namespace
+
+} // end clang namespace
+
+#endif
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index 934cc5c..dd7e9dd 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -494,6 +494,11 @@
     return getBinding(getRegionBindings(S), L, T);
   }
 
+  Optional<SVal> getDefaultBinding(Store S, const MemRegion *R) override {
+    RegionBindingsRef B = getRegionBindings(S);
+    return B.getDefaultBinding(R);
+  }
+
   SVal getBinding(RegionBindingsConstRef B, Loc L, QualType T = QualType());
 
   SVal getBindingForElement(RegionBindingsConstRef B, const ElementRegion *R);
@@ -1336,7 +1341,8 @@
   if (!Array.getAs<loc::MemRegionVal>())
     return UnknownVal();
 
-  const MemRegion* R = Array.castAs<loc::MemRegionVal>().getRegion();
+  const SubRegion *R =
+      cast<SubRegion>(Array.castAs<loc::MemRegionVal>().getRegion());
   NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
   return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, R, Ctx));
 }
@@ -1379,7 +1385,7 @@
         T = SR->getSymbol()->getType();
       }
     }
-    MR = GetElementZeroRegion(MR, T);
+    MR = GetElementZeroRegion(cast<SubRegion>(MR), T);
   }
 
   // FIXME: Perhaps this method should just take a 'const MemRegion*' argument
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
index 0e512ff..adb4017 100644
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleConstraintManager.cpp
@@ -7,12 +7,12 @@
 //
 //===----------------------------------------------------------------------===//
 //
-//  This file defines SimpleConstraintManager, a class that holds code shared
-//  between BasicConstraintManager and RangeConstraintManager.
+//  This file defines SimpleConstraintManager, a class that provides a
+//  simplified constraint manager interface, compared to ConstraintManager.
 //
 //===----------------------------------------------------------------------===//
 
-#include "SimpleConstraintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
@@ -23,48 +23,6 @@
 
 SimpleConstraintManager::~SimpleConstraintManager() {}
 
-bool SimpleConstraintManager::canReasonAbout(SVal X) const {
-  Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
-  if (SymVal && SymVal->isExpression()) {
-    const SymExpr *SE = SymVal->getSymbol();
-
-    if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
-      switch (SIE->getOpcode()) {
-      // We don't reason yet about bitwise-constraints on symbolic values.
-      case BO_And:
-      case BO_Or:
-      case BO_Xor:
-        return false;
-      // We don't reason yet about these arithmetic constraints on
-      // symbolic values.
-      case BO_Mul:
-      case BO_Div:
-      case BO_Rem:
-      case BO_Shl:
-      case BO_Shr:
-        return false;
-      // All other cases.
-      default:
-        return true;
-      }
-    }
-
-    if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
-      if (BinaryOperator::isComparisonOp(SSE->getOpcode())) {
-        // We handle Loc <> Loc comparisons, but not (yet) NonLoc <> NonLoc.
-        if (Loc::isLocType(SSE->getLHS()->getType())) {
-          assert(Loc::isLocType(SSE->getRHS()->getType()));
-          return true;
-        }
-      }
-    }
-
-    return false;
-  }
-
-  return true;
-}
-
 ProgramStateRef SimpleConstraintManager::assume(ProgramStateRef State,
                                                 DefinedSVal Cond,
                                                 bool Assumption) {
@@ -92,23 +50,6 @@
   return State;
 }
 
-ProgramStateRef
-SimpleConstraintManager::assumeAuxForSymbol(ProgramStateRef State,
-                                            SymbolRef Sym, bool Assumption) {
-  BasicValueFactory &BVF = getBasicVals();
-  QualType T = Sym->getType();
-
-  // None of the constraint solvers currently support non-integer types.
-  if (!T->isIntegralOrEnumerationType())
-    return State;
-
-  const llvm::APSInt &zero = BVF.getValue(0, T);
-  if (Assumption)
-    return assumeSymNE(State, Sym, zero, zero);
-  else
-    return assumeSymEQ(State, Sym, zero, zero);
-}
-
 ProgramStateRef SimpleConstraintManager::assumeAux(ProgramStateRef State,
                                                    NonLoc Cond,
                                                    bool Assumption) {
@@ -118,7 +59,8 @@
   if (!canReasonAbout(Cond)) {
     // Just add the constraint to the expression without trying to simplify.
     SymbolRef Sym = Cond.getAsSymExpr();
-    return assumeAuxForSymbol(State, Sym, Assumption);
+    assert(Sym);
+    return assumeSymUnsupported(State, Sym, Assumption);
   }
 
   switch (Cond.getSubKind()) {
@@ -129,51 +71,7 @@
     nonloc::SymbolVal SV = Cond.castAs<nonloc::SymbolVal>();
     SymbolRef Sym = SV.getSymbol();
     assert(Sym);
-
-    // Handle SymbolData.
-    if (!SV.isExpression()) {
-      return assumeAuxForSymbol(State, Sym, Assumption);
-
-      // Handle symbolic expression.
-    } else if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(Sym)) {
-      // We can only simplify expressions whose RHS is an integer.
-
-      BinaryOperator::Opcode Op = SE->getOpcode();
-      if (BinaryOperator::isComparisonOp(Op)) {
-        if (!Assumption)
-          Op = BinaryOperator::negateComparisonOp(Op);
-
-        return assumeSymRel(State, SE->getLHS(), Op, SE->getRHS());
-      }
-
-    } else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(Sym)) {
-      // Translate "a != b" to "(b - a) != 0".
-      // We invert the order of the operands as a heuristic for how loop
-      // conditions are usually written ("begin != end") as compared to length
-      // calculations ("end - begin"). The more correct thing to do would be to
-      // canonicalize "a - b" and "b - a", which would allow us to treat
-      // "a != b" and "b != a" the same.
-      SymbolManager &SymMgr = getSymbolManager();
-      BinaryOperator::Opcode Op = SSE->getOpcode();
-      assert(BinaryOperator::isComparisonOp(Op));
-
-      // For now, we only support comparing pointers.
-      assert(Loc::isLocType(SSE->getLHS()->getType()));
-      assert(Loc::isLocType(SSE->getRHS()->getType()));
-      QualType DiffTy = SymMgr.getContext().getPointerDiffType();
-      SymbolRef Subtraction =
-          SymMgr.getSymSymExpr(SSE->getRHS(), BO_Sub, SSE->getLHS(), DiffTy);
-
-      const llvm::APSInt &Zero = getBasicVals().getValue(0, DiffTy);
-      Op = BinaryOperator::reverseComparisonOp(Op);
-      if (!Assumption)
-        Op = BinaryOperator::negateComparisonOp(Op);
-      return assumeSymRel(State, Subtraction, Op, Zero);
-    }
-
-    // If we get here, there's nothing else we can do but treat the symbol as
-    // opaque.
-    return assumeAuxForSymbol(State, Sym, Assumption);
+    return assumeSym(State, Sym, Assumption);
   }
 
   case nonloc::ConcreteIntKind: {
@@ -206,7 +104,7 @@
     // Just add the constraint to the expression without trying to simplify.
     SymbolRef Sym = Value.getAsSymExpr();
     assert(Sym);
-    return assumeSymWithinInclusiveRange(State, Sym, From, To, InRange);
+    return assumeSymInclusiveRange(State, Sym, From, To, InRange);
   }
 
   switch (Value.getSubKind()) {
@@ -217,7 +115,7 @@
   case nonloc::LocAsIntegerKind:
   case nonloc::SymbolValKind: {
     if (SymbolRef Sym = Value.getAsSymbol())
-      return assumeSymWithinInclusiveRange(State, Sym, From, To, InRange);
+      return assumeSymInclusiveRange(State, Sym, From, To, InRange);
     return State;
   } // end switch
 
@@ -230,118 +128,6 @@
   } // end switch
 }
 
-static void computeAdjustment(SymbolRef &Sym, llvm::APSInt &Adjustment) {
-  // Is it a "($sym+constant1)" expression?
-  if (const SymIntExpr *SE = dyn_cast<SymIntExpr>(Sym)) {
-    BinaryOperator::Opcode Op = SE->getOpcode();
-    if (Op == BO_Add || Op == BO_Sub) {
-      Sym = SE->getLHS();
-      Adjustment = APSIntType(Adjustment).convert(SE->getRHS());
-
-      // Don't forget to negate the adjustment if it's being subtracted.
-      // This should happen /after/ promotion, in case the value being
-      // subtracted is, say, CHAR_MIN, and the promoted type is 'int'.
-      if (Op == BO_Sub)
-        Adjustment = -Adjustment;
-    }
-  }
-}
-
-ProgramStateRef SimpleConstraintManager::assumeSymRel(ProgramStateRef State,
-                                                      const SymExpr *LHS,
-                                                      BinaryOperator::Opcode Op,
-                                                      const llvm::APSInt &Int) {
-  assert(BinaryOperator::isComparisonOp(Op) &&
-         "Non-comparison ops should be rewritten as comparisons to zero.");
-
-  SymbolRef Sym = LHS;
-
-  // Simplification: translate an assume of a constraint of the form
-  // "(exp comparison_op expr) != 0" to true into an assume of 
-  // "exp comparison_op expr" to true. (And similarly, an assume of the form
-  // "(exp comparison_op expr) == 0" to true into an assume of
-  // "exp comparison_op expr" to false.)
-  if (Int == 0 && (Op == BO_EQ || Op == BO_NE)) {
-    if (const BinarySymExpr *SE = dyn_cast<BinarySymExpr>(Sym))
-      if (BinaryOperator::isComparisonOp(SE->getOpcode()))
-        return assume(State, nonloc::SymbolVal(Sym), (Op == BO_NE ? true : false));
-  }
-
-  // Get the type used for calculating wraparound.
-  BasicValueFactory &BVF = getBasicVals();
-  APSIntType WraparoundType = BVF.getAPSIntType(LHS->getType());
-
-  // We only handle simple comparisons of the form "$sym == constant"
-  // or "($sym+constant1) == constant2".
-  // The adjustment is "constant1" in the above expression. It's used to
-  // "slide" the solution range around for modular arithmetic. For example,
-  // x < 4 has the solution [0, 3]. x+2 < 4 has the solution [0-2, 3-2], which
-  // in modular arithmetic is [0, 1] U [UINT_MAX-1, UINT_MAX]. It's up to
-  // the subclasses of SimpleConstraintManager to handle the adjustment.
-  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
-  computeAdjustment(Sym, Adjustment);
-
-  // Convert the right-hand side integer as necessary.
-  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(Int));
-  llvm::APSInt ConvertedInt = ComparisonType.convert(Int);
-
-  // Prefer unsigned comparisons.
-  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
-      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
-    Adjustment.setIsSigned(false);
-
-  switch (Op) {
-  default:
-    llvm_unreachable("invalid operation not caught by assertion above");
-
-  case BO_EQ:
-    return assumeSymEQ(State, Sym, ConvertedInt, Adjustment);
-
-  case BO_NE:
-    return assumeSymNE(State, Sym, ConvertedInt, Adjustment);
-
-  case BO_GT:
-    return assumeSymGT(State, Sym, ConvertedInt, Adjustment);
-
-  case BO_GE:
-    return assumeSymGE(State, Sym, ConvertedInt, Adjustment);
-
-  case BO_LT:
-    return assumeSymLT(State, Sym, ConvertedInt, Adjustment);
-
-  case BO_LE:
-    return assumeSymLE(State, Sym, ConvertedInt, Adjustment);
-  } // end switch
-}
-
-ProgramStateRef SimpleConstraintManager::assumeSymWithinInclusiveRange(
-    ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
-    const llvm::APSInt &To, bool InRange) {
-  // Get the type used for calculating wraparound.
-  BasicValueFactory &BVF = getBasicVals();
-  APSIntType WraparoundType = BVF.getAPSIntType(Sym->getType());
-
-  llvm::APSInt Adjustment = WraparoundType.getZeroValue();
-  SymbolRef AdjustedSym = Sym;
-  computeAdjustment(AdjustedSym, Adjustment);
-
-  // Convert the right-hand side integer as necessary.
-  APSIntType ComparisonType = std::max(WraparoundType, APSIntType(From));
-  llvm::APSInt ConvertedFrom = ComparisonType.convert(From);
-  llvm::APSInt ConvertedTo = ComparisonType.convert(To);
-
-  // Prefer unsigned comparisons.
-  if (ComparisonType.getBitWidth() == WraparoundType.getBitWidth() &&
-      ComparisonType.isUnsigned() && !WraparoundType.isUnsigned())
-    Adjustment.setIsSigned(false);
-
-  if (InRange)
-    return assumeSymbolWithinInclusiveRange(State, AdjustedSym, ConvertedFrom,
-                                            ConvertedTo, Adjustment);
-  return assumeSymbolOutOfInclusiveRange(State, AdjustedSym, ConvertedFrom,
-                                         ConvertedTo, Adjustment);
-}
-
 } // end of namespace ento
 
 } // end of namespace clang
diff --git a/lib/StaticAnalyzer/Core/SimpleConstraintManager.h b/lib/StaticAnalyzer/Core/SimpleConstraintManager.h
deleted file mode 100644
index 1128e77..0000000
--- a/lib/StaticAnalyzer/Core/SimpleConstraintManager.h
+++ /dev/null
@@ -1,115 +0,0 @@
-//== SimpleConstraintManager.h ----------------------------------*- C++ -*--==//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  Code shared between BasicConstraintManager and RangeConstraintManager.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_STATICANALYZER_CORE_SIMPLECONSTRAINTMANAGER_H
-#define LLVM_CLANG_LIB_STATICANALYZER_CORE_SIMPLECONSTRAINTMANAGER_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-
-namespace clang {
-
-namespace ento {
-
-class SimpleConstraintManager : public ConstraintManager {
-  SubEngine *SU;
-  SValBuilder &SVB;
-
-public:
-  SimpleConstraintManager(SubEngine *SE, SValBuilder &SB) : SU(SE), SVB(SB) {}
-  ~SimpleConstraintManager() override;
-
-  //===------------------------------------------------------------------===//
-  // Common implementation for the interface provided by ConstraintManager.
-  //===------------------------------------------------------------------===//
-
-  ProgramStateRef assume(ProgramStateRef State, DefinedSVal Cond,
-                         bool Assumption) override;
-
-  ProgramStateRef assume(ProgramStateRef State, NonLoc Cond, bool Assumption);
-
-  ProgramStateRef assumeInclusiveRange(ProgramStateRef State, NonLoc Value,
-                                       const llvm::APSInt &From,
-                                       const llvm::APSInt &To,
-                                       bool InRange) override;
-
-  ProgramStateRef assumeSymRel(ProgramStateRef State, const SymExpr *LHS,
-                               BinaryOperator::Opcode Op,
-                               const llvm::APSInt &Int);
-
-  ProgramStateRef assumeSymWithinInclusiveRange(ProgramStateRef State,
-                                                SymbolRef Sym,
-                                                const llvm::APSInt &From,
-                                                const llvm::APSInt &To,
-                                                bool InRange);
-
-protected:
-  //===------------------------------------------------------------------===//
-  // Interface that subclasses must implement.
-  //===------------------------------------------------------------------===//
-
-  // Each of these is of the form "$Sym+Adj <> V", where "<>" is the comparison
-  // operation for the method being invoked.
-  virtual ProgramStateRef assumeSymNE(ProgramStateRef State, SymbolRef Sym,
-                                      const llvm::APSInt &V,
-                                      const llvm::APSInt &Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymEQ(ProgramStateRef State, SymbolRef Sym,
-                                      const llvm::APSInt &V,
-                                      const llvm::APSInt &Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymLT(ProgramStateRef State, SymbolRef Sym,
-                                      const llvm::APSInt &V,
-                                      const llvm::APSInt &Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymGT(ProgramStateRef State, SymbolRef Sym,
-                                      const llvm::APSInt &V,
-                                      const llvm::APSInt &Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymLE(ProgramStateRef State, SymbolRef Sym,
-                                      const llvm::APSInt &V,
-                                      const llvm::APSInt &Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymGE(ProgramStateRef State, SymbolRef Sym,
-                                      const llvm::APSInt &V,
-                                      const llvm::APSInt &Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymbolWithinInclusiveRange(
-      ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
-      const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
-
-  virtual ProgramStateRef assumeSymbolOutOfInclusiveRange(
-      ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
-      const llvm::APSInt &To, const llvm::APSInt &Adjustment) = 0;
-
-  //===------------------------------------------------------------------===//
-  // Internal implementation.
-  //===------------------------------------------------------------------===//
-
-  BasicValueFactory &getBasicVals() const { return SVB.getBasicValueFactory(); }
-  SymbolManager &getSymbolManager() const { return SVB.getSymbolManager(); }
-
-  bool canReasonAbout(SVal X) const override;
-
-  ProgramStateRef assumeAux(ProgramStateRef State, NonLoc Cond,
-                            bool Assumption);
-
-  ProgramStateRef assumeAuxForSymbol(ProgramStateRef State, SymbolRef Sym,
-                                     bool Assumption);
-};
-
-} // end GR namespace
-
-} // end clang namespace
-
-#endif
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index 28b43dd..82ce8b4 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -14,6 +14,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h"
 
 using namespace clang;
 using namespace ento;
@@ -44,6 +45,10 @@
   ///  (integer) value, that value is returned. Otherwise, returns NULL.
   const llvm::APSInt *getKnownValue(ProgramStateRef state, SVal V) override;
 
+  /// Recursively descends into symbolic expressions and replaces symbols
+  /// with their known values (in the sense of the getKnownValue() method).
+  SVal simplifySVal(ProgramStateRef State, SVal V) override;
+
   SVal MakeSymIntVal(const SymExpr *LHS, BinaryOperator::Opcode op,
                      const llvm::APSInt &RHS, QualType resultTy);
 };
@@ -362,6 +367,9 @@
                              resultTy);
         case nonloc::ConcreteIntKind: {
           // Transform the integer into a location and compare.
+          // FIXME: This only makes sense for comparisons. If we want to, say,
+          // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,
+          // then pack it back into a LocAsInteger.
           llvm::APSInt i = rhs.castAs<nonloc::ConcreteInt>().getValue();
           BasicVals.getAPSIntType(Context.VoidPtrTy).apply(i);
           return evalBinOpLL(state, op, lhsL, makeLoc(i), resultTy);
@@ -534,11 +542,12 @@
       // Does the symbolic expression simplify to a constant?
       // If so, "fold" the constant by setting 'lhs' to a ConcreteInt
       // and try again.
-      ConstraintManager &CMgr = state->getConstraintManager();
-      if (const llvm::APSInt *Constant = CMgr.getSymVal(state, Sym)) {
-        lhs = nonloc::ConcreteInt(*Constant);
-        continue;
-      }
+      SVal simplifiedLhs = simplifySVal(state, lhs);
+      if (simplifiedLhs != lhs)
+        if (auto simplifiedLhsAsNonLoc = simplifiedLhs.getAs<NonLoc>()) {
+          lhs = *simplifiedLhsAsNonLoc;
+          continue;
+        }
 
       // Is the RHS a constant?
       if (const llvm::APSInt *RHSValue = getKnownValue(state, rhs))
@@ -941,20 +950,26 @@
   if (const MemRegion *region = lhs.getAsRegion()) {
     rhs = convertToArrayIndex(rhs).castAs<NonLoc>();
     SVal index = UnknownVal();
-    const MemRegion *superR = nullptr;
+    const SubRegion *superR = nullptr;
+    // We need to know the type of the pointer in order to add an integer to it.
+    // Depending on the type, different amount of bytes is added.
     QualType elementType;
 
     if (const ElementRegion *elemReg = dyn_cast<ElementRegion>(region)) {
       assert(op == BO_Add || op == BO_Sub);
       index = evalBinOpNN(state, op, elemReg->getIndex(), rhs,
                           getArrayIndexType());
-      superR = elemReg->getSuperRegion();
+      superR = cast<SubRegion>(elemReg->getSuperRegion());
       elementType = elemReg->getElementType();
     }
     else if (isa<SubRegion>(region)) {
       assert(op == BO_Add || op == BO_Sub);
       index = (op == BO_Add) ? rhs : evalMinus(rhs);
-      superR = region;
+      superR = cast<SubRegion>(region);
+      // TODO: Is this actually reliable? Maybe improving our MemRegion
+      // hierarchy to provide typed regions for all non-void pointers would be
+      // better. For instance, we cannot extend this towards LocAsInteger
+      // operations, where result type of the expression is integer.
       if (resultTy->isAnyPointerType())
         elementType = resultTy->getPointeeType();
     }
@@ -984,3 +999,74 @@
   // FIXME: Add support for SymExprs.
   return nullptr;
 }
+
+SVal SimpleSValBuilder::simplifySVal(ProgramStateRef State, SVal V) {
+  // For now, this function tries to constant-fold symbols inside a
+  // nonloc::SymbolVal, and does nothing else. More simplifications should
+  // be possible, such as constant-folding an index in an ElementRegion.
+
+  class Simplifier : public FullSValVisitor<Simplifier, SVal> {
+    ProgramStateRef State;
+    SValBuilder &SVB;
+
+  public:
+    Simplifier(ProgramStateRef State)
+        : State(State), SVB(State->getStateManager().getSValBuilder()) {}
+
+    SVal VisitSymbolData(const SymbolData *S) {
+      if (const llvm::APSInt *I =
+              SVB.getKnownValue(State, nonloc::SymbolVal(S)))
+        return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
+                                            : (SVal)SVB.makeIntVal(*I);
+      return nonloc::SymbolVal(S);
+    }
+
+    // TODO: Support SymbolCast. Support IntSymExpr when/if we actually
+    // start producing them.
+
+    SVal VisitSymIntExpr(const SymIntExpr *S) {
+      SVal LHS = Visit(S->getLHS());
+      SVal RHS;
+      // By looking at the APSInt in the right-hand side of S, we cannot
+      // figure out if it should be treated as a Loc or as a NonLoc.
+      // So make our guess by recalling that we cannot multiply pointers
+      // or compare a pointer to an integer.
+      if (Loc::isLocType(S->getLHS()->getType()) &&
+          BinaryOperator::isComparisonOp(S->getOpcode())) {
+        // The usual conversion of $sym to &SymRegion{$sym}, as they have
+        // the same meaning for Loc-type symbols, but the latter form
+        // is preferred in SVal computations for being Loc itself.
+        if (SymbolRef Sym = LHS.getAsSymbol()) {
+          assert(Loc::isLocType(Sym->getType()));
+          LHS = SVB.makeLoc(Sym);
+        }
+        RHS = SVB.makeIntLocVal(S->getRHS());
+      } else {
+        RHS = SVB.makeIntVal(S->getRHS());
+      }
+      return SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType());
+    }
+
+    SVal VisitSymSymExpr(const SymSymExpr *S) {
+      SVal LHS = Visit(S->getLHS());
+      SVal RHS = Visit(S->getRHS());
+      return SVB.evalBinOp(State, S->getOpcode(), LHS, RHS, S->getType());
+    }
+
+    SVal VisitSymExpr(SymbolRef S) { return nonloc::SymbolVal(S); }
+
+    SVal VisitMemRegion(const MemRegion *R) { return loc::MemRegionVal(R); }
+
+    SVal VisitNonLocSymbolVal(nonloc::SymbolVal V) {
+      // Simplification is much more costly than computing complexity.
+      // For high complexity, it may be not worth it.
+      if (V.getSymbol()->computeComplexity() > 100)
+        return V;
+      return Visit(V.getSymbol());
+    }
+
+    SVal VisitSVal(SVal V) { return V; }
+  };
+
+  return Simplifier(State).Visit(V);
+}
diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp
index aca6e3b..1af49f6 100644
--- a/lib/StaticAnalyzer/Core/Store.cpp
+++ b/lib/StaticAnalyzer/Core/Store.cpp
@@ -42,8 +42,9 @@
   return Store;
 }
 
-const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base,
-                                              QualType EleTy, uint64_t index) {
+const ElementRegion *StoreManager::MakeElementRegion(const SubRegion *Base,
+                                                     QualType EleTy,
+                                                     uint64_t index) {
   NonLoc idx = svalBuilder.makeArrayIndex(index);
   return MRMgr.getElementRegion(EleTy, idx, Base, svalBuilder.getContext());
 }
@@ -52,7 +53,7 @@
   return StoreRef(store, *this);
 }
 
-const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R,
+const ElementRegion *StoreManager::GetElementZeroRegion(const SubRegion *R,
                                                         QualType T) {
   NonLoc idx = svalBuilder.makeZeroArrayIndex();
   assert(!T.isNull());
@@ -126,7 +127,7 @@
     case MemRegion::VarRegionKind:
     case MemRegion::CXXTempObjectRegionKind:
     case MemRegion::CXXBaseObjectRegionKind:
-      return MakeElementRegion(R, PointeeTy);
+      return MakeElementRegion(cast<SubRegion>(R), PointeeTy);
 
     case MemRegion::ElementRegionKind: {
       // If we are casting from an ElementRegion to another type, the
@@ -171,7 +172,7 @@
         }
 
         // Otherwise, create a new ElementRegion at offset 0.
-        return MakeElementRegion(baseR, PointeeTy);
+        return MakeElementRegion(cast<SubRegion>(baseR), PointeeTy);
       }
 
       // We have a non-zero offset from the base region.  We want to determine
@@ -202,10 +203,11 @@
       if (!newSuperR) {
         // Create an intermediate ElementRegion to represent the raw byte.
         // This will be the super region of the final ElementRegion.
-        newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off.getQuantity());
+        newSuperR = MakeElementRegion(cast<SubRegion>(baseR), Ctx.CharTy,
+                                      off.getQuantity());
       }
 
-      return MakeElementRegion(newSuperR, PointeeTy, newIndex);
+      return MakeElementRegion(cast<SubRegion>(newSuperR), PointeeTy, newIndex);
     }
   }
 
@@ -271,9 +273,8 @@
     BaseDecl = BaseType->getAsCXXRecordDecl();
   assert(BaseDecl && "not a C++ object?");
 
-  const MemRegion *BaseReg =
-    MRMgr.getCXXBaseObjectRegion(BaseDecl, DerivedRegVal->getRegion(),
-                                 IsVirtual);
+  const MemRegion *BaseReg = MRMgr.getCXXBaseObjectRegion(
+      BaseDecl, cast<SubRegion>(DerivedRegVal->getRegion()), IsVirtual);
 
   return loc::MemRegionVal(BaseReg);
 }
@@ -390,11 +391,11 @@
     return Base;
 
   Loc BaseL = Base.castAs<Loc>();
-  const MemRegion* BaseR = nullptr;
+  const SubRegion* BaseR = nullptr;
 
   switch (BaseL.getSubKind()) {
   case loc::MemRegionValKind:
-    BaseR = BaseL.castAs<loc::MemRegionVal>().getRegion();
+    BaseR = cast<SubRegion>(BaseL.castAs<loc::MemRegionVal>().getRegion());
     break;
 
   case loc::GotoLabelKind:
@@ -403,9 +404,15 @@
 
   case loc::ConcreteIntKind:
     // While these seem funny, this can happen through casts.
-    // FIXME: What we should return is the field offset.  For example,
-    //  add the field offset to the integer value.  That way funny things
+    // FIXME: What we should return is the field offset, not base. For example,
+    //  add the field offset to the integer value.  That way things
     //  like this work properly:  &(((struct foo *) 0xa)->f)
+    //  However, that's not easy to fix without reducing our abilities
+    //  to catch null pointer dereference. Eg., ((struct foo *)0x0)->f = 7
+    //  is a null dereference even though we're dereferencing offset of f
+    //  rather than null. Coming up with an approach that computes offsets
+    //  over null pointers properly while still being able to catch null
+    //  dereferences might be worth it.
     return Base;
 
   default:
@@ -430,11 +437,12 @@
   // If the base is an unknown or undefined value, just return it back.
   // FIXME: For absolute pointer addresses, we just return that value back as
   //  well, although in reality we should return the offset added to that
-  //  value.
+  //  value. See also the similar FIXME in getLValueFieldOrIvar().
   if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>())
     return Base;
 
-  const MemRegion* BaseRegion = Base.castAs<loc::MemRegionVal>().getRegion();
+  const SubRegion *BaseRegion =
+      Base.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>();
 
   // Pointer of any type can be cast and used as array base.
   const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
@@ -471,9 +479,8 @@
     if (isa<ElementRegion>(BaseRegion->StripCasts()))
       return UnknownVal();
 
-    return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
-                                                    ElemR->getSuperRegion(),
-                                                    Ctx));
+    return loc::MemRegionVal(MRMgr.getElementRegion(
+        elementType, Offset, cast<SubRegion>(ElemR->getSuperRegion()), Ctx));
   }
 
   const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();
@@ -484,7 +491,7 @@
                                                                     OffI));
 
   // Construct the new ElementRegion.
-  const MemRegion *ArrayR = ElemR->getSuperRegion();
+  const SubRegion *ArrayR = cast<SubRegion>(ElemR->getSuperRegion());
   return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
                                                   Ctx));
 }
diff --git a/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp b/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
new file mode 100644
index 0000000..f9f9057
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/Z3ConstraintManager.cpp
@@ -0,0 +1,1618 @@
+//== Z3ConstraintManager.cpp --------------------------------*- C++ -*--==//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/TargetInfo.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SimpleConstraintManager.h"
+
+#include "clang/Config/config.h"
+
+using namespace clang;
+using namespace ento;
+
+#if CLANG_ANALYZER_WITH_Z3
+
+#include <z3.h>
+
+// Forward declarations
+namespace {
+class Z3Expr;
+class ConstraintZ3 {};
+} // end anonymous namespace
+
+typedef llvm::ImmutableSet<std::pair<SymbolRef, Z3Expr>> ConstraintZ3Ty;
+
+// Expansion of REGISTER_TRAIT_WITH_PROGRAMSTATE(ConstraintZ3, Z3SetPair)
+namespace clang {
+namespace ento {
+template <>
+struct ProgramStateTrait<ConstraintZ3>
+    : public ProgramStatePartialTrait<ConstraintZ3Ty> {
+  static void *GDMIndex() {
+    static int Index;
+    return &Index;
+  }
+};
+} // end namespace ento
+} // end namespace clang
+
+namespace {
+
+class Z3Config {
+  friend class Z3Context;
+
+  Z3_config Config;
+
+public:
+  Z3Config() : Config(Z3_mk_config()) {
+    // Enable model finding
+    Z3_set_param_value(Config, "model", "true");
+    // Disable proof generation
+    Z3_set_param_value(Config, "proof", "false");
+    // Set timeout to 15000ms = 15s
+    Z3_set_param_value(Config, "timeout", "15000");
+  }
+
+  ~Z3Config() { Z3_del_config(Config); }
+}; // end class Z3Config
+
+class Z3Context {
+  Z3_context ZC_P;
+
+public:
+  static Z3_context ZC;
+
+  Z3Context() : ZC_P(Z3_mk_context_rc(Z3Config().Config)) { ZC = ZC_P; }
+
+  ~Z3Context() {
+    Z3_del_context(ZC);
+    Z3_finalize_memory();
+    ZC_P = nullptr;
+  }
+}; // end class Z3Context
+
+class Z3Sort {
+  friend class Z3Expr;
+
+  Z3_sort Sort;
+
+  Z3Sort() : Sort(nullptr) {}
+  Z3Sort(Z3_sort ZS) : Sort(ZS) {
+    Z3_inc_ref(Z3Context::ZC, reinterpret_cast<Z3_ast>(Sort));
+  }
+
+public:
+  /// Override implicit copy constructor for correct reference counting.
+  Z3Sort(const Z3Sort &Copy) : Sort(Copy.Sort) {
+    Z3_inc_ref(Z3Context::ZC, reinterpret_cast<Z3_ast>(Sort));
+  }
+
+  /// Provide move constructor
+  Z3Sort(Z3Sort &&Move) : Sort(nullptr) { *this = std::move(Move); }
+
+  /// Provide move assignment constructor
+  Z3Sort &operator=(Z3Sort &&Move) {
+    if (this != &Move) {
+      if (Sort)
+        Z3_dec_ref(Z3Context::ZC, reinterpret_cast<Z3_ast>(Sort));
+      Sort = Move.Sort;
+      Move.Sort = nullptr;
+    }
+    return *this;
+  }
+
+  ~Z3Sort() {
+    if (Sort)
+      Z3_dec_ref(Z3Context::ZC, reinterpret_cast<Z3_ast>(Sort));
+  }
+
+  // Return a boolean sort.
+  static Z3Sort getBoolSort() { return Z3Sort(Z3_mk_bool_sort(Z3Context::ZC)); }
+
+  // Return an appropriate bitvector sort for the given bitwidth.
+  static Z3Sort getBitvectorSort(unsigned BitWidth) {
+    return Z3Sort(Z3_mk_bv_sort(Z3Context::ZC, BitWidth));
+  }
+
+  // Return an appropriate floating-point sort for the given bitwidth.
+  static Z3Sort getFloatSort(unsigned BitWidth) {
+    Z3_sort Sort;
+
+    switch (BitWidth) {
+    default:
+      llvm_unreachable("Unsupported floating-point bitwidth!");
+      break;
+    case 16:
+      Sort = Z3_mk_fpa_sort_16(Z3Context::ZC);
+      break;
+    case 32:
+      Sort = Z3_mk_fpa_sort_32(Z3Context::ZC);
+      break;
+    case 64:
+      Sort = Z3_mk_fpa_sort_64(Z3Context::ZC);
+      break;
+    case 128:
+      Sort = Z3_mk_fpa_sort_128(Z3Context::ZC);
+      break;
+    }
+    return Z3Sort(Sort);
+  }
+
+  // Return an appropriate sort for the given AST.
+  static Z3Sort getSort(Z3_ast AST) {
+    return Z3Sort(Z3_get_sort(Z3Context::ZC, AST));
+  }
+
+  Z3_sort_kind getSortKind() const {
+    return Z3_get_sort_kind(Z3Context::ZC, Sort);
+  }
+
+  unsigned getBitvectorSortSize() const {
+    assert(getSortKind() == Z3_BV_SORT && "Not a bitvector sort!");
+    return Z3_get_bv_sort_size(Z3Context::ZC, Sort);
+  }
+
+  unsigned getFloatSortSize() const {
+    assert(getSortKind() == Z3_FLOATING_POINT_SORT &&
+           "Not a floating-point sort!");
+    return Z3_fpa_get_ebits(Z3Context::ZC, Sort) +
+           Z3_fpa_get_sbits(Z3Context::ZC, Sort);
+  }
+
+  bool operator==(const Z3Sort &Other) const {
+    return Z3_is_eq_sort(Z3Context::ZC, Sort, Other.Sort);
+  }
+
+  Z3Sort &operator=(const Z3Sort &Move) {
+    Z3_inc_ref(Z3Context::ZC, reinterpret_cast<Z3_ast>(Move.Sort));
+    Z3_dec_ref(Z3Context::ZC, reinterpret_cast<Z3_ast>(Sort));
+    Sort = Move.Sort;
+    return *this;
+  }
+
+  void print(raw_ostream &OS) const {
+    OS << Z3_sort_to_string(Z3Context::ZC, Sort);
+  }
+
+  LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
+}; // end class Z3Sort
+
+class Z3Expr {
+  friend class Z3Model;
+  friend class Z3Solver;
+
+  Z3_ast AST;
+
+  Z3Expr(Z3_ast ZA) : AST(ZA) { Z3_inc_ref(Z3Context::ZC, AST); }
+
+  // Return an appropriate floating-point rounding mode.
+  static Z3Expr getFloatRoundingMode() {
+    // TODO: Don't assume nearest ties to even rounding mode
+    return Z3Expr(Z3_mk_fpa_rne(Z3Context::ZC));
+  }
+
+  // Determine whether two float semantics are equivalent
+  static bool areEquivalent(const llvm::fltSemantics &LHS,
+                            const llvm::fltSemantics &RHS) {
+    return (llvm::APFloat::semanticsPrecision(LHS) ==
+            llvm::APFloat::semanticsPrecision(RHS)) &&
+           (llvm::APFloat::semanticsMinExponent(LHS) ==
+            llvm::APFloat::semanticsMinExponent(RHS)) &&
+           (llvm::APFloat::semanticsMaxExponent(LHS) ==
+            llvm::APFloat::semanticsMaxExponent(RHS)) &&
+           (llvm::APFloat::semanticsSizeInBits(LHS) ==
+            llvm::APFloat::semanticsSizeInBits(RHS));
+  }
+
+public:
+  /// Override implicit copy constructor for correct reference counting.
+  Z3Expr(const Z3Expr &Copy) : AST(Copy.AST) { Z3_inc_ref(Z3Context::ZC, AST); }
+
+  /// Provide move constructor
+  Z3Expr(Z3Expr &&Move) : AST(nullptr) { *this = std::move(Move); }
+
+  /// Provide move assignment constructor
+  Z3Expr &operator=(Z3Expr &&Move) {
+    if (this != &Move) {
+      if (AST)
+        Z3_dec_ref(Z3Context::ZC, AST);
+      AST = Move.AST;
+      Move.AST = nullptr;
+    }
+    return *this;
+  }
+
+  ~Z3Expr() {
+    if (AST)
+      Z3_dec_ref(Z3Context::ZC, AST);
+  }
+
+  /// Get the corresponding IEEE floating-point type for a given bitwidth.
+  static const llvm::fltSemantics &getFloatSemantics(unsigned BitWidth) {
+    switch (BitWidth) {
+    default:
+      llvm_unreachable("Unsupported floating-point semantics!");
+      break;
+    case 16:
+      return llvm::APFloat::IEEEhalf();
+    case 32:
+      return llvm::APFloat::IEEEsingle();
+    case 64:
+      return llvm::APFloat::IEEEdouble();
+    case 128:
+      return llvm::APFloat::IEEEquad();
+    }
+  }
+
+  /// Construct a Z3Expr from a unary operator, given a Z3_context.
+  static Z3Expr fromUnOp(const UnaryOperator::Opcode Op, const Z3Expr &Exp) {
+    Z3_ast AST;
+
+    switch (Op) {
+    default:
+      llvm_unreachable("Unimplemented opcode");
+      break;
+
+    case UO_Minus:
+      AST = Z3_mk_bvneg(Z3Context::ZC, Exp.AST);
+      break;
+
+    case UO_Not:
+      AST = Z3_mk_bvnot(Z3Context::ZC, Exp.AST);
+      break;
+
+    case UO_LNot:
+      AST = Z3_mk_not(Z3Context::ZC, Exp.AST);
+      break;
+    }
+
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from a floating-point unary operator, given a
+  /// Z3_context.
+  static Z3Expr fromFloatUnOp(const UnaryOperator::Opcode Op,
+                              const Z3Expr &Exp) {
+    Z3_ast AST;
+
+    switch (Op) {
+    default:
+      llvm_unreachable("Unimplemented opcode");
+      break;
+
+    case UO_Minus:
+      AST = Z3_mk_fpa_neg(Z3Context::ZC, Exp.AST);
+      break;
+
+    case UO_LNot:
+      return Z3Expr::fromUnOp(Op, Exp);
+    }
+
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from a n-ary binary operator.
+  static Z3Expr fromNBinOp(const BinaryOperator::Opcode Op,
+                           const std::vector<Z3_ast> &ASTs) {
+    Z3_ast AST;
+
+    switch (Op) {
+    default:
+      llvm_unreachable("Unimplemented opcode");
+      break;
+
+    case BO_LAnd:
+      AST = Z3_mk_and(Z3Context::ZC, ASTs.size(), ASTs.data());
+      break;
+
+    case BO_LOr:
+      AST = Z3_mk_or(Z3Context::ZC, ASTs.size(), ASTs.data());
+      break;
+    }
+
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from a binary operator, given a Z3_context.
+  static Z3Expr fromBinOp(const Z3Expr &LHS, const BinaryOperator::Opcode Op,
+                          const Z3Expr &RHS, bool isSigned) {
+    Z3_ast AST;
+
+    assert(Z3Sort::getSort(LHS.AST) == Z3Sort::getSort(RHS.AST) &&
+           "AST's must have the same sort!");
+
+    switch (Op) {
+    default:
+      llvm_unreachable("Unimplemented opcode");
+      break;
+
+    // Multiplicative operators
+    case BO_Mul:
+      AST = Z3_mk_bvmul(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_Div:
+      AST = isSigned ? Z3_mk_bvsdiv(Z3Context::ZC, LHS.AST, RHS.AST)
+                     : Z3_mk_bvudiv(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_Rem:
+      AST = isSigned ? Z3_mk_bvsrem(Z3Context::ZC, LHS.AST, RHS.AST)
+                     : Z3_mk_bvurem(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+
+    // Additive operators
+    case BO_Add:
+      AST = Z3_mk_bvadd(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_Sub:
+      AST = Z3_mk_bvsub(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+
+    // Bitwise shift operators
+    case BO_Shl:
+      AST = Z3_mk_bvshl(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_Shr:
+      AST = isSigned ? Z3_mk_bvashr(Z3Context::ZC, LHS.AST, RHS.AST)
+                     : Z3_mk_bvlshr(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+
+    // Relational operators
+    case BO_LT:
+      AST = isSigned ? Z3_mk_bvslt(Z3Context::ZC, LHS.AST, RHS.AST)
+                     : Z3_mk_bvult(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_GT:
+      AST = isSigned ? Z3_mk_bvsgt(Z3Context::ZC, LHS.AST, RHS.AST)
+                     : Z3_mk_bvugt(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_LE:
+      AST = isSigned ? Z3_mk_bvsle(Z3Context::ZC, LHS.AST, RHS.AST)
+                     : Z3_mk_bvule(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_GE:
+      AST = isSigned ? Z3_mk_bvsge(Z3Context::ZC, LHS.AST, RHS.AST)
+                     : Z3_mk_bvuge(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+
+    // Equality operators
+    case BO_EQ:
+      AST = Z3_mk_eq(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_NE:
+      return Z3Expr::fromUnOp(UO_LNot,
+                              Z3Expr::fromBinOp(LHS, BO_EQ, RHS, isSigned));
+      break;
+
+    // Bitwise operators
+    case BO_And:
+      AST = Z3_mk_bvand(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_Xor:
+      AST = Z3_mk_bvxor(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_Or:
+      AST = Z3_mk_bvor(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+
+    // Logical operators
+    case BO_LAnd:
+    case BO_LOr: {
+      std::vector<Z3_ast> Args = {LHS.AST, RHS.AST};
+      return Z3Expr::fromNBinOp(Op, Args);
+    }
+    }
+
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from a special floating-point binary operator, given
+  /// a Z3_context.
+  static Z3Expr fromFloatSpecialBinOp(const Z3Expr &LHS,
+                                      const BinaryOperator::Opcode Op,
+                                      const llvm::APFloat::fltCategory &RHS) {
+    Z3_ast AST;
+
+    switch (Op) {
+    default:
+      llvm_unreachable("Unimplemented opcode");
+      break;
+
+    // Equality operators
+    case BO_EQ:
+      switch (RHS) {
+      case llvm::APFloat::fcInfinity:
+        AST = Z3_mk_fpa_is_infinite(Z3Context::ZC, LHS.AST);
+        break;
+      case llvm::APFloat::fcNaN:
+        AST = Z3_mk_fpa_is_nan(Z3Context::ZC, LHS.AST);
+        break;
+      case llvm::APFloat::fcNormal:
+        AST = Z3_mk_fpa_is_normal(Z3Context::ZC, LHS.AST);
+        break;
+      case llvm::APFloat::fcZero:
+        AST = Z3_mk_fpa_is_zero(Z3Context::ZC, LHS.AST);
+        break;
+      }
+      break;
+    case BO_NE:
+      return Z3Expr::fromFloatUnOp(
+          UO_LNot, Z3Expr::fromFloatSpecialBinOp(LHS, BO_EQ, RHS));
+      break;
+    }
+
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from a floating-point binary operator, given a
+  /// Z3_context.
+  static Z3Expr fromFloatBinOp(const Z3Expr &LHS,
+                               const BinaryOperator::Opcode Op,
+                               const Z3Expr &RHS) {
+    Z3_ast AST;
+
+    assert(Z3Sort::getSort(LHS.AST) == Z3Sort::getSort(RHS.AST) &&
+           "AST's must have the same sort!");
+
+    switch (Op) {
+    default:
+      llvm_unreachable("Unimplemented opcode");
+      break;
+
+    // Multiplicative operators
+    case BO_Mul: {
+      Z3Expr RoundingMode = Z3Expr::getFloatRoundingMode();
+      AST = Z3_mk_fpa_mul(Z3Context::ZC, RoundingMode.AST, LHS.AST, RHS.AST);
+      break;
+    }
+    case BO_Div: {
+      Z3Expr RoundingMode = Z3Expr::getFloatRoundingMode();
+      AST = Z3_mk_fpa_div(Z3Context::ZC, RoundingMode.AST, LHS.AST, RHS.AST);
+      break;
+    }
+    case BO_Rem:
+      AST = Z3_mk_fpa_rem(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+
+    // Additive operators
+    case BO_Add: {
+      Z3Expr RoundingMode = Z3Expr::getFloatRoundingMode();
+      AST = Z3_mk_fpa_add(Z3Context::ZC, RoundingMode.AST, LHS.AST, RHS.AST);
+      break;
+    }
+    case BO_Sub: {
+      Z3Expr RoundingMode = Z3Expr::getFloatRoundingMode();
+      AST = Z3_mk_fpa_sub(Z3Context::ZC, RoundingMode.AST, LHS.AST, RHS.AST);
+      break;
+    }
+
+    // Relational operators
+    case BO_LT:
+      AST = Z3_mk_fpa_lt(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_GT:
+      AST = Z3_mk_fpa_gt(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_LE:
+      AST = Z3_mk_fpa_leq(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_GE:
+      AST = Z3_mk_fpa_geq(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+
+    // Equality operators
+    case BO_EQ:
+      AST = Z3_mk_fpa_eq(Z3Context::ZC, LHS.AST, RHS.AST);
+      break;
+    case BO_NE:
+      return Z3Expr::fromFloatUnOp(UO_LNot,
+                                   Z3Expr::fromFloatBinOp(LHS, BO_EQ, RHS));
+      break;
+
+    // Logical operators
+    case BO_LAnd:
+    case BO_LOr:
+      return Z3Expr::fromBinOp(LHS, Op, RHS, false);
+    }
+
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from a SymbolData, given a Z3_context.
+  static Z3Expr fromData(const SymbolID ID, bool isBool, bool isFloat,
+                         uint64_t BitWidth) {
+    llvm::Twine Name = "$" + llvm::Twine(ID);
+
+    Z3Sort Sort;
+    if (isBool)
+      Sort = Z3Sort::getBoolSort();
+    else if (isFloat)
+      Sort = Z3Sort::getFloatSort(BitWidth);
+    else
+      Sort = Z3Sort::getBitvectorSort(BitWidth);
+
+    Z3_symbol Symbol = Z3_mk_string_symbol(Z3Context::ZC, Name.str().c_str());
+    Z3_ast AST = Z3_mk_const(Z3Context::ZC, Symbol, Sort.Sort);
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from a SymbolCast, given a Z3_context.
+  static Z3Expr fromCast(const Z3Expr &Exp, QualType ToTy, uint64_t ToBitWidth,
+                         QualType FromTy, uint64_t FromBitWidth) {
+    Z3_ast AST;
+
+    if ((FromTy->isIntegralOrEnumerationType() &&
+         ToTy->isIntegralOrEnumerationType()) ||
+        (FromTy->isAnyPointerType() ^ ToTy->isAnyPointerType()) ||
+        (FromTy->isBlockPointerType() ^ ToTy->isBlockPointerType()) ||
+        (FromTy->isReferenceType() ^ ToTy->isReferenceType())) {
+      // Special case: Z3 boolean type is distinct from bitvector type, so
+      // must use if-then-else expression instead of direct cast
+      if (FromTy->isBooleanType()) {
+        assert(ToBitWidth > 0 && "BitWidth must be positive!");
+        Z3Expr Zero = Z3Expr::fromInt("0", ToBitWidth);
+        Z3Expr One = Z3Expr::fromInt("1", ToBitWidth);
+        AST = Z3_mk_ite(Z3Context::ZC, Exp.AST, One.AST, Zero.AST);
+      } else if (ToBitWidth > FromBitWidth) {
+        AST = FromTy->isSignedIntegerOrEnumerationType()
+                  ? Z3_mk_sign_ext(Z3Context::ZC, ToBitWidth - FromBitWidth,
+                                   Exp.AST)
+                  : Z3_mk_zero_ext(Z3Context::ZC, ToBitWidth - FromBitWidth,
+                                   Exp.AST);
+      } else if (ToBitWidth < FromBitWidth) {
+        AST = Z3_mk_extract(Z3Context::ZC, ToBitWidth - 1, 0, Exp.AST);
+      } else {
+        // Both are bitvectors with the same width, ignore the type cast
+        return Exp;
+      }
+    } else if (FromTy->isRealFloatingType() && ToTy->isRealFloatingType()) {
+      if (ToBitWidth != FromBitWidth) {
+        Z3Expr RoundingMode = Z3Expr::getFloatRoundingMode();
+        Z3Sort Sort = Z3Sort::getFloatSort(ToBitWidth);
+        AST = Z3_mk_fpa_to_fp_float(Z3Context::ZC, RoundingMode.AST, Exp.AST,
+                                    Sort.Sort);
+      } else {
+        return Exp;
+      }
+    } else if (FromTy->isIntegralOrEnumerationType() &&
+               ToTy->isRealFloatingType()) {
+      Z3Expr RoundingMode = Z3Expr::getFloatRoundingMode();
+      Z3Sort Sort = Z3Sort::getFloatSort(ToBitWidth);
+      AST = FromTy->isSignedIntegerOrEnumerationType()
+                ? Z3_mk_fpa_to_fp_signed(Z3Context::ZC, RoundingMode.AST,
+                                         Exp.AST, Sort.Sort)
+                : Z3_mk_fpa_to_fp_unsigned(Z3Context::ZC, RoundingMode.AST,
+                                           Exp.AST, Sort.Sort);
+    } else if (FromTy->isRealFloatingType() &&
+               ToTy->isIntegralOrEnumerationType()) {
+      Z3Expr RoundingMode = Z3Expr::getFloatRoundingMode();
+      AST = ToTy->isSignedIntegerOrEnumerationType()
+                ? Z3_mk_fpa_to_sbv(Z3Context::ZC, RoundingMode.AST, Exp.AST,
+                                   ToBitWidth)
+                : Z3_mk_fpa_to_ubv(Z3Context::ZC, RoundingMode.AST, Exp.AST,
+                                   ToBitWidth);
+    } else {
+      llvm_unreachable("Unsupported explicit type cast!");
+    }
+
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from a boolean, given a Z3_context.
+  static Z3Expr fromBoolean(const bool Bool) {
+    Z3_ast AST = Bool ? Z3_mk_true(Z3Context::ZC) : Z3_mk_false(Z3Context::ZC);
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from a finite APFloat, given a Z3_context.
+  static Z3Expr fromAPFloat(const llvm::APFloat &Float) {
+    Z3_ast AST;
+    Z3Sort Sort = Z3Sort::getFloatSort(
+        llvm::APFloat::semanticsSizeInBits(Float.getSemantics()));
+
+    llvm::APSInt Int = llvm::APSInt(Float.bitcastToAPInt(), true);
+    Z3Expr Z3Int = Z3Expr::fromAPSInt(Int);
+    AST = Z3_mk_fpa_to_fp_bv(Z3Context::ZC, Z3Int.AST, Sort.Sort);
+
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from an APSInt, given a Z3_context.
+  static Z3Expr fromAPSInt(const llvm::APSInt &Int) {
+    Z3Sort Sort = Z3Sort::getBitvectorSort(Int.getBitWidth());
+    Z3_ast AST =
+        Z3_mk_numeral(Z3Context::ZC, Int.toString(10).c_str(), Sort.Sort);
+    return Z3Expr(AST);
+  }
+
+  /// Construct a Z3Expr from an integer, given a Z3_context.
+  static Z3Expr fromInt(const char *Int, uint64_t BitWidth) {
+    Z3Sort Sort = Z3Sort::getBitvectorSort(BitWidth);
+    Z3_ast AST = Z3_mk_numeral(Z3Context::ZC, Int, Sort.Sort);
+    return Z3Expr(AST);
+  }
+
+  /// Construct an APFloat from a Z3Expr, given the AST representation
+  static bool toAPFloat(const Z3Sort &Sort, const Z3_ast &AST,
+                        llvm::APFloat &Float, bool useSemantics = true) {
+    assert(Sort.getSortKind() == Z3_FLOATING_POINT_SORT &&
+           "Unsupported sort to floating-point!");
+
+    llvm::APSInt Int(Sort.getFloatSortSize(), true);
+    const llvm::fltSemantics &Semantics =
+        Z3Expr::getFloatSemantics(Sort.getFloatSortSize());
+    Z3Sort BVSort = Z3Sort::getBitvectorSort(Sort.getFloatSortSize());
+    if (!Z3Expr::toAPSInt(BVSort, AST, Int, true)) {
+      return false;
+    }
+
+    if (useSemantics &&
+        !Z3Expr::areEquivalent(Float.getSemantics(), Semantics)) {
+      assert(false && "Floating-point types don't match!");
+      return false;
+    }
+
+    Float = llvm::APFloat(Semantics, Int);
+    return true;
+  }
+
+  /// Construct an APSInt from a Z3Expr, given the AST representation
+  static bool toAPSInt(const Z3Sort &Sort, const Z3_ast &AST, llvm::APSInt &Int,
+                       bool useSemantics = true) {
+    switch (Sort.getSortKind()) {
+    default:
+      llvm_unreachable("Unsupported sort to integer!");
+    case Z3_BV_SORT: {
+      if (useSemantics && Int.getBitWidth() != Sort.getBitvectorSortSize()) {
+        assert(false && "Bitvector types don't match!");
+        return false;
+      }
+
+      uint64_t Value[2];
+      // Force cast because Z3 defines __uint64 to be a unsigned long long
+      // type, which isn't compatible with a unsigned long type, even if they
+      // are the same size.
+      Z3_get_numeral_uint64(Z3Context::ZC, AST,
+                            reinterpret_cast<__uint64 *>(&Value[0]));
+      if (Sort.getBitvectorSortSize() <= 64) {
+        Int = llvm::APSInt(llvm::APInt(Int.getBitWidth(), Value[0]), true);
+      } else if (Sort.getBitvectorSortSize() == 128) {
+        Z3Expr ASTHigh = Z3Expr(Z3_mk_extract(Z3Context::ZC, 127, 64, AST));
+        Z3_get_numeral_uint64(Z3Context::ZC, AST,
+                              reinterpret_cast<__uint64 *>(&Value[1]));
+        Int = llvm::APSInt(llvm::APInt(Int.getBitWidth(), Value), true);
+      } else {
+        assert(false && "Bitwidth not supported!");
+        return false;
+      }
+      return true;
+    }
+    case Z3_BOOL_SORT:
+      if (useSemantics && Int.getBitWidth() < 1) {
+        assert(false && "Boolean type doesn't match!");
+        return false;
+      }
+      Int = llvm::APSInt(
+          llvm::APInt(Int.getBitWidth(),
+                      Z3_get_bool_value(Z3Context::ZC, AST) == Z3_L_TRUE ? 1
+                                                                         : 0),
+          true);
+      return true;
+    }
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(Z3_get_ast_hash(Z3Context::ZC, AST));
+  }
+
+  bool operator<(const Z3Expr &Other) const {
+    llvm::FoldingSetNodeID ID1, ID2;
+    Profile(ID1);
+    Other.Profile(ID2);
+    return ID1 < ID2;
+  }
+
+  /// Comparison of AST equality, not model equivalence.
+  bool operator==(const Z3Expr &Other) const {
+    assert(Z3_is_eq_sort(Z3Context::ZC, Z3_get_sort(Z3Context::ZC, AST),
+                         Z3_get_sort(Z3Context::ZC, Other.AST)) &&
+           "AST's must have the same sort");
+    return Z3_is_eq_ast(Z3Context::ZC, AST, Other.AST);
+  }
+
+  /// Override implicit move constructor for correct reference counting.
+  Z3Expr &operator=(const Z3Expr &Move) {
+    Z3_inc_ref(Z3Context::ZC, Move.AST);
+    Z3_dec_ref(Z3Context::ZC, AST);
+    AST = Move.AST;
+    return *this;
+  }
+
+  void print(raw_ostream &OS) const {
+    OS << Z3_ast_to_string(Z3Context::ZC, AST);
+  }
+
+  LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
+}; // end class Z3Expr
+
+class Z3Model {
+  Z3_model Model;
+
+public:
+  Z3Model(Z3_model ZM) : Model(ZM) { Z3_model_inc_ref(Z3Context::ZC, Model); }
+
+  /// Override implicit copy constructor for correct reference counting.
+  Z3Model(const Z3Model &Copy) : Model(Copy.Model) {
+    Z3_model_inc_ref(Z3Context::ZC, Model);
+  }
+
+  /// Provide move constructor
+  Z3Model(Z3Model &&Move) : Model(nullptr) { *this = std::move(Move); }
+
+  /// Provide move assignment constructor
+  Z3Model &operator=(Z3Model &&Move) {
+    if (this != &Move) {
+      if (Model)
+        Z3_model_dec_ref(Z3Context::ZC, Model);
+      Model = Move.Model;
+      Move.Model = nullptr;
+    }
+    return *this;
+  }
+
+  ~Z3Model() {
+    if (Model)
+      Z3_model_dec_ref(Z3Context::ZC, Model);
+  }
+
+  /// Given an expression, extract the value of this operand in the model.
+  bool getInterpretation(const Z3Expr &Exp, llvm::APSInt &Int) const {
+    Z3_func_decl Func =
+        Z3_get_app_decl(Z3Context::ZC, Z3_to_app(Z3Context::ZC, Exp.AST));
+    if (Z3_model_has_interp(Z3Context::ZC, Model, Func) != Z3_L_TRUE)
+      return false;
+
+    Z3_ast Assign = Z3_model_get_const_interp(Z3Context::ZC, Model, Func);
+    Z3Sort Sort = Z3Sort::getSort(Assign);
+    return Z3Expr::toAPSInt(Sort, Assign, Int, true);
+  }
+
+  /// Given an expression, extract the value of this operand in the model.
+  bool getInterpretation(const Z3Expr &Exp, llvm::APFloat &Float) const {
+    Z3_func_decl Func =
+        Z3_get_app_decl(Z3Context::ZC, Z3_to_app(Z3Context::ZC, Exp.AST));
+    if (Z3_model_has_interp(Z3Context::ZC, Model, Func) != Z3_L_TRUE)
+      return false;
+
+    Z3_ast Assign = Z3_model_get_const_interp(Z3Context::ZC, Model, Func);
+    Z3Sort Sort = Z3Sort::getSort(Assign);
+    return Z3Expr::toAPFloat(Sort, Assign, Float, true);
+  }
+
+  void print(raw_ostream &OS) const {
+    OS << Z3_model_to_string(Z3Context::ZC, Model);
+  }
+
+  LLVM_DUMP_METHOD void dump() const { print(llvm::errs()); }
+}; // end class Z3Model
+
+class Z3Solver {
+  friend class Z3ConstraintManager;
+
+  Z3_solver Solver;
+
+  Z3Solver(Z3_solver ZS) : Solver(ZS) {
+    Z3_solver_inc_ref(Z3Context::ZC, Solver);
+  }
+
+public:
+  /// Override implicit copy constructor for correct reference counting.
+  Z3Solver(const Z3Solver &Copy) : Solver(Copy.Solver) {
+    Z3_solver_inc_ref(Z3Context::ZC, Solver);
+  }
+
+  /// Provide move constructor
+  Z3Solver(Z3Solver &&Move) : Solver(nullptr) { *this = std::move(Move); }
+
+  /// Provide move assignment constructor
+  Z3Solver &operator=(Z3Solver &&Move) {
+    if (this != &Move) {
+      if (Solver)
+        Z3_solver_dec_ref(Z3Context::ZC, Solver);
+      Solver = Move.Solver;
+      Move.Solver = nullptr;
+    }
+    return *this;
+  }
+
+  ~Z3Solver() {
+    if (Solver)
+      Z3_solver_dec_ref(Z3Context::ZC, Solver);
+  }
+
+  /// Given a constraint, add it to the solver
+  void addConstraint(const Z3Expr &Exp) {
+    Z3_solver_assert(Z3Context::ZC, Solver, Exp.AST);
+  }
+
+  /// Given a program state, construct the logical conjunction and add it to
+  /// the solver
+  void addStateConstraints(ProgramStateRef State) {
+    // TODO: Don't add all the constraints, only the relevant ones
+    ConstraintZ3Ty CZ = State->get<ConstraintZ3>();
+    ConstraintZ3Ty::iterator I = CZ.begin(), IE = CZ.end();
+
+    // Construct the logical AND of all the constraints
+    if (I != IE) {
+      std::vector<Z3_ast> ASTs;
+
+      while (I != IE)
+        ASTs.push_back(I++->second.AST);
+
+      Z3Expr Conj = Z3Expr::fromNBinOp(BO_LAnd, ASTs);
+      addConstraint(Conj);
+    }
+  }
+
+  /// Check if the constraints are satisfiable
+  Z3_lbool check() { return Z3_solver_check(Z3Context::ZC, Solver); }
+
+  /// Push the current solver state
+  void push() { return Z3_solver_push(Z3Context::ZC, Solver); }
+
+  /// Pop the previous solver state
+  void pop(unsigned NumStates = 1) {
+    assert(Z3_solver_get_num_scopes(Z3Context::ZC, Solver) >= NumStates);
+    return Z3_solver_pop(Z3Context::ZC, Solver, NumStates);
+  }
+
+  /// Get a model from the solver. Caller should check the model is
+  /// satisfiable.
+  Z3Model getModel() {
+    return Z3Model(Z3_solver_get_model(Z3Context::ZC, Solver));
+  }
+
+  /// Reset the solver and remove all constraints.
+  void reset() { Z3_solver_reset(Z3Context::ZC, Solver); }
+}; // end class Z3Solver
+
+void Z3ErrorHandler(Z3_context Context, Z3_error_code Error) {
+  llvm::report_fatal_error("Z3 error: " +
+                           llvm::Twine(Z3_get_error_msg_ex(Context, Error)));
+}
+
+class Z3ConstraintManager : public SimpleConstraintManager {
+  Z3Context Context;
+  mutable Z3Solver Solver;
+
+public:
+  Z3ConstraintManager(SubEngine *SE, SValBuilder &SB)
+      : SimpleConstraintManager(SE, SB),
+        Solver(Z3_mk_simple_solver(Z3Context::ZC)) {
+    Z3_set_error_handler(Z3Context::ZC, Z3ErrorHandler);
+  }
+
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from ConstraintManager.
+  //===------------------------------------------------------------------===//
+
+  bool canReasonAbout(SVal X) const override;
+
+  ConditionTruthVal checkNull(ProgramStateRef State, SymbolRef Sym) override;
+
+  const llvm::APSInt *getSymVal(ProgramStateRef State,
+                                SymbolRef Sym) const override;
+
+  ProgramStateRef removeDeadBindings(ProgramStateRef St,
+                                     SymbolReaper &SymReaper) override;
+
+  void print(ProgramStateRef St, raw_ostream &Out, const char *nl,
+             const char *sep) override;
+
+  //===------------------------------------------------------------------===//
+  // Implementation for interface from SimpleConstraintManager.
+  //===------------------------------------------------------------------===//
+
+  ProgramStateRef assumeSym(ProgramStateRef state, SymbolRef Sym,
+                            bool Assumption) override;
+
+  ProgramStateRef assumeSymInclusiveRange(ProgramStateRef State, SymbolRef Sym,
+                                          const llvm::APSInt &From,
+                                          const llvm::APSInt &To,
+                                          bool InRange) override;
+
+  ProgramStateRef assumeSymUnsupported(ProgramStateRef State, SymbolRef Sym,
+                                       bool Assumption) override;
+
+private:
+  //===------------------------------------------------------------------===//
+  // Internal implementation.
+  //===------------------------------------------------------------------===//
+
+  // Check whether a new model is satisfiable, and update the program state.
+  ProgramStateRef assumeZ3Expr(ProgramStateRef State, SymbolRef Sym,
+                               const Z3Expr &Exp);
+
+  // Generate and check a Z3 model, using the given constraint.
+  Z3_lbool checkZ3Model(ProgramStateRef State, const Z3Expr &Exp) const;
+
+  // Generate a Z3Expr that represents the given symbolic expression.
+  // Sets the hasComparison parameter if the expression has a comparison
+  // operator.
+  // Sets the RetTy parameter to the final return type after promotions and
+  // casts.
+  Z3Expr getZ3Expr(SymbolRef Sym, QualType *RetTy = nullptr,
+                   bool *hasComparison = nullptr) const;
+
+  // Generate a Z3Expr that takes the logical not of an expression.
+  Z3Expr getZ3NotExpr(const Z3Expr &Exp) const;
+
+  // Generate a Z3Expr that compares the expression to zero.
+  Z3Expr getZ3ZeroExpr(const Z3Expr &Exp, QualType RetTy,
+                       bool Assumption) const;
+
+  // Recursive implementation to unpack and generate symbolic expression.
+  // Sets the hasComparison and RetTy parameters. See getZ3Expr().
+  Z3Expr getZ3SymExpr(SymbolRef Sym, QualType *RetTy,
+                      bool *hasComparison) const;
+
+  // Wrapper to generate Z3Expr from SymbolData.
+  Z3Expr getZ3DataExpr(const SymbolID ID, QualType Ty) const;
+
+  // Wrapper to generate Z3Expr from SymbolCast.
+  Z3Expr getZ3CastExpr(const Z3Expr &Exp, QualType FromTy, QualType Ty) const;
+
+  // Wrapper to generate Z3Expr from BinarySymExpr.
+  // Sets the hasComparison and RetTy parameters. See getZ3Expr().
+  Z3Expr getZ3SymBinExpr(const BinarySymExpr *BSE, bool *hasComparison,
+                         QualType *RetTy) const;
+
+  // Wrapper to generate Z3Expr from unpacked binary symbolic expression.
+  // Sets the RetTy parameter. See getZ3Expr().
+  Z3Expr getZ3BinExpr(const Z3Expr &LHS, QualType LTy,
+                      BinaryOperator::Opcode Op, const Z3Expr &RHS,
+                      QualType RTy, QualType *RetTy) const;
+
+  //===------------------------------------------------------------------===//
+  // Helper functions.
+  //===------------------------------------------------------------------===//
+
+  // Recover the QualType of an APSInt.
+  // TODO: Refactor to put elsewhere
+  QualType getAPSIntType(const llvm::APSInt &Int) const;
+
+  // Perform implicit type conversion on binary symbolic expressions.
+  // May modify all input parameters.
+  // TODO: Refactor to use built-in conversion functions
+  void doTypeConversion(Z3Expr &LHS, Z3Expr &RHS, QualType &LTy,
+                        QualType &RTy) const;
+
+  // Perform implicit integer type conversion.
+  // May modify all input parameters.
+  // TODO: Refactor to use Sema::handleIntegerConversion()
+  template <typename T,
+            T(doCast)(const T &, QualType, uint64_t, QualType, uint64_t)>
+  void doIntTypeConversion(T &LHS, QualType &LTy, T &RHS, QualType &RTy) const;
+
+  // Perform implicit floating-point type conversion.
+  // May modify all input parameters.
+  // TODO: Refactor to use Sema::handleFloatConversion()
+  template <typename T,
+            T(doCast)(const T &, QualType, uint64_t, QualType, uint64_t)>
+  void doFloatTypeConversion(T &LHS, QualType &LTy, T &RHS,
+                             QualType &RTy) const;
+
+  // Callback function for doCast parameter on APSInt type.
+  static llvm::APSInt castAPSInt(const llvm::APSInt &V, QualType ToTy,
+                                 uint64_t ToWidth, QualType FromTy,
+                                 uint64_t FromWidth);
+}; // end class Z3ConstraintManager
+
+Z3_context Z3Context::ZC;
+
+} // end anonymous namespace
+
+ProgramStateRef Z3ConstraintManager::assumeSym(ProgramStateRef State,
+                                               SymbolRef Sym, bool Assumption) {
+  QualType RetTy;
+  bool hasComparison;
+
+  Z3Expr Exp = getZ3Expr(Sym, &RetTy, &hasComparison);
+  // Create zero comparison for implicit boolean cast, with reversed assumption
+  if (!hasComparison && !RetTy->isBooleanType())
+    return assumeZ3Expr(State, Sym, getZ3ZeroExpr(Exp, RetTy, !Assumption));
+
+  return assumeZ3Expr(State, Sym, Assumption ? Exp : getZ3NotExpr(Exp));
+}
+
+ProgramStateRef Z3ConstraintManager::assumeSymInclusiveRange(
+    ProgramStateRef State, SymbolRef Sym, const llvm::APSInt &From,
+    const llvm::APSInt &To, bool InRange) {
+  QualType RetTy;
+  // The expression may be casted, so we cannot call getZ3DataExpr() directly
+  Z3Expr Exp = getZ3Expr(Sym, &RetTy);
+
+  assert((getAPSIntType(From) == getAPSIntType(To)) &&
+         "Range values have different types!");
+  QualType RTy = getAPSIntType(From);
+  bool isSignedTy = RetTy->isSignedIntegerOrEnumerationType();
+  Z3Expr FromExp = Z3Expr::fromAPSInt(From);
+  Z3Expr ToExp = Z3Expr::fromAPSInt(To);
+
+  // Construct single (in)equality
+  if (From == To)
+    return assumeZ3Expr(State, Sym,
+                        getZ3BinExpr(Exp, RetTy, InRange ? BO_EQ : BO_NE,
+                                     FromExp, RTy, nullptr));
+
+  // Construct two (in)equalities, and a logical and/or
+  Z3Expr LHS =
+      getZ3BinExpr(Exp, RetTy, InRange ? BO_GE : BO_LT, FromExp, RTy, nullptr);
+  Z3Expr RHS =
+      getZ3BinExpr(Exp, RetTy, InRange ? BO_LE : BO_GT, ToExp, RTy, nullptr);
+  return assumeZ3Expr(
+      State, Sym,
+      Z3Expr::fromBinOp(LHS, InRange ? BO_LAnd : BO_LOr, RHS, isSignedTy));
+}
+
+ProgramStateRef Z3ConstraintManager::assumeSymUnsupported(ProgramStateRef State,
+                                                          SymbolRef Sym,
+                                                          bool Assumption) {
+  // Skip anything that is unsupported
+  return State;
+}
+
+bool Z3ConstraintManager::canReasonAbout(SVal X) const {
+  const TargetInfo &TI = getBasicVals().getContext().getTargetInfo();
+
+  Optional<nonloc::SymbolVal> SymVal = X.getAs<nonloc::SymbolVal>();
+  if (!SymVal)
+    return true;
+
+  const SymExpr *Sym = SymVal->getSymbol();
+  do {
+    QualType Ty = Sym->getType();
+
+    // Complex types are not modeled
+    if (Ty->isComplexType() || Ty->isComplexIntegerType())
+      return false;
+
+    // Non-IEEE 754 floating-point types are not modeled
+    if ((Ty->isSpecificBuiltinType(BuiltinType::LongDouble) &&
+         (&TI.getLongDoubleFormat() == &llvm::APFloat::x87DoubleExtended() ||
+          &TI.getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble())))
+      return false;
+
+    if (isa<SymbolData>(Sym)) {
+      break;
+    } else if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
+      Sym = SC->getOperand();
+    } else if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
+      if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
+        Sym = SIE->getLHS();
+      } else if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
+        Sym = ISE->getRHS();
+      } else if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
+        return canReasonAbout(nonloc::SymbolVal(SSM->getLHS())) &&
+               canReasonAbout(nonloc::SymbolVal(SSM->getRHS()));
+      } else {
+        llvm_unreachable("Unsupported binary expression to reason about!");
+      }
+    } else {
+      llvm_unreachable("Unsupported expression to reason about!");
+    }
+  } while (Sym);
+
+  return true;
+}
+
+ConditionTruthVal Z3ConstraintManager::checkNull(ProgramStateRef State,
+                                                 SymbolRef Sym) {
+  QualType RetTy;
+  // The expression may be casted, so we cannot call getZ3DataExpr() directly
+  Z3Expr VarExp = getZ3Expr(Sym, &RetTy);
+  Z3Expr Exp = getZ3ZeroExpr(VarExp, RetTy, true);
+  // Negate the constraint
+  Z3Expr NotExp = getZ3ZeroExpr(VarExp, RetTy, false);
+
+  Solver.reset();
+  Solver.addStateConstraints(State);
+
+  Solver.push();
+  Solver.addConstraint(Exp);
+  Z3_lbool isSat = Solver.check();
+
+  Solver.pop();
+  Solver.addConstraint(NotExp);
+  Z3_lbool isNotSat = Solver.check();
+
+  // Zero is the only possible solution
+  if (isSat == Z3_L_TRUE && isNotSat == Z3_L_FALSE)
+    return true;
+  // Zero is not a solution
+  else if (isSat == Z3_L_FALSE && isNotSat == Z3_L_TRUE)
+    return false;
+
+  // Zero may be a solution
+  return ConditionTruthVal();
+}
+
+const llvm::APSInt *Z3ConstraintManager::getSymVal(ProgramStateRef State,
+                                                   SymbolRef Sym) const {
+  BasicValueFactory &BV = getBasicVals();
+  ASTContext &Ctx = BV.getContext();
+
+  if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
+    QualType Ty = Sym->getType();
+    assert(!Ty->isRealFloatingType());
+    llvm::APSInt Value(Ctx.getTypeSize(Ty),
+                       !Ty->isSignedIntegerOrEnumerationType());
+
+    Z3Expr Exp = getZ3DataExpr(SD->getSymbolID(), Ty);
+
+    Solver.reset();
+    Solver.addStateConstraints(State);
+
+    // Constraints are unsatisfiable
+    if (Solver.check() != Z3_L_TRUE)
+      return nullptr;
+
+    Z3Model Model = Solver.getModel();
+    // Model does not assign interpretation
+    if (!Model.getInterpretation(Exp, Value))
+      return nullptr;
+
+    // A value has been obtained, check if it is the only value
+    Z3Expr NotExp = Z3Expr::fromBinOp(
+        Exp, BO_NE,
+        Ty->isBooleanType() ? Z3Expr::fromBoolean(Value.getBoolValue())
+                            : Z3Expr::fromAPSInt(Value),
+        false);
+
+    Solver.addConstraint(NotExp);
+    if (Solver.check() == Z3_L_TRUE)
+      return nullptr;
+
+    // This is the only solution, store it
+    return &BV.getValue(Value);
+  } else if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
+    SymbolRef CastSym = SC->getOperand();
+    QualType CastTy = SC->getType();
+    // Skip the void type
+    if (CastTy->isVoidType())
+      return nullptr;
+
+    const llvm::APSInt *Value;
+    if (!(Value = getSymVal(State, CastSym)))
+      return nullptr;
+    return &BV.Convert(SC->getType(), *Value);
+  } else if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
+    const llvm::APSInt *LHS, *RHS;
+    if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
+      LHS = getSymVal(State, SIE->getLHS());
+      RHS = &SIE->getRHS();
+    } else if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
+      LHS = &ISE->getLHS();
+      RHS = getSymVal(State, ISE->getRHS());
+    } else if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
+      // Early termination to avoid expensive call
+      LHS = getSymVal(State, SSM->getLHS());
+      RHS = LHS ? getSymVal(State, SSM->getRHS()) : nullptr;
+    } else {
+      llvm_unreachable("Unsupported binary expression to get symbol value!");
+    }
+
+    if (!LHS || !RHS)
+      return nullptr;
+
+    llvm::APSInt ConvertedLHS = *LHS, ConvertedRHS = *RHS;
+    QualType LTy = getAPSIntType(*LHS), RTy = getAPSIntType(*RHS);
+    doIntTypeConversion<llvm::APSInt, Z3ConstraintManager::castAPSInt>(
+        ConvertedLHS, LTy, ConvertedRHS, RTy);
+    return BV.evalAPSInt(BSE->getOpcode(), ConvertedLHS, ConvertedRHS);
+  }
+
+  llvm_unreachable("Unsupported expression to get symbol value!");
+}
+
+ProgramStateRef
+Z3ConstraintManager::removeDeadBindings(ProgramStateRef State,
+                                        SymbolReaper &SymReaper) {
+  ConstraintZ3Ty CZ = State->get<ConstraintZ3>();
+  ConstraintZ3Ty::Factory &CZFactory = State->get_context<ConstraintZ3>();
+
+  for (ConstraintZ3Ty::iterator I = CZ.begin(), E = CZ.end(); I != E; ++I) {
+    if (SymReaper.maybeDead(I->first))
+      CZ = CZFactory.remove(CZ, *I);
+  }
+
+  return State->set<ConstraintZ3>(CZ);
+}
+
+//===------------------------------------------------------------------===//
+// Internal implementation.
+//===------------------------------------------------------------------===//
+
+ProgramStateRef Z3ConstraintManager::assumeZ3Expr(ProgramStateRef State,
+                                                  SymbolRef Sym,
+                                                  const Z3Expr &Exp) {
+  // Check the model, avoid simplifying AST to save time
+  if (checkZ3Model(State, Exp) == Z3_L_TRUE)
+    return State->add<ConstraintZ3>(std::make_pair(Sym, Exp));
+
+  return nullptr;
+}
+
+Z3_lbool Z3ConstraintManager::checkZ3Model(ProgramStateRef State,
+                                           const Z3Expr &Exp) const {
+  Solver.reset();
+  Solver.addConstraint(Exp);
+  Solver.addStateConstraints(State);
+  return Solver.check();
+}
+
+Z3Expr Z3ConstraintManager::getZ3Expr(SymbolRef Sym, QualType *RetTy,
+                                      bool *hasComparison) const {
+  if (hasComparison) {
+    *hasComparison = false;
+  }
+
+  return getZ3SymExpr(Sym, RetTy, hasComparison);
+}
+
+Z3Expr Z3ConstraintManager::getZ3NotExpr(const Z3Expr &Exp) const {
+  return Z3Expr::fromUnOp(UO_LNot, Exp);
+}
+
+Z3Expr Z3ConstraintManager::getZ3ZeroExpr(const Z3Expr &Exp, QualType Ty,
+                                          bool Assumption) const {
+  ASTContext &Ctx = getBasicVals().getContext();
+  if (Ty->isRealFloatingType()) {
+    llvm::APFloat Zero = llvm::APFloat::getZero(Ctx.getFloatTypeSemantics(Ty));
+    return Z3Expr::fromFloatBinOp(Exp, Assumption ? BO_EQ : BO_NE,
+                                  Z3Expr::fromAPFloat(Zero));
+  } else if (Ty->isIntegralOrEnumerationType() || Ty->isAnyPointerType() ||
+             Ty->isBlockPointerType() || Ty->isReferenceType()) {
+    bool isSigned = Ty->isSignedIntegerOrEnumerationType();
+    // Skip explicit comparison for boolean types
+    if (Ty->isBooleanType())
+      return Assumption ? getZ3NotExpr(Exp) : Exp;
+    return Z3Expr::fromBinOp(Exp, Assumption ? BO_EQ : BO_NE,
+                             Z3Expr::fromInt("0", Ctx.getTypeSize(Ty)),
+                             isSigned);
+  }
+
+  llvm_unreachable("Unsupported type for zero value!");
+}
+
+Z3Expr Z3ConstraintManager::getZ3SymExpr(SymbolRef Sym, QualType *RetTy,
+                                         bool *hasComparison) const {
+  if (const SymbolData *SD = dyn_cast<SymbolData>(Sym)) {
+    if (RetTy)
+      *RetTy = Sym->getType();
+
+    return getZ3DataExpr(SD->getSymbolID(), Sym->getType());
+  } else if (const SymbolCast *SC = dyn_cast<SymbolCast>(Sym)) {
+    if (RetTy)
+      *RetTy = Sym->getType();
+
+    QualType FromTy;
+    Z3Expr Exp = getZ3SymExpr(SC->getOperand(), &FromTy, hasComparison);
+    // Casting an expression with a comparison invalidates it. Note that this
+    // must occur after the recursive call above.
+    // e.g. (signed char) (x > 0)
+    if (hasComparison)
+      *hasComparison = false;
+    return getZ3CastExpr(Exp, FromTy, Sym->getType());
+  } else if (const BinarySymExpr *BSE = dyn_cast<BinarySymExpr>(Sym)) {
+    Z3Expr Exp = getZ3SymBinExpr(BSE, hasComparison, RetTy);
+    // Set the hasComparison parameter, in post-order traversal order.
+    if (hasComparison)
+      *hasComparison = BinaryOperator::isComparisonOp(BSE->getOpcode());
+    return Exp;
+  }
+
+  llvm_unreachable("Unsupported SymbolRef type!");
+}
+
+Z3Expr Z3ConstraintManager::getZ3DataExpr(const SymbolID ID,
+                                          QualType Ty) const {
+  ASTContext &Ctx = getBasicVals().getContext();
+  return Z3Expr::fromData(ID, Ty->isBooleanType(), Ty->isRealFloatingType(),
+                          Ctx.getTypeSize(Ty));
+}
+
+Z3Expr Z3ConstraintManager::getZ3CastExpr(const Z3Expr &Exp, QualType FromTy,
+                                          QualType ToTy) const {
+  ASTContext &Ctx = getBasicVals().getContext();
+  return Z3Expr::fromCast(Exp, ToTy, Ctx.getTypeSize(ToTy), FromTy,
+                          Ctx.getTypeSize(FromTy));
+}
+
+Z3Expr Z3ConstraintManager::getZ3SymBinExpr(const BinarySymExpr *BSE,
+                                            bool *hasComparison,
+                                            QualType *RetTy) const {
+  QualType LTy, RTy;
+  BinaryOperator::Opcode Op = BSE->getOpcode();
+
+  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(BSE)) {
+    RTy = getAPSIntType(SIE->getRHS());
+    Z3Expr LHS = getZ3SymExpr(SIE->getLHS(), &LTy, hasComparison);
+    Z3Expr RHS = Z3Expr::fromAPSInt(SIE->getRHS());
+    return getZ3BinExpr(LHS, LTy, Op, RHS, RTy, RetTy);
+  } else if (const IntSymExpr *ISE = dyn_cast<IntSymExpr>(BSE)) {
+    LTy = getAPSIntType(ISE->getLHS());
+    Z3Expr LHS = Z3Expr::fromAPSInt(ISE->getLHS());
+    Z3Expr RHS = getZ3SymExpr(ISE->getRHS(), &RTy, hasComparison);
+    return getZ3BinExpr(LHS, LTy, Op, RHS, RTy, RetTy);
+  } else if (const SymSymExpr *SSM = dyn_cast<SymSymExpr>(BSE)) {
+    Z3Expr LHS = getZ3SymExpr(SSM->getLHS(), &LTy, hasComparison);
+    Z3Expr RHS = getZ3SymExpr(SSM->getRHS(), &RTy, hasComparison);
+    return getZ3BinExpr(LHS, LTy, Op, RHS, RTy, RetTy);
+  } else {
+    llvm_unreachable("Unsupported BinarySymExpr type!");
+  }
+}
+
+Z3Expr Z3ConstraintManager::getZ3BinExpr(const Z3Expr &LHS, QualType LTy,
+                                         BinaryOperator::Opcode Op,
+                                         const Z3Expr &RHS, QualType RTy,
+                                         QualType *RetTy) const {
+  Z3Expr NewLHS = LHS;
+  Z3Expr NewRHS = RHS;
+  doTypeConversion(NewLHS, NewRHS, LTy, RTy);
+  // Update the return type parameter if the output type has changed.
+  if (RetTy) {
+    // A boolean result can be represented as an integer type in C/C++, but at
+    // this point we only care about the Z3 type. Set it as a boolean type to
+    // avoid subsequent Z3 errors.
+    if (BinaryOperator::isComparisonOp(Op) || BinaryOperator::isLogicalOp(Op)) {
+      ASTContext &Ctx = getBasicVals().getContext();
+      *RetTy = Ctx.BoolTy;
+    } else {
+      *RetTy = LTy;
+    }
+
+    // If the two operands are pointers and the operation is a subtraction, the
+    // result is of type ptrdiff_t, which is signed
+    if (LTy->isAnyPointerType() && LTy == RTy && Op == BO_Sub) {
+      ASTContext &Ctx = getBasicVals().getContext();
+      *RetTy = Ctx.getIntTypeForBitwidth(Ctx.getTypeSize(LTy), true);
+    }
+  }
+
+  return LTy->isRealFloatingType()
+             ? Z3Expr::fromFloatBinOp(NewLHS, Op, NewRHS)
+             : Z3Expr::fromBinOp(NewLHS, Op, NewRHS,
+                                 LTy->isSignedIntegerOrEnumerationType());
+}
+
+//===------------------------------------------------------------------===//
+// Helper functions.
+//===------------------------------------------------------------------===//
+
+QualType Z3ConstraintManager::getAPSIntType(const llvm::APSInt &Int) const {
+  ASTContext &Ctx = getBasicVals().getContext();
+  return Ctx.getIntTypeForBitwidth(Int.getBitWidth(), Int.isSigned());
+}
+
+void Z3ConstraintManager::doTypeConversion(Z3Expr &LHS, Z3Expr &RHS,
+                                           QualType &LTy, QualType &RTy) const {
+  ASTContext &Ctx = getBasicVals().getContext();
+
+  // Perform type conversion
+  if (LTy->isIntegralOrEnumerationType() &&
+      RTy->isIntegralOrEnumerationType()) {
+    if (LTy->isArithmeticType() && RTy->isArithmeticType())
+      return doIntTypeConversion<Z3Expr, Z3Expr::fromCast>(LHS, LTy, RHS, RTy);
+  } else if (LTy->isRealFloatingType() || RTy->isRealFloatingType()) {
+    return doFloatTypeConversion<Z3Expr, Z3Expr::fromCast>(LHS, LTy, RHS, RTy);
+  } else if ((LTy->isAnyPointerType() || RTy->isAnyPointerType()) ||
+             (LTy->isBlockPointerType() || RTy->isBlockPointerType()) ||
+             (LTy->isReferenceType() || RTy->isReferenceType())) {
+    // TODO: Refactor to Sema::FindCompositePointerType(), and
+    // Sema::CheckCompareOperands().
+
+    uint64_t LBitWidth = Ctx.getTypeSize(LTy);
+    uint64_t RBitWidth = Ctx.getTypeSize(RTy);
+
+    // Cast the non-pointer type to the pointer type.
+    // TODO: Be more strict about this.
+    if ((LTy->isAnyPointerType() ^ RTy->isAnyPointerType()) ||
+        (LTy->isBlockPointerType() ^ RTy->isBlockPointerType()) ||
+        (LTy->isReferenceType() ^ RTy->isReferenceType())) {
+      if (LTy->isNullPtrType() || LTy->isBlockPointerType() ||
+          LTy->isReferenceType()) {
+        LHS = Z3Expr::fromCast(LHS, RTy, RBitWidth, LTy, LBitWidth);
+        LTy = RTy;
+      } else {
+        RHS = Z3Expr::fromCast(RHS, LTy, LBitWidth, RTy, RBitWidth);
+        RTy = LTy;
+      }
+    }
+
+    // Cast the void pointer type to the non-void pointer type.
+    // For void types, this assumes that the casted value is equal to the value
+    // of the original pointer, and does not account for alignment requirements.
+    if (LTy->isVoidPointerType() ^ RTy->isVoidPointerType()) {
+      assert((Ctx.getTypeSize(LTy) == Ctx.getTypeSize(RTy)) &&
+             "Pointer types have different bitwidths!");
+      if (RTy->isVoidPointerType())
+        RTy = LTy;
+      else
+        LTy = RTy;
+    }
+
+    if (LTy == RTy)
+      return;
+  }
+
+  // Fallback: for the solver, assume that these types don't really matter
+  if ((LTy.getCanonicalType() == RTy.getCanonicalType()) ||
+      (LTy->isObjCObjectPointerType() && RTy->isObjCObjectPointerType())) {
+    LTy = RTy;
+    return;
+  }
+
+  // TODO: Refine behavior for invalid type casts
+}
+
+template <typename T,
+          T(doCast)(const T &, QualType, uint64_t, QualType, uint64_t)>
+void Z3ConstraintManager::doIntTypeConversion(T &LHS, QualType &LTy, T &RHS,
+                                              QualType &RTy) const {
+  ASTContext &Ctx = getBasicVals().getContext();
+
+  uint64_t LBitWidth = Ctx.getTypeSize(LTy);
+  uint64_t RBitWidth = Ctx.getTypeSize(RTy);
+
+  // Always perform integer promotion before checking type equality.
+  // Otherwise, e.g. (bool) a + (bool) b could trigger a backend assertion
+  if (LTy->isPromotableIntegerType()) {
+    QualType NewTy = Ctx.getPromotedIntegerType(LTy);
+    uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
+    LHS = (*doCast)(LHS, NewTy, NewBitWidth, LTy, LBitWidth);
+    LTy = NewTy;
+    LBitWidth = NewBitWidth;
+  }
+  if (RTy->isPromotableIntegerType()) {
+    QualType NewTy = Ctx.getPromotedIntegerType(RTy);
+    uint64_t NewBitWidth = Ctx.getTypeSize(NewTy);
+    RHS = (*doCast)(RHS, NewTy, NewBitWidth, RTy, RBitWidth);
+    RTy = NewTy;
+    RBitWidth = NewBitWidth;
+  }
+
+  if (LTy == RTy)
+    return;
+
+  // Perform integer type conversion
+  // Note: Safe to skip updating bitwidth because this must terminate
+  bool isLSignedTy = LTy->isSignedIntegerOrEnumerationType();
+  bool isRSignedTy = RTy->isSignedIntegerOrEnumerationType();
+
+  int order = Ctx.getIntegerTypeOrder(LTy, RTy);
+  if (isLSignedTy == isRSignedTy) {
+    // Same signedness; use the higher-ranked type
+    if (order == 1) {
+      RHS = (*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+      RTy = LTy;
+    } else {
+      LHS = (*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+      LTy = RTy;
+    }
+  } else if (order != (isLSignedTy ? 1 : -1)) {
+    // The unsigned type has greater than or equal rank to the
+    // signed type, so use the unsigned type
+    if (isRSignedTy) {
+      RHS = (*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+      RTy = LTy;
+    } else {
+      LHS = (*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+      LTy = RTy;
+    }
+  } else if (LBitWidth != RBitWidth) {
+    // The two types are different widths; if we are here, that
+    // means the signed type is larger than the unsigned type, so
+    // use the signed type.
+    if (isLSignedTy) {
+      RHS = (*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+      RTy = LTy;
+    } else {
+      LHS = (*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+      LTy = RTy;
+    }
+  } else {
+    // The signed type is higher-ranked than the unsigned type,
+    // but isn't actually any bigger (like unsigned int and long
+    // on most 32-bit systems).  Use the unsigned type corresponding
+    // to the signed type.
+    QualType NewTy = Ctx.getCorrespondingUnsignedType(isLSignedTy ? LTy : RTy);
+    RHS = (*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+    RTy = NewTy;
+    LHS = (*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+    LTy = NewTy;
+  }
+}
+
+template <typename T,
+          T(doCast)(const T &, QualType, uint64_t, QualType, uint64_t)>
+void Z3ConstraintManager::doFloatTypeConversion(T &LHS, QualType &LTy, T &RHS,
+                                                QualType &RTy) const {
+  ASTContext &Ctx = getBasicVals().getContext();
+
+  uint64_t LBitWidth = Ctx.getTypeSize(LTy);
+  uint64_t RBitWidth = Ctx.getTypeSize(RTy);
+
+  // Perform float-point type promotion
+  if (!LTy->isRealFloatingType()) {
+    LHS = (*doCast)(LHS, RTy, RBitWidth, LTy, LBitWidth);
+    LTy = RTy;
+    LBitWidth = RBitWidth;
+  }
+  if (!RTy->isRealFloatingType()) {
+    RHS = (*doCast)(RHS, LTy, LBitWidth, RTy, RBitWidth);
+    RTy = LTy;
+    RBitWidth = LBitWidth;
+  }
+
+  if (LTy == RTy)
+    return;
+
+  // If we have two real floating types, convert the smaller operand to the
+  // bigger result
+  // Note: Safe to skip updating bitwidth because this must terminate
+  int order = Ctx.getFloatingTypeOrder(LTy, RTy);
+  if (order > 0) {
+    RHS = Z3Expr::fromCast(RHS, LTy, LBitWidth, RTy, RBitWidth);
+    RTy = LTy;
+  } else if (order == 0) {
+    LHS = Z3Expr::fromCast(LHS, RTy, RBitWidth, LTy, LBitWidth);
+    LTy = RTy;
+  } else {
+    llvm_unreachable("Unsupported floating-point type cast!");
+  }
+}
+
+llvm::APSInt Z3ConstraintManager::castAPSInt(const llvm::APSInt &V,
+                                             QualType ToTy, uint64_t ToWidth,
+                                             QualType FromTy,
+                                             uint64_t FromWidth) {
+  APSIntType TargetType(ToWidth, !ToTy->isSignedIntegerOrEnumerationType());
+  return TargetType.convert(V);
+}
+
+//==------------------------------------------------------------------------==/
+// Pretty-printing.
+//==------------------------------------------------------------------------==/
+
+void Z3ConstraintManager::print(ProgramStateRef St, raw_ostream &OS,
+                                const char *nl, const char *sep) {
+
+  ConstraintZ3Ty CZ = St->get<ConstraintZ3>();
+
+  OS << nl << sep << "Constraints:";
+  for (ConstraintZ3Ty::iterator I = CZ.begin(), E = CZ.end(); I != E; ++I) {
+    OS << nl << ' ' << I->first << " : ";
+    I->second.print(OS);
+  }
+  OS << nl;
+}
+
+#endif
+
+std::unique_ptr<ConstraintManager>
+ento::CreateZ3ConstraintManager(ProgramStateManager &StMgr, SubEngine *Eng) {
+#if CLANG_ANALYZER_WITH_Z3
+  return llvm::make_unique<Z3ConstraintManager>(Eng, StMgr.getSValBuilder());
+#else
+  llvm::report_fatal_error("Clang was not compiled with Z3 support!", false);
+  return nullptr;
+#endif
+}
diff --git a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index b3e287e..0fe0f3a 100644
--- a/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -615,8 +615,8 @@
            << OC->getIdentifier()->getNameStart() << ')';
       }
     } else if (const auto *OCD = dyn_cast<ObjCCategoryImplDecl>(DC)) {
-      OS << ((const NamedDecl *)OCD)->getIdentifier()->getNameStart() << '('
-         << OCD->getIdentifier()->getNameStart() << ')';
+      OS << OCD->getClassInterface()->getName() << '('
+         << OCD->getName() << ')';
     } else if (isa<ObjCProtocolDecl>(DC)) {
       // We can extract the type of the class from the self pointer.
       if (ImplicitParamDecl *SelfDecl = OMD->getSelfDecl()) {
diff --git a/test/APINotes/Inputs/APINotes/SomeOtherKit.apinotes b/test/APINotes/Inputs/APINotes/SomeOtherKit.apinotes
new file mode 100644
index 0000000..ccdc4e1
--- /dev/null
+++ b/test/APINotes/Inputs/APINotes/SomeOtherKit.apinotes
@@ -0,0 +1,8 @@
+Name: SomeOtherKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "methodB"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
diff --git a/test/APINotes/Inputs/BrokenHeaders/APINotes.apinotes b/test/APINotes/Inputs/BrokenHeaders/APINotes.apinotes
new file mode 100644
index 0000000..d547317
--- /dev/null
+++ b/test/APINotes/Inputs/BrokenHeaders/APINotes.apinotes
@@ -0,0 +1,4 @@
+Name: SomeBrokenLib
+Functions:
+  - Name: do_something_with_pointers
+    Nu llabilityOfRet: O
diff --git a/test/APINotes/Inputs/BrokenHeaders/SomeBrokenLib.h b/test/APINotes/Inputs/BrokenHeaders/SomeBrokenLib.h
new file mode 100644
index 0000000..b09c6f6
--- /dev/null
+++ b/test/APINotes/Inputs/BrokenHeaders/SomeBrokenLib.h
@@ -0,0 +1,6 @@
+#ifndef SOME_BROKEN_LIB_H
+#define SOME_BROKEN_LIB_H
+
+void do_something_with_pointers(int *ptr1, int *ptr2);
+
+#endif // SOME_BROKEN_LIB_H
diff --git a/test/APINotes/Inputs/BrokenHeaders2/APINotes.apinotes b/test/APINotes/Inputs/BrokenHeaders2/APINotes.apinotes
new file mode 100644
index 0000000..33eeaaa
--- /dev/null
+++ b/test/APINotes/Inputs/BrokenHeaders2/APINotes.apinotes
@@ -0,0 +1,7 @@
+Name: SomeBrokenLib
+Functions:
+  - Name: do_something_with_pointers
+    NullabilityOfRet: O
+  - Name: do_something_with_pointers
+    NullabilityOfRet: O
+    
diff --git a/test/APINotes/Inputs/BrokenHeaders2/SomeBrokenLib.h b/test/APINotes/Inputs/BrokenHeaders2/SomeBrokenLib.h
new file mode 100644
index 0000000..b09c6f6
--- /dev/null
+++ b/test/APINotes/Inputs/BrokenHeaders2/SomeBrokenLib.h
@@ -0,0 +1,6 @@
+#ifndef SOME_BROKEN_LIB_H
+#define SOME_BROKEN_LIB_H
+
+void do_something_with_pointers(int *ptr1, int *ptr2);
+
+#endif // SOME_BROKEN_LIB_H
diff --git a/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.apinotes b/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.apinotes
new file mode 100644
index 0000000..336f168
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.apinotes
@@ -0,0 +1,6 @@
+Name: SimpleKit
+Tags:
+- Name: RenamedAgainInAPINotesA
+  SwiftName: SuccessfullyRenamedA
+- Name: RenamedAgainInAPINotesB
+  SwiftName: SuccessfullyRenamedB
diff --git a/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.h b/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.h
new file mode 100644
index 0000000..c30a1e7
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.h
@@ -0,0 +1,7 @@
+struct RenamedAgainInAPINotesA {
+  int field;
+} __attribute__((swift_name("bad")));
+
+struct __attribute__((swift_name("bad"))) RenamedAgainInAPINotesB {
+  int field;
+};
diff --git a/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Modules/module.modulemap b/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..2d07e76
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module SimpleKit {
+  umbrella header "SimpleKit.h"
+  export *
+  module * { export * }
+}
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes
new file mode 100644
index 0000000..817af12
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit.apinotes
@@ -0,0 +1,74 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "transform:"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
+      - Selector: "transform:integer:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+    Properties:
+      - Name: intValue
+        PropertyKind:    Instance
+        Availability: none
+        AvailabilityMsg: "wouldn't work anyway"
+      - Name: nonnullAInstance
+        PropertyKind:    Instance
+        Nullability:     N
+      - Name: nonnullAClass
+        PropertyKind:    Class
+        Nullability:     N
+      - Name: nonnullABoth
+        Nullability:     N
+  - Name: B
+    Availability: none
+    AvailabilityMsg: "just don't"
+  - Name: C
+    Methods:
+      - Selector: "initWithA:"
+        MethodKind: Instance
+        DesignatedInit: true
+  - Name: OverriddenTypes
+    Methods:
+      - Selector: "methodToMangle:second:"
+        MethodKind: Instance
+        ResultType: 'char *'
+        Parameters:
+          - Position: 0
+            Type: 'SOMEKIT_DOUBLE *'
+          - Position: 1
+            Type: 'float *'
+    Properties:
+      - Name: intPropertyToMangle
+        PropertyKind: Instance
+        Type: 'double *'
+Functions:
+  - Name: global_int_fun
+    ResultType: 'char *'
+    Parameters:
+      - Position: 0
+        Type: 'double *'
+      - Position: 1
+        Type: 'float *'
+Globals:
+  - Name: global_int_ptr
+    Type: 'double *'
+SwiftVersions:
+  - Version: 3.0
+    Classes:
+      - Name: A
+        Methods:
+          - Selector: "transform:integer:"
+            MethodKind:      Instance
+            NullabilityOfRet: O
+            Nullability:      [ O, S ]
+        Properties:
+          - Name: explicitNonnullInstance
+            PropertyKind:    Instance
+            Nullability:     O
+          - Name: explicitNullableInstance
+            PropertyKind:    Instance
+            Nullability:     N
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit_private.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit_private.apinotes
new file mode 100644
index 0000000..28ede9d
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/APINotes/SomeKit_private.apinotes
@@ -0,0 +1,15 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:         
+      - Selector: "privateTransform:input:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+    Properties:
+      - Name: internalProperty
+        Nullability: N
+Protocols:
+  - Name: InternalProtocol
+    Availability: none
+    AvailabilityMsg: "not for you"
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
new file mode 100644
index 0000000..ff88fdb
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.apinotes
@@ -0,0 +1,98 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "transform:"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
+      - Selector: "transform:integer:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+      - Selector: "implicitGetOnlyInstance"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "implicitGetOnlyClass"
+        MethodKind:      Class
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "implicitGetSetInstance"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "implicitGetSetClass"
+        MethodKind:      Class
+        Availability:    none
+        AvailabilityMsg: "getter gone"
+      - Selector: "setImplicitGetSetInstance:"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "setter gone"
+      - Selector: "setImplicitGetSetClass:"
+        MethodKind:      Class
+        Availability:    none
+        AvailabilityMsg: "setter gone"
+    Properties:
+      - Name: intValue
+        PropertyKind:    Instance
+        Availability: none
+        AvailabilityMsg: "wouldn't work anyway"
+      - Name: nonnullAInstance
+        PropertyKind:    Instance
+        Nullability:     N
+      - Name: nonnullAClass
+        PropertyKind:    Class
+        Nullability:     N
+      - Name: nonnullABoth
+        Nullability:     N
+  - Name: B
+    Availability: none
+    AvailabilityMsg: "just don't"
+  - Name: C
+    Methods:
+      - Selector: "initWithA:"
+        MethodKind: Instance
+        DesignatedInit: true
+  - Name: OverriddenTypes
+    Methods:
+      - Selector: "methodToMangle:second:"
+        MethodKind: Instance
+        ResultType: 'char *'
+        Parameters:
+          - Position: 0
+            Type: 'SOMEKIT_DOUBLE *'
+          - Position: 1
+            Type: 'float *'
+    Properties:
+      - Name: intPropertyToMangle
+        PropertyKind: Instance
+        Type: 'double *'
+Functions:
+  - Name: global_int_fun
+    ResultType: 'char *'
+    Parameters:
+      - Position: 0
+        Type: 'double *'
+      - Position: 1
+        Type: 'float *'
+Globals:
+  - Name: global_int_ptr
+    Type: 'double (*)(int, int)'
+SwiftVersions:
+  - Version: 3.0
+    Classes:
+      - Name: A
+        Methods:
+          - Selector: "transform:integer:"
+            MethodKind:      Instance
+            NullabilityOfRet: O
+            Nullability:      [ O, S ]
+        Properties:
+          - Name: explicitNonnullInstance
+            PropertyKind:    Instance
+            Nullability:     O
+          - Name: explicitNullableInstance
+            PropertyKind:    Instance
+            Nullability:     N
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h
new file mode 100644
index 0000000..1a192f5
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKit.h
@@ -0,0 +1,60 @@
+#ifndef SOMEKIT_H
+#define SOMEKIT_H
+
+__attribute__((objc_root_class))
+@interface A
+-(A*)transform:(A*)input;
+-(A*)transform:(A*)input integer:(int)integer;
+
+@property (nonatomic, readonly, retain) A* someA;
+@property (nonatomic, retain) A* someOtherA;
+
+@property (nonatomic) int intValue;
+@end
+
+@interface B : A
+@end
+
+@interface C : A
+- (instancetype)init;
+- (instancetype)initWithA:(A*)a;
+@end
+
+@interface ProcessInfo : A
++(instancetype)processInfo;
+@end
+
+@interface A(NonNullProperties)
+@property (nonatomic, readwrite, retain) A *nonnullAInstance;
+@property (class, nonatomic, readwrite, retain) A *nonnullAInstance;
+
+@property (nonatomic, readwrite, retain) A *nonnullAClass;
+@property (class, nonatomic, readwrite, retain) A *nonnullAClass;
+
+@property (nonatomic, readwrite, retain) A *nonnullABoth;
+@property (class, nonatomic, readwrite, retain) A *nonnullABoth;
+@end
+
+#import <SomeKit/SomeKitExplicitNullability.h>
+
+extern int *global_int_ptr;
+
+int *global_int_fun(int *ptr, int *ptr2);
+
+#define SOMEKIT_DOUBLE double
+
+__attribute__((objc_root_class))
+@interface OverriddenTypes
+-(int *)methodToMangle:(int *)ptr1 second:(int *)ptr2;
+@property int *intPropertyToMangle;
+@end
+
+@interface A(ImplicitGetterSetters)
+@property (nonatomic, readonly, retain) A *implicitGetOnlyInstance;
+@property (class, nonatomic, readonly, retain) A *implicitGetOnlyClass;
+
+@property (nonatomic, readwrite, retain) A *implicitGetSetInstance;
+@property (class, nonatomic, readwrite, retain) A *implicitGetSetClass;
+@end
+
+#endif
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitExplicitNullability.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitExplicitNullability.h
new file mode 100644
index 0000000..40be241
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitExplicitNullability.h
@@ -0,0 +1,5 @@
+@interface A(ExplicitNullabilityProperties)
+@property (nonatomic, readwrite, retain, nonnull) A *explicitNonnullInstance;
+@property (nonatomic, readwrite, retain, nullable) A *explicitNullableInstance;
+@end
+
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitForNullAnnotation.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitForNullAnnotation.h
new file mode 100644
index 0000000..d1eeb61
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Headers/SomeKitForNullAnnotation.h
@@ -0,0 +1,55 @@
+#ifndef SOMEKIT_H
+#define SOMEKIT_H
+
+#define ROOT_CLASS __attribute__((objc_root_class))
+
+ROOT_CLASS
+@interface A
+-(A*)transform:(A*)input;
+-(A*)transform:(A*)input integer:(int)integer;
+
+@property (nonatomic, readonly, retain) A* someA;
+@property (nonatomic, retain) A* someOtherA;
+
+@property (nonatomic) int intValue;
+@end
+
+@interface B : A
+@end
+
+@interface C : A
+- (instancetype)init;
+- (instancetype)initWithA:(A*)a;
+@end
+
+
+@interface MyClass : A
+- Inst;
++ Clas;
+@end
+
+struct CGRect {
+  float origin;
+  float size;
+};
+typedef struct CGRect NSRect;
+
+@interface I
+- (void) Meth : (NSRect[4])exposedRects;
+- (void) Meth1 : (const  I*)exposedRects;
+- (void) Meth2 : (const I*)exposedRects;
+- (void) Meth3 : (I*)exposedRects;
+- (const I*) Meth4;
+- (const I*) Meth5 : (int) Arg1 : (const I*)Arg2 : (double)Arg3 :   (const I*) Arg4 :(const  volatile id) Arg5;
+- (volatile const I*) Meth6 : (const char *)Arg1 : (const char *)Arg2 : (double)Arg3 :   (const I*) Arg4 :(const  volatile id) Arg5;
+@end
+
+@class NSURL,  NSArray, NSError;
+@interface INTF_BLOCKS
+  + (void)getNonLocalVersionsOfItemAtURL:(NSURL *)url completionHandler:(void (^)(NSArray *nonLocalFileVersions, NSError *error))completionHandler;
+  + (void *)getNonLocalVersionsOfItemAtURL2:(NSURL *)url completionHandler:(void (^)(NSArray *nonLocalFileVersions, NSError *error))completionHandler;
+  + (NSError **)getNonLocalVersionsOfItemAtURL3:(int)url completionHandler:(void (^)(NSArray *nonLocalFileVersions, NSError *error))completionHandler;
+  + (id)getNonLocalVersionsOfItemAtURL4:(NSURL *)url completionHandler:(void (^)(int nonLocalFileVersions, NSError *error, NSURL*))completionHandler;
+@end
+
+#endif
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.modulemap b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..3abee2d
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module SomeKit {
+  umbrella header "SomeKit.h"
+  export *
+  module * { export * }
+}
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.private.modulemap b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..bbda9d0
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module.private.modulemap
@@ -0,0 +1,8 @@
+module SomeKit.Private {
+  header "SomeKit_Private.h"
+  export *
+
+  explicit module NullAnnotation {
+    header "SomeKit_PrivateForNullAnnotation.h"
+  }
+}
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module_private.modulemap b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module_private.modulemap
new file mode 100644
index 0000000..e310343
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/Modules/module_private.modulemap
@@ -0,0 +1,8 @@
+explicit framework module SomeKit.Private {
+  header "SomeKit_Private.h"
+  explicit NullAnnotation { header "SomeKit_PrivateForNullAnnotation.h" }
+  export *
+  module * { export * }
+syntax error
+
+}
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_Private.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_Private.h
new file mode 100644
index 0000000..c761112
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_Private.h
@@ -0,0 +1,16 @@
+#ifndef SOMEKIT_PRIVATE_H
+#define SOMEKIT_PRIVATE_H
+
+#import <SomeKit/SomeKit.h>
+
+@interface A(Private)
+-(A*)privateTransform:(A*)input;
+
+@property (nonatomic) A* internalProperty;
+@end
+
+@protocol InternalProtocol
+@end
+
+#endif
+
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_PrivateForNullAnnotation.h b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_PrivateForNullAnnotation.h
new file mode 100644
index 0000000..bae4456
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_PrivateForNullAnnotation.h
@@ -0,0 +1,17 @@
+#ifndef SOMEKIT_PRIVATE_H
+#define SOMEKIT_PRIVATE_H
+
+#import <SomeKit/SomeKitForNullAnnotation.h>
+
+@interface A(Private)
+-(A*)privateTransform:(A*)input;
+
+@property (nonatomic) A* internalProperty;
+@end
+
+@protocol InternalProtocol
+- (id) MomeMethod;
+@end
+
+#endif
+
diff --git a/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_private.apinotes b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_private.apinotes
new file mode 100644
index 0000000..28ede9d
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeKit.framework/PrivateHeaders/SomeKit_private.apinotes
@@ -0,0 +1,15 @@
+Name: SomeKit
+Classes:
+  - Name: A
+    Methods:         
+      - Selector: "privateTransform:input:"
+        MethodKind:      Instance
+        NullabilityOfRet: N
+        Nullability:      [ N, S ]
+    Properties:
+      - Name: internalProperty
+        Nullability: N
+Protocols:
+  - Name: InternalProtocol
+    Availability: none
+    AvailabilityMsg: "not for you"
diff --git a/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/APINotes/SomeOtherKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/APINotes/SomeOtherKit.apinotes
new file mode 100644
index 0000000..2ad546b
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/APINotes/SomeOtherKit.apinotes
@@ -0,0 +1,8 @@
+Name: SomeOtherKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "methodA"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
diff --git a/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes
new file mode 100644
index 0000000..2ad546b
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.apinotes
@@ -0,0 +1,8 @@
+Name: SomeOtherKit
+Classes:
+  - Name: A
+    Methods:
+      - Selector:        "methodA"
+        MethodKind:      Instance
+        Availability:    none
+        AvailabilityMsg: "anything but this"
diff --git a/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.h b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.h
new file mode 100644
index 0000000..3911d76
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.h
@@ -0,0 +1,9 @@
+#ifndef SOME_OTHER_KIT_H
+
+__attribute__((objc_root_class))
+@interface A
+-(void)methodA;
+-(void)methodB;
+@end
+
+#endif
diff --git a/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Modules/module.modulemap b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..0aaad92
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SomeOtherKit.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module SomeOtherKit {
+  umbrella header "SomeOtherKit.h"
+  export *
+  module * { export * }
+}
diff --git a/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.apinotes b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.apinotes
new file mode 100644
index 0000000..c02c6cb
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.apinotes
@@ -0,0 +1,92 @@
+Name: VersionedKit
+Classes:
+  - Name: TestProperties
+    SwiftObjCMembers: true
+    Properties:
+      - Name: accessorsOnly
+        PropertyKind:    Instance
+        SwiftImportAsAccessors: true
+      - Name: accessorsOnlyForClass
+        PropertyKind:    Class
+        SwiftImportAsAccessors: true
+      - Name: accessorsOnlyExceptInVersion3
+        PropertyKind:    Instance
+        SwiftImportAsAccessors: true
+      - Name: accessorsOnlyForClassExceptInVersion3
+        PropertyKind:    Class
+        SwiftImportAsAccessors: true
+Tags:
+  - Name: APINotedFlagEnum
+    FlagEnum: true
+  - Name: APINotedOpenEnum
+    EnumExtensibility: open
+  - Name: APINotedClosedEnum
+    EnumExtensibility: closed
+  - Name: SoonToBeCFEnum
+    EnumKind: CFEnum
+  - Name: SoonToBeNSEnum
+    EnumKind: NSEnum
+  - Name: SoonToBeCFOptions
+    EnumKind: CFOptions
+  - Name: SoonToBeNSOptions
+    EnumKind: NSOptions
+  - Name: SoonToBeCFClosedEnum
+    EnumKind: CFClosedEnum
+  - Name: SoonToBeNSClosedEnum
+    EnumKind: NSClosedEnum
+  - Name: UndoAllThatHasBeenDoneToMe
+    EnumKind: none
+SwiftVersions:
+  - Version: 3.0
+    Classes:
+      - Name: MyReferenceType
+        SwiftBridge: ''
+      - Name: TestGenericDUMP
+        SwiftImportAsNonGeneric: true
+      - Name: TestProperties
+        SwiftObjCMembers: false
+        Properties:
+          - Name: accessorsOnlyInVersion3
+            PropertyKind:    Instance
+            SwiftImportAsAccessors: true
+          - Name: accessorsOnlyForClassInVersion3
+            PropertyKind:    Class
+            SwiftImportAsAccessors: true
+          - Name: accessorsOnlyExceptInVersion3
+            PropertyKind:    Instance
+            SwiftImportAsAccessors: false
+          - Name: accessorsOnlyForClassExceptInVersion3
+            PropertyKind:    Class
+            SwiftImportAsAccessors: false
+      - Name: Swift3RenamedOnlyDUMP
+        SwiftName: SpecialSwift3Name
+      - Name: Swift3RenamedAlsoDUMP
+        SwiftName: SpecialSwift3Also
+    Functions:
+      - Name: moveToPointDUMP
+        SwiftName: 'moveTo(a:b:)'
+      - Name: acceptClosure
+        Parameters:      
+          - Position:        0
+            NoEscape:        false
+      - Name: privateFunc
+        SwiftPrivate: false
+    Tags:
+      - Name: MyErrorCode
+        NSErrorDomain: ''
+      - Name: NewlyFlagEnum
+        FlagEnum: false
+      - Name: OpenToClosedEnum
+        EnumExtensibility: open
+      - Name: ClosedToOpenEnum
+        EnumExtensibility: closed
+      - Name: NewlyClosedEnum
+        EnumExtensibility: none
+      - Name: NewlyOpenEnum
+        EnumExtensibility: none
+    Typedefs:
+      - Name: MyDoubleWrapper
+        SwiftWrapper: none
+
+
+  
\ No newline at end of file
diff --git a/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.h b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.h
new file mode 100644
index 0000000..61a1003
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.h
@@ -0,0 +1,112 @@
+void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(x:y:)")));
+
+void acceptClosure(void (^ __attribute__((noescape)) block)(void));
+
+@class NSString;
+
+extern NSString *MyErrorDomain;
+
+enum __attribute__((ns_error_domain(MyErrorDomain))) MyErrorCode {
+  MyErrorCodeFailed = 1
+};
+
+__attribute__((swift_bridge("MyValueType")))
+@interface MyReferenceType
+@end
+
+void privateFunc(void) __attribute__((swift_private));
+
+typedef double MyDoubleWrapper __attribute__((swift_wrapper(struct)));
+
+@interface TestProperties
+@property (nonatomic, readwrite, retain) id accessorsOnly;
+@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClass;
+
+@property (nonatomic, readwrite, retain) id accessorsOnlyInVersion3;
+@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClassInVersion3;
+
+@property (nonatomic, readwrite, retain) id accessorsOnlyExceptInVersion3;
+@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClassExceptInVersion3;
+@end
+
+@interface Base
+@end
+
+@interface TestGenericDUMP<Element> : Base
+- (Element)element;
+@end
+
+@interface Swift3RenamedOnlyDUMP
+@end
+
+__attribute__((swift_name("Swift4Name")))
+@interface Swift3RenamedAlsoDUMP
+@end
+
+
+enum __attribute__((flag_enum)) FlagEnum {
+  FlagEnumA = 1,
+  FlagEnumB = 2
+};
+
+enum __attribute__((flag_enum)) NewlyFlagEnum {
+  NewlyFlagEnumA = 1,
+  NewlyFlagEnumB = 2
+};
+
+enum APINotedFlagEnum {
+  APINotedFlagEnumA = 1,
+  APINotedFlagEnumB = 2
+};
+
+
+enum __attribute__((enum_extensibility(open))) OpenEnum {
+  OpenEnumA = 1,
+};
+
+enum __attribute__((enum_extensibility(open))) NewlyOpenEnum {
+  NewlyOpenEnumA = 1,
+};
+
+enum __attribute__((enum_extensibility(closed))) NewlyClosedEnum {
+  NewlyClosedEnumA = 1,
+};
+
+enum __attribute__((enum_extensibility(open))) ClosedToOpenEnum {
+  ClosedToOpenEnumA = 1,
+};
+
+enum __attribute__((enum_extensibility(closed))) OpenToClosedEnum {
+  OpenToClosedEnumA = 1,
+};
+
+enum APINotedOpenEnum {
+  APINotedOpenEnumA = 1,
+};
+
+enum APINotedClosedEnum {
+  APINotedClosedEnumA = 1,
+};
+
+
+enum SoonToBeCFEnum {
+  SoonToBeCFEnumA = 1
+};
+enum SoonToBeNSEnum {
+  SoonToBeNSEnumA = 1
+};
+enum SoonToBeCFOptions {
+  SoonToBeCFOptionsA = 1
+};
+enum SoonToBeNSOptions {
+  SoonToBeNSOptionsA = 1
+};
+enum SoonToBeCFClosedEnum {
+  SoonToBeCFClosedEnumA = 1
+};
+enum SoonToBeNSClosedEnum {
+  SoonToBeNSClosedEnumA = 1
+};
+enum UndoAllThatHasBeenDoneToMe {
+  UndoAllThatHasBeenDoneToMeA = 1
+} __attribute__((flag_enum)) __attribute__((enum_extensibility(closed)));
diff --git a/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Modules/module.modulemap b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Modules/module.modulemap
new file mode 100644
index 0000000..6d957fd
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module VersionedKit {
+  umbrella header "VersionedKit.h"
+  export *
+  module * { export * }
+}
diff --git a/test/APINotes/Inputs/Headers/APINotes.apinotes b/test/APINotes/Inputs/Headers/APINotes.apinotes
new file mode 100644
index 0000000..08210fc
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/APINotes.apinotes
@@ -0,0 +1,18 @@
+Name: HeaderLib
+SwiftInferImportAsMember: true
+Functions:
+  - Name: custom_realloc
+    NullabilityOfRet: N
+    Nullability: [ N, S ]
+  - Name: unavailable_function
+    Availability: none
+    AvailabilityMsg: "I beg you not to use this"
+  - Name: do_something_with_pointers
+    NullabilityOfRet: O
+    Nullability: [ N, O ]
+    
+Globals:
+  - Name: global_int
+    Nullability: N
+  - Name: unavailable_global_int
+    Availability: none
diff --git a/test/APINotes/Inputs/Headers/BrokenTypes.apinotes b/test/APINotes/Inputs/Headers/BrokenTypes.apinotes
new file mode 100644
index 0000000..00f7b50
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/BrokenTypes.apinotes
@@ -0,0 +1,10 @@
+Name: BrokenTypes
+Functions:
+  - Name: break_me_function
+    ResultType: 'int * with extra junk'
+    Parameters:
+      - Position: 0
+        Type: 'not_a_type'
+Globals:
+  - Name: break_me_variable
+    Type: 'double'
diff --git a/test/APINotes/Inputs/Headers/BrokenTypes.h b/test/APINotes/Inputs/Headers/BrokenTypes.h
new file mode 100644
index 0000000..fee054b
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/BrokenTypes.h
@@ -0,0 +1,8 @@
+#ifndef BROKEN_TYPES_H
+#define BROKEN_TYPES_H
+
+char break_me_function(void *ptr);
+
+extern char break_me_variable;
+
+#endif // BROKEN_TYPES_H
diff --git a/test/APINotes/Inputs/Headers/HeaderLib.apinotes b/test/APINotes/Inputs/Headers/HeaderLib.apinotes
new file mode 100644
index 0000000..c822964
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/HeaderLib.apinotes
@@ -0,0 +1,37 @@
+Name: HeaderLib
+SwiftInferImportAsMember: true
+Functions:
+  - Name: custom_realloc
+    NullabilityOfRet: N
+    Nullability: [ N, S ]
+  - Name: unavailable_function
+    Availability: none
+    AvailabilityMsg: "I beg you not to use this"
+  - Name: do_something_with_pointers
+    NullabilityOfRet: O
+    Nullability: [ N, O ]
+  - Name: do_something_with_arrays
+    Parameters:
+      - Position: 0
+        Nullability: N
+      - Position: 1
+        Nullability: N
+  - Name: take_pointer_and_int
+    Parameters:
+      - Position: 0
+        Nullability: N
+        NoEscape: true
+      - Position: 1
+        NoEscape: true
+Globals:
+  - Name: global_int
+    Nullability: N
+  - Name: unavailable_global_int
+    Availability: none
+Tags:
+  - Name: unavailable_struct
+    Availability: none
+
+Typedefs:
+  - Name: unavailable_typedef
+    Availability: none
\ No newline at end of file
diff --git a/test/APINotes/Inputs/Headers/HeaderLib.h b/test/APINotes/Inputs/Headers/HeaderLib.h
new file mode 100644
index 0000000..8065249
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/HeaderLib.h
@@ -0,0 +1,19 @@
+#ifndef HEADER_LIB_H
+#define HEADER_LIB_H
+
+void *custom_realloc(void *member, unsigned size);
+
+int *global_int;
+
+int unavailable_function(void);
+int unavailable_global_int;
+
+void do_something_with_pointers(int *ptr1, int *ptr2);
+void do_something_with_arrays(int simple[], int nested[][2]);
+
+typedef int unavailable_typedef;
+struct unavailable_struct { int x, y, z; };
+
+void take_pointer_and_int(int *ptr1, int value);
+
+#endif
diff --git a/test/APINotes/Inputs/Headers/module.modulemap b/test/APINotes/Inputs/Headers/module.modulemap
new file mode 100644
index 0000000..54af0f5
--- /dev/null
+++ b/test/APINotes/Inputs/Headers/module.modulemap
@@ -0,0 +1,7 @@
+module HeaderLib {
+  header "HeaderLib.h"
+}
+
+module BrokenTypes {
+  header "BrokenTypes.h"
+}
diff --git a/test/APINotes/Inputs/os-availability.apinotes b/test/APINotes/Inputs/os-availability.apinotes
new file mode 100644
index 0000000..d59e79c
--- /dev/null
+++ b/test/APINotes/Inputs/os-availability.apinotes
@@ -0,0 +1,53 @@
+Name:            Foundation
+Classes:
+  - Name:            NSCountedSet
+    Availability:    iOS
+    Methods:
+      - Selector:        'initWithCapacity:'
+        MethodKind:      Instance
+        DesignatedInit:  true
+  - Name:            NSArray
+    Methods:
+      - Selector:        'init'
+        MethodKind:      Instance
+        DesignatedInit:  true
+      - Selector:        'initWithObjects:'
+        MethodKind:      Instance
+        DesignatedInit:  true
+        Availability:    iOS
+      - Selector:        'initWithObjects:count:'
+        MethodKind:      Instance
+        DesignatedInit:  true
+        Availability:    iOS
+    Properties:
+      - Name:            'familyNameios'
+        Nullability:     N
+        Availability:    iOS
+      - Name:            'fontName'
+        Nullability:     N
+Protocols:        
+  - Name:            UIApplicationDelegate
+    AuditedForNullability: true
+    Methods:
+      - Selector:        'application:willFinishLaunchingWithOptions:'
+        MethodKind:      Instance
+        Nullability:     [ N, U ]
+  - Name:            UIApplicationDelegateIOS
+    Availability:    iOS
+    AuditedForNullability: true
+    Methods:
+      - Selector:        'application:willFinishLaunchingWithOptions:'
+        MethodKind:      Instance
+        Nullability:     [ N, U ]
+Functions:       
+  - Name:            NSAvailableWindowDepthsiOS
+    NullabilityOfRet: N
+    Availability:    iOS
+  - Name:            NSAvailableWindowDepths
+    NullabilityOfRet: N
+Globals:         
+  - Name:            NSCalibratedWhiteColorSpace
+    Nullability:     N
+    Availability:    OSX
+    AvailabilityMsg: ''
+
diff --git a/test/APINotes/Inputs/roundtrip.apinotes b/test/APINotes/Inputs/roundtrip.apinotes
new file mode 100644
index 0000000..65e3928
--- /dev/null
+++ b/test/APINotes/Inputs/roundtrip.apinotes
@@ -0,0 +1,185 @@
+---
+Name:            AppKit
+Availability:    available
+AvailabilityMsg: ''
+SwiftInferImportAsMember: true
+Classes:         
+  - Name:            NSCell
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       ''
+    SwiftImportAsNonGeneric: true
+    SwiftObjCMembers: false
+    Methods:         
+      - Selector:        'cellWithImage:'
+        MethodKind:      Class
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        ResultType:      id
+      - Selector:        init
+        MethodKind:      Instance
+        NullabilityOfRet: U
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    true
+        SwiftName:       ''
+        DesignatedInit:  true
+      - Selector:        'initImageCell:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: U
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        DesignatedInit:  true
+      - Selector:        'initTextCell:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: U
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        DesignatedInit:  true
+      - Selector:        'initWithCoder:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: U
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        DesignatedInit:  true
+        Required:        true
+  - Name:            NSView
+    AuditedForNullability: true
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       ''
+    SwiftBridge:     View
+    SwiftObjCMembers: true
+    Methods:         
+      - Selector:        'addSubview:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: N
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+      - Selector:        'addSubview:positioned:relativeTo:'
+        MethodKind:      Instance
+        Parameters:      
+          - Position:        0
+            NoEscape:        false
+          - Position:        1
+          - Position:        2
+            NoEscape:        true
+            Type:            id
+        Nullability:     [ N, N, O ]
+        NullabilityOfRet: N
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftName:       ''
+      - Selector:        'beginDraggingSessionWithItems:event:source:'
+        MethodKind:      Instance
+        Nullability:     [ U, U, N ]
+        NullabilityOfRet: N
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       'beginDragginSession(_:event:source:)'
+    Properties:      
+      - Name:            enclosingScrollView
+        PropertyKind:    Instance
+        Nullability:     O
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftName:       enclosing
+        Type:            id
+      - Name:            makeBackingLayer
+        PropertyKind:    Class
+        Nullability:     N
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       ''
+        SwiftImportAsAccessors: false
+Functions:       
+  - Name:            NSAvailableWindowDepths
+    NullabilityOfRet: N
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftName:       'availableWindowDepths()'
+    ResultType:      NSInteger
+Globals:         
+  - Name:            NSCalibratedWhiteColorSpace
+    Nullability:     N
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       calibratedWhite
+    Type:            id
+Enumerators:     
+  - Name:            NSColorRed
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       Red
+Tags:            
+  - Name:            NSSomeEnum
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       SomeEnum
+    NSErrorDomain:   some_error_domain
+    EnumExtensibility: closed
+    FlagEnum:        false
+  - Name:            NSSomeStruct
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       SomeStruct
+    NSErrorDomain:   ''
+Typedefs:        
+  - Name:            NSTypedef
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftPrivate:    false
+    SwiftName:       Typedef
+    SwiftBridge:     ''
+    SwiftWrapper:    struct
+SwiftVersions:   
+  - Version:         3.0
+    Classes:         
+      - Name:            NSCell
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftPrivate:    false
+        SwiftName:       NSBox
+        SwiftBridge:     ''
+        Methods:         
+          - Selector:        init
+            MethodKind:      Instance
+            NullabilityOfRet: N
+            Availability:    available
+            AvailabilityMsg: ''
+            SwiftPrivate:    true
+            SwiftName:       ''
+            DesignatedInit:  true
+      - Name:            NSView
+        Availability:    available
+        AvailabilityMsg: ''
+        SwiftName:       ''
+        Properties:      
+          - Name:            makeBackingLayer
+            PropertyKind:    Class
+            Availability:    available
+            AvailabilityMsg: ''
+            SwiftName:       ''
+            SwiftImportAsAccessors: true
diff --git a/test/APINotes/availability.m b/test/APINotes/availability.m
new file mode 100644
index 0000000..f9bee1a
--- /dev/null
+++ b/test/APINotes/availability.m
@@ -0,0 +1,48 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+#include "HeaderLib.h"
+#import <SomeKit/SomeKit.h>
+#import <SomeKit/SomeKit_Private.h>
+
+int main() {
+  int i;
+  i = unavailable_function(); // expected-error{{'unavailable_function' is unavailable: I beg you not to use this}}
+  // expected-note@HeaderLib.h:8{{'unavailable_function' has been explicitly marked unavailable here}}
+  i = unavailable_global_int; // expected-error{{'unavailable_global_int' is unavailable}}
+  // expected-note@HeaderLib.h:9{{'unavailable_global_int' has been explicitly marked unavailable here}}
+
+  unavailable_typedef t; // expected-error{{'unavailable_typedef' is unavailable}}
+  // expected-note@HeaderLib.h:14{{'unavailable_typedef' has been explicitly marked unavailable here}}
+
+  struct unavailable_struct s; // expected-error{{'unavailable_struct' is unavailable}}
+  // expected-note@HeaderLib.h:15{{'unavailable_struct' has been explicitly marked unavailable here}}
+
+  B *b = 0; // expected-error{{'B' is unavailable: just don't}}
+  // expected-note@SomeKit/SomeKit.h:15{{'B' has been explicitly marked unavailable here}}
+
+  id<InternalProtocol> proto = 0; // expected-error{{'InternalProtocol' is unavailable: not for you}}
+  // expected-note@SomeKit/SomeKit_Private.h:12{{'InternalProtocol' has been explicitly marked unavailable here}}
+
+  A *a = 0;
+  i = a.intValue; // expected-error{{intValue' is unavailable: wouldn't work anyway}}
+  // expected-note@SomeKit/SomeKit.h:12{{'intValue' has been explicitly marked unavailable here}}
+
+  [a transform:a]; // expected-error{{'transform:' is unavailable: anything but this}}
+  // expected-note@SomeKit/SomeKit.h:6{{'transform:' has been explicitly marked unavailable here}}
+
+  [a implicitGetOnlyInstance]; // expected-error{{'implicitGetOnlyInstance' is unavailable: getter gone}}
+  // expected-note@SomeKit/SomeKit.h:53{{'implicitGetOnlyInstance' has been explicitly marked unavailable here}}
+  [A implicitGetOnlyClass]; // expected-error{{'implicitGetOnlyClass' is unavailable: getter gone}}
+  // expected-note@SomeKit/SomeKit.h:54{{'implicitGetOnlyClass' has been explicitly marked unavailable here}}
+  [a implicitGetSetInstance]; // expected-error{{'implicitGetSetInstance' is unavailable: getter gone}}
+  // expected-note@SomeKit/SomeKit.h:56{{'implicitGetSetInstance' has been explicitly marked unavailable here}}
+  [a setImplicitGetSetInstance: a];  // expected-error{{'setImplicitGetSetInstance:' is unavailable: setter gone}}
+  // expected-note@SomeKit/SomeKit.h:56{{'setImplicitGetSetInstance:' has been explicitly marked unavailable here}}
+  [A implicitGetSetClass]; // expected-error{{'implicitGetSetClass' is unavailable: getter gone}}
+  // expected-note@SomeKit/SomeKit.h:57{{'implicitGetSetClass' has been explicitly marked unavailable here}}
+  [A setImplicitGetSetClass: a];  // expected-error{{'setImplicitGetSetClass:' is unavailable: setter gone}}
+  // expected-note@SomeKit/SomeKit.h:57{{'setImplicitGetSetClass:' has been explicitly marked unavailable here}}
+  return 0;
+}
+
diff --git a/test/APINotes/broken_types.m b/test/APINotes/broken_types.m
new file mode 100644
index 0000000..164ae79
--- /dev/null
+++ b/test/APINotes/broken_types.m
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s 2> %t.err
+// RUN: FileCheck %s < %t.err
+
+#include "BrokenTypes.h"
+
+// CHECK: <API Notes>:1:1: error: unknown type name 'not_a_type'
+// CHECK-NEXT: not_a_type
+// CHECK-NEXT: ^
+
+// CHECK: <API Notes>:1:7: error: unparsed tokens following type
+// CHECK-NEXT: int * with extra junk
+// CHECK-NEXT:       ^
+
+// CHECK: BrokenTypes.h:4:6: error: API notes replacement type 'int *' has a different size from original type 'char'
+
+// CHECK: BrokenTypes.h:6:13: error: API notes replacement type 'double' has a different size from original type 'char'
+
+// CHECK: 5 errors generated.
diff --git a/test/APINotes/cache.m b/test/APINotes/cache.m
new file mode 100644
index 0000000..b87bdf1
--- /dev/null
+++ b/test/APINotes/cache.m
@@ -0,0 +1,32 @@
+// RUN: rm -rf %t/APINotesCache
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+// Check for the presence of the cached compiled form.
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+
+// Run test again to ensure that caching doesn't cause problems.
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks  %s -verify
+
+// Check that the driver provides a default -fapinotes-cache-path=
+// RUN: %clang -fsyntax-only -fapinotes -fapinotes-modules -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -### 2>&1 | FileCheck --check-prefix=CHECK-DEFAULT-PATH %s
+// CHECK-DEFAULT-PATH: -fapinotes-cache-path={{.*}}org.llvm.clang/APINotesCache
+
+// Check that the driver passes through a provided -fapinotes-cache-path=
+// RUN: %clang -fsyntax-only -fapinotes -fapinotes-modules -fapinotes-cache-path=/wobble -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -### 2>&1 | FileCheck --check-prefix=CHECK-PATH %s
+// CHECK-PATH: -fapinotes-cache-path=/wobble
+
+#include "HeaderLib.h"
+#import <SomeKit/SomeKit.h>
+
+int main() {
+  int i;
+  i = unavailable_function(); // expected-error{{'unavailable_function' is unavailable: I beg you not to use this}}
+  // expected-note@HeaderLib.h:8{{'unavailable_function' has been explicitly marked unavailable here}}
+
+  A *a = 0;
+  [a transform:a]; // expected-error{{'transform:' is unavailable: anything but this}}
+  // expected-note@SomeKit/SomeKit.h:6{{'transform:' has been explicitly marked unavailable here}}
+
+  return 0;
+}
diff --git a/test/APINotes/cache_pruning.m b/test/APINotes/cache_pruning.m
new file mode 100644
index 0000000..1a36570
--- /dev/null
+++ b/test/APINotes/cache_pruning.m
@@ -0,0 +1,49 @@
+// We need 'touch' and 'find' for this test to work.
+// REQUIRES: shell
+
+// RUN: rm -rf %t/APINotesCache
+
+// Run Clang. This should generated the cached versions of both and a timestamp.
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DINCLUDE_HEADERLIB
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+// Set the timestamp back a very long time. We should try to prune,
+// but nothing gets pruned because the API Notes files are new enough.
+// RUN: touch -m -a -t 201101010000 %t/APINotes.timestamp 
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+// Set the HeaderLib access time back a very long time.
+// This shouldn't prune anything, because the timestamp has been updated, so
+// the pruning mechanism won't fire.
+// RUN: find %t/APINotesCache -name APINotes-*.apinotesc | xargs touch -a -t 201101010000
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+// Set the timestack back a very long time. This should prune the
+// HeaderLib file, because the pruning mechanism should fire and
+// HeaderLib is both old and not used.
+// RUN: touch -m -a -t 201101010000 %t/APINotesCache/APINotes.timestamp 
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: ls %t/APINotesCache | not grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+// Run Clang. This should generated the cached versions of both and a timestamp.
+// RUN: %clang_cc1 -fapinotes -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DINCLUDE_HEADERLIB
+// RUN: ls %t/APINotesCache | grep "APINotes-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "SomeKit-.*.apinotesc"
+// RUN: ls %t/APINotesCache | grep "APINotes.timestamp"
+
+#ifdef INCLUDE_HEADERLIB
+#include "HeaderLib.h"
+#endif
+#include <SomeKit/SomeKit.h>
+
+int main() { return 0; }
diff --git a/test/APINotes/module-cache.m b/test/APINotes/module-cache.m
new file mode 100644
index 0000000..2324697
--- /dev/null
+++ b/test/APINotes/module-cache.m
@@ -0,0 +1,90 @@
+// RUN: rm -rf %t
+
+// Set up a directory with API notes
+// RUN: mkdir -p %t/APINotes
+// RUN: cp %S/Inputs/APINotes/SomeOtherKit.apinotes %t/APINotes/SomeOtherKit.apinotes
+
+// First build: check that 'methodB' is unavailable but 'methodA' is available.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/before.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/before.log
+// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/before.log
+// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/before.log
+
+// Do it again; now we're using caches.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/before.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/before.log
+// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/before.log
+// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/before.log
+
+// Change the API notes file.
+// RUN: echo '      - Selector: "methodA"' >> %t/APINotes/SomeOtherKit.apinotes
+// RUN: echo '        MethodKind: Instance' >> %t/APINotes/SomeOtherKit.apinotes
+// RUN: echo '        Availability: none' >> %t/APINotes/SomeOtherKit.apinotes
+// RUN: echo '        AvailabilityMsg: "not here either"' >> %t/APINotes/SomeOtherKit.apinotes
+
+// Build again: check that both methods are now unavailable and that the module rebuilt.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/after.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/after.log
+
+// Run the build again: check that both methods are now unavailable
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/after.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/after.log
+// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/after.log
+
+// Set up a directory with pre-compiled API notes.
+// RUN: mkdir -p %t/CompiledAPINotes
+// RUN: rm -rf %t/ModulesCache
+// RUN: rm -rf %t/APINotesCache
+// RUN: %clang -cc1apinotes -yaml-to-binary -o %t/CompiledAPINotes/SomeOtherKit.apinotesc %S/Inputs/APINotes/SomeOtherKit.apinotes
+
+// First build: check that 'methodB' is unavailable but 'methodA' is available.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/CompiledAPINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/compiled-before.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/compiled-before.log
+// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/compiled-before.log
+// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/compiled-before.log
+
+// Do it again; now we're using caches.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/CompiledAPINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/compiled-before.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/compiled-before.log
+// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/compiled-before.log
+// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/compiled-before.log
+
+// Compile a new API notes file to replace the old one.
+// RUN: %clang -cc1apinotes -yaml-to-binary -o %t/CompiledAPINotes/SomeOtherKit.apinotesc %t/APINotes/SomeOtherKit.apinotes
+
+// Build again: check that both methods are now unavailable and that the module rebuilt.
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/CompiledAPINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/compiled-after.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/compiled-after.log
+
+// Run the build again: check that both methods are now unavailable
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/CompiledAPINotes -fapinotes-cache-path=%t/APINotesCache -F %S/Inputs/Frameworks %s > %t/compiled-after.log 2>&1
+// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/compiled-after.log
+// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/compiled-after.log
+
+@import SomeOtherKit;
+
+void test(A *a) {
+  // CHECK-METHODA: error: 'methodA' is unavailable: not here either
+  [a methodA];
+
+  // CHECK-METHODB: error: 'methodB' is unavailable: anything but this
+  [a methodB];
+}
+
+// CHECK-REBUILD: remark: building module{{.*}}SomeOtherKit
+
+// CHECK-WITHOUT-REBUILD-NOT: remark: building module{{.*}}SomeOtherKit
+
+// CHECK-ONE-ERROR: 1 error generated.
+// CHECK-TWO-ERRORS: 2 errors generated.
+
diff --git a/test/APINotes/nullability.c b/test/APINotes/nullability.c
new file mode 100644
index 0000000..1fcd0ee
--- /dev/null
+++ b/test/APINotes/nullability.c
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+#include "HeaderLib.h"
+
+int main() {
+  custom_realloc(0, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}
+  int i = 0;
+  do_something_with_pointers(&i, 0);
+  do_something_with_pointers(0, &i); // expected-warning{{null passed to a callee that requires a non-null argument}}
+  
+  extern void *p;
+  do_something_with_arrays(0, p); // expected-warning{{null passed to a callee that requires a non-null argument}}
+  do_something_with_arrays(p, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}
+
+  take_pointer_and_int(0, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}
+
+  float *fp = global_int; // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'int * _Nonnull'}}
+  return 0;
+}
+
diff --git a/test/APINotes/nullability.m b/test/APINotes/nullability.m
new file mode 100644
index 0000000..f70c363
--- /dev/null
+++ b/test/APINotes/nullability.m
@@ -0,0 +1,44 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+// Test with Swift version 3.0. This should only affect the few APIs that have an entry in the 3.0 tables.
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fapinotes-swift-version=3.0 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify -DSWIFT_VERSION_3_0 -fmodules-ignore-macro=SWIFT_VERSION_3_0
+
+#import <SomeKit/SomeKit.h>
+
+int main() {
+  A *a;
+
+#if SWIFT_VERSION_3_0
+  float *fp =  // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'A * _Nullable'}}
+    [a transform: 0 integer: 0];
+#else
+  float *fp =  // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'A *'}}
+    [a transform: 0 integer: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+#endif
+
+  [a setNonnullAInstance: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+  [A setNonnullAInstance: 0]; // no warning
+  
+  [a setNonnullAClass: 0]; // no warning
+  [A setNonnullAClass: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+
+  [a setNonnullABoth: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+  [A setNonnullABoth: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+
+  [a setInternalProperty: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+
+#if SWIFT_VERSION_3_0
+  // Version 3 information overrides header information.
+  [a setExplicitNonnullInstance: 0]; //  okay
+  [a setExplicitNullableInstance: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+#else
+  // Header information overrides unversioned information.
+  [a setExplicitNonnullInstance: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
+  [a setExplicitNullableInstance: 0]; // okay
+#endif
+
+  return 0;
+}
+
diff --git a/test/APINotes/objc_designated_inits.m b/test/APINotes/objc_designated_inits.m
new file mode 100644
index 0000000..1df8cf8
--- /dev/null
+++ b/test/APINotes/objc_designated_inits.m
@@ -0,0 +1,17 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+
+#include "HeaderLib.h"
+#import <SomeKit/SomeKit.h>
+
+@interface CSub : C
+-(instancetype)initWithA:(A*)a;
+@end
+
+@implementation CSub
+-(instancetype)initWithA:(A*)a { // expected-warning{{designated initializer missing a 'super' call to a designated initializer of the super class}}
+  // expected-note@SomeKit/SomeKit.h:20 2{{method marked as designated initializer of the class here}}
+  self = [super init]; // expected-warning{{designated initializer invoked a non-designated initializer}}
+  return self;
+}
+@end
diff --git a/test/APINotes/properties.m b/test/APINotes/properties.m
new file mode 100644
index 0000000..b1559b9
--- /dev/null
+++ b/test/APINotes/properties.m
@@ -0,0 +1,45 @@
+// RUN: rm -rf %t && mkdir -p %t
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fblocks -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter 'TestProperties::' | FileCheck -check-prefix=CHECK -check-prefix=CHECK-4 %s
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fblocks -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter 'TestProperties::' -fapinotes-swift-version=3 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-3 %s
+
+// I know, FileChecking an AST dump is brittle. However, the attributes being
+// tested aren't used for anything by Clang, and don't even have a spelling.
+
+@import VersionedKit;
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnly 'id'
+// CHECK-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyForClass 'id'
+// CHECK-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyInVersion3 'id'
+// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-4-NEXT: SwiftVersionedAttr {{.+}} 3.0
+// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyForClassInVersion3 'id'
+// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-4-NEXT: SwiftVersionedAttr {{.+}} 3.0
+// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyExceptInVersion3 'id'
+// CHECK-3-NEXT: SwiftVersionedAttr {{.+}} 0{{$}}
+// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-4-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 3.0 {{[0-9]+}}
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyForClassExceptInVersion3 'id'
+// CHECK-3-NEXT: SwiftVersionedAttr {{.+}} 0{{$}}
+// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} Implicit
+// CHECK-4-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 3.0 {{[0-9]+}}
+// CHECK-NOT: Attr
+
+// CHECK-LABEL: Decl
diff --git a/test/APINotes/search-order.m b/test/APINotes/search-order.m
new file mode 100644
index 0000000..2c667be
--- /dev/null
+++ b/test/APINotes/search-order.m
@@ -0,0 +1,25 @@
+// RUN: rm -rf %t && mkdir -p %t
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DFROM_FRAMEWORK=1 -verify
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %S/Inputs/APINotes -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DFROM_SEARCH_PATH=1 -verify
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -iapinotes-modules %S/Inputs/APINotes -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DFROM_FRAMEWORK=1 -verify
+
+@import SomeOtherKit;
+
+void test(A *a) {
+#if FROM_FRAMEWORK
+  [a methodA]; // expected-error{{unavailable}}
+  [a methodB];
+
+  // expected-note@SomeOtherKit/SomeOtherKit.h:5{{'methodA' has been explicitly marked unavailable here}}
+#elif FROM_SEARCH_PATH
+  [a methodA];
+  [a methodB]; // expected-error{{unavailable}}
+
+  // expected-note@SomeOtherKit/SomeOtherKit.h:6{{'methodB' has been explicitly marked unavailable here}}
+#else
+#  error Not something we need to test
+#endif
+}
diff --git a/test/APINotes/types.m b/test/APINotes/types.m
new file mode 100644
index 0000000..9f8b970
--- /dev/null
+++ b/test/APINotes/types.m
@@ -0,0 +1,28 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fdisable-module-hash -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
+// RUN: %clang_cc1 -ast-print %t/ModulesCache/SimpleKit.pcm | FileCheck %s
+
+#import <SomeKit/SomeKit.h>
+#import <SimpleKit/SimpleKit.h>
+
+// CHECK: struct __attribute__((swift_name("SuccessfullyRenamedA"))) RenamedAgainInAPINotesA {
+// CHECK: struct __attribute__((swift_name("SuccessfullyRenamedB"))) RenamedAgainInAPINotesB {
+
+void test(OverriddenTypes *overridden) {
+  int *ip1 = global_int_ptr; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'double (*)(int, int)'}}
+
+  int *ip2 = global_int_fun( // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'char *'}}
+               ip2, // expected-warning{{incompatible pointer types passing 'int *' to parameter of type 'double *'}}
+               ip2); // expected-warning{{incompatible pointer types passing 'int *' to parameter of type 'float *'}}
+
+  int *ip3 = [overridden // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'char *'}}
+                methodToMangle: ip3 // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'double *'}}
+                        second: ip3]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'float *'}}
+
+  int *ip4 = overridden.intPropertyToMangle; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'double *'}}
+}
+
+// expected-note@SomeKit/SomeKit.h:42{{passing argument to parameter 'ptr' here}}
+// expected-note@SomeKit/SomeKit.h:42{{passing argument to parameter 'ptr2' here}}
+// expected-note@SomeKit/SomeKit.h:48{{passing argument to parameter 'ptr1' here}}
+// expected-note@SomeKit/SomeKit.h:48{{passing argument to parameter 'ptr2' here}}
diff --git a/test/APINotes/versioned.m b/test/APINotes/versioned.m
new file mode 100644
index 0000000..5657ae1
--- /dev/null
+++ b/test/APINotes/versioned.m
@@ -0,0 +1,172 @@
+// RUN: rm -rf %t && mkdir -p %t
+
+// Build and check the unversioned module file.
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Unversioned -fdisable-module-hash -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: %clang_cc1 -ast-print %t/ModulesCache/Unversioned/VersionedKit.pcm | FileCheck -check-prefix=CHECK-UNVERSIONED %s
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Unversioned -fdisable-module-hash -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter 'DUMP' | FileCheck -check-prefix=CHECK-DUMP -check-prefix=CHECK-UNVERSIONED-DUMP %s
+
+// Build and check the versioned module file.
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Versioned -fdisable-module-hash -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fapinotes-swift-version=3 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: %clang_cc1 -ast-print %t/ModulesCache/Versioned/VersionedKit.pcm | FileCheck -check-prefix=CHECK-VERSIONED %s
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Versioned -fdisable-module-hash -fapinotes-modules -fapinotes-cache-path=%t/APINotesCache -fapinotes-swift-version=3 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter 'DUMP' | FileCheck -check-prefix=CHECK-DUMP -check-prefix=CHECK-VERSIONED-DUMP %s
+
+#import <VersionedKit/VersionedKit.h>
+
+// CHECK-UNVERSIONED: void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(x:y:)")));
+// CHECK-VERSIONED: void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(a:b:)")));
+
+// CHECK-DUMP-LABEL: Dumping moveToPointDUMP
+// CHECK-VERSIONED-DUMP: SwiftVersionedAttr {{.+}} Implicit 0
+// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} "moveTo(x:y:)"
+// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "moveTo(a:b:)"
+// CHECK-UNVERSIONED-DUMP: SwiftNameAttr {{.+}} "moveTo(x:y:)"
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "moveTo(a:b:)"
+// CHECK-DUMP-NOT: Attr
+
+// CHECK-DUMP-LABEL: Dumping TestGenericDUMP
+// CHECK-VERSIONED-DUMP: SwiftImportAsNonGenericAttr {{.+}} Implicit
+// CHECK-UNVERSIONED-DUMP: SwiftVersionedAttr {{.+}} Implicit 3.0
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftImportAsNonGenericAttr {{.+}} Implicit
+// CHECK-DUMP-NOT: Attr
+
+// CHECK-DUMP-LABEL: Dumping Swift3RenamedOnlyDUMP
+// CHECK-DUMP: in VersionedKit Swift3RenamedOnlyDUMP
+// CHECK-VERSIONED-DUMP-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 0 {{[0-9]+}}
+// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} "SpecialSwift3Name"
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "SpecialSwift3Name"
+// CHECK-DUMP-NOT: Attr
+
+// CHECK-DUMP-LABEL: Dumping Swift3RenamedAlsoDUMP
+// CHECK-DUMP: in VersionedKit Swift3RenamedAlsoDUMP
+// CHECK-VERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 0
+// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} <line:{{.+}}, col:{{.+}}> "Swift4Name"
+// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} "SpecialSwift3Also"
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} <line:{{.+}}, col:{{.+}}> "Swift4Name"
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 3.0
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "SpecialSwift3Also"
+// CHECK-DUMP-NOT: Attr
+
+// CHECK-DUMP-NOT: Dumping
+
+// CHECK-UNVERSIONED: void acceptClosure(void (^block)(void) __attribute__((noescape)));
+// CHECK-VERSIONED: void acceptClosure(void (^block)(void));
+
+// CHECK-UNVERSIONED:      enum MyErrorCode {
+// CHECK-UNVERSIONED-NEXT:     MyErrorCodeFailed = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((ns_error_domain(MyErrorDomain)));
+
+// CHECK-UNVERSIONED: __attribute__((swift_bridge("MyValueType")))
+// CHECK-UNVERSIONED: @interface MyReferenceType
+
+// CHECK-UNVERSIONED: void privateFunc() __attribute__((swift_private));
+
+// CHECK-UNVERSIONED: typedef double MyDoubleWrapper __attribute__((swift_wrapper("struct")));
+
+// CHECK-VERSIONED:      enum MyErrorCode {
+// CHECK-VERSIONED-NEXT:     MyErrorCodeFailed = 1
+// CHECK-VERSIONED-NEXT: };
+
+// CHECK-VERSIONED-NOT: __attribute__((swift_bridge("MyValueType")))
+// CHECK-VERSIONED: @interface MyReferenceType
+
+// CHECK-VERSIONED: void privateFunc();
+
+// CHECK-VERSIONED: typedef double MyDoubleWrapper;
+
+// CHECK-UNVERSIONED: __attribute__((swift_objc_members)
+// CHECK-UNVERSIONED-NEXT: @interface TestProperties
+// CHECK-VERSIONED-NOT: __attribute__((swift_objc_members)
+// CHECK-VERSIONED: @interface TestProperties
+
+// CHECK-UNVERSIONED-LABEL: enum FlagEnum {
+// CHECK-UNVERSIONED-NEXT:     FlagEnumA = 1,
+// CHECK-UNVERSIONED-NEXT:     FlagEnumB = 2
+// CHECK-UNVERSIONED-NEXT: } __attribute__((flag_enum));
+// CHECK-UNVERSIONED-LABEL: enum NewlyFlagEnum {
+// CHECK-UNVERSIONED-NEXT:     NewlyFlagEnumA = 1,
+// CHECK-UNVERSIONED-NEXT:     NewlyFlagEnumB = 2
+// CHECK-UNVERSIONED-NEXT: } __attribute__((flag_enum));
+// CHECK-UNVERSIONED-LABEL: enum APINotedFlagEnum {
+// CHECK-UNVERSIONED-NEXT:     APINotedFlagEnumA = 1,
+// CHECK-UNVERSIONED-NEXT:     APINotedFlagEnumB = 2
+// CHECK-UNVERSIONED-NEXT: } __attribute__((flag_enum));
+// CHECK-UNVERSIONED-LABEL: enum OpenEnum {
+// CHECK-UNVERSIONED-NEXT:     OpenEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("open")));
+// CHECK-UNVERSIONED-LABEL: enum NewlyOpenEnum {
+// CHECK-UNVERSIONED-NEXT:     NewlyOpenEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("open")));
+// CHECK-UNVERSIONED-LABEL: enum NewlyClosedEnum {
+// CHECK-UNVERSIONED-NEXT:     NewlyClosedEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("closed")));
+// CHECK-UNVERSIONED-LABEL: enum ClosedToOpenEnum {
+// CHECK-UNVERSIONED-NEXT:     ClosedToOpenEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("open")));
+// CHECK-UNVERSIONED-LABEL: enum OpenToClosedEnum {
+// CHECK-UNVERSIONED-NEXT:     OpenToClosedEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("closed")));
+// CHECK-UNVERSIONED-LABEL: enum APINotedOpenEnum {
+// CHECK-UNVERSIONED-NEXT:     APINotedOpenEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("open")));
+// CHECK-UNVERSIONED-LABEL: enum APINotedClosedEnum {
+// CHECK-UNVERSIONED-NEXT:     APINotedClosedEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("closed")));
+
+// CHECK-VERSIONED-LABEL: enum FlagEnum {
+// CHECK-VERSIONED-NEXT:     FlagEnumA = 1,
+// CHECK-VERSIONED-NEXT:     FlagEnumB = 2
+// CHECK-VERSIONED-NEXT: } __attribute__((flag_enum));
+// CHECK-VERSIONED-LABEL: enum NewlyFlagEnum {
+// CHECK-VERSIONED-NEXT:     NewlyFlagEnumA = 1,
+// CHECK-VERSIONED-NEXT:     NewlyFlagEnumB = 2
+// CHECK-VERSIONED-NEXT: };
+// CHECK-VERSIONED-LABEL: enum APINotedFlagEnum {
+// CHECK-VERSIONED-NEXT:     APINotedFlagEnumA = 1,
+// CHECK-VERSIONED-NEXT:     APINotedFlagEnumB = 2
+// CHECK-VERSIONED-NEXT: } __attribute__((flag_enum));
+// CHECK-VERSIONED-LABEL: enum OpenEnum {
+// CHECK-VERSIONED-NEXT:     OpenEnumA = 1
+// CHECK-VERSIONED-NEXT: } __attribute__((enum_extensibility("open")));
+// CHECK-VERSIONED-LABEL: enum NewlyOpenEnum {
+// CHECK-VERSIONED-NEXT:     NewlyOpenEnumA = 1
+// CHECK-VERSIONED-NEXT: };
+// CHECK-VERSIONED-LABEL: enum NewlyClosedEnum {
+// CHECK-VERSIONED-NEXT:     NewlyClosedEnumA = 1
+// CHECK-VERSIONED-NEXT: };
+// CHECK-VERSIONED-LABEL: enum ClosedToOpenEnum {
+// CHECK-VERSIONED-NEXT:     ClosedToOpenEnumA = 1
+// CHECK-VERSIONED-NEXT: } __attribute__((enum_extensibility("closed")));
+// CHECK-VERSIONED-LABEL: enum OpenToClosedEnum {
+// CHECK-VERSIONED-NEXT:     OpenToClosedEnumA = 1
+// CHECK-VERSIONED-NEXT: } __attribute__((enum_extensibility("open")));
+// CHECK-VERSIONED-LABEL: enum APINotedOpenEnum {
+// CHECK-VERSIONED-NEXT:     APINotedOpenEnumA = 1
+// CHECK-VERSIONED-NEXT: } __attribute__((enum_extensibility("open")));
+// CHECK-VERSIONED-LABEL: enum APINotedClosedEnum {
+// CHECK-VERSIONED-NEXT:     APINotedClosedEnumA = 1
+// CHECK-VERSIONED-NEXT: } __attribute__((enum_extensibility("closed")));
+
+// These don't actually have versioned information, so we just check them once.
+// CHECK-UNVERSIONED-LABEL: enum SoonToBeCFEnum {
+// CHECK-UNVERSIONED-NEXT:     SoonToBeCFEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("open")));
+// CHECK-UNVERSIONED-LABEL: enum SoonToBeNSEnum {
+// CHECK-UNVERSIONED-NEXT:     SoonToBeNSEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("open")));
+// CHECK-UNVERSIONED-LABEL: enum SoonToBeCFOptions {
+// CHECK-UNVERSIONED-NEXT:     SoonToBeCFOptionsA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("open"))) __attribute__((flag_enum));
+// CHECK-UNVERSIONED-LABEL: enum SoonToBeNSOptions {
+// CHECK-UNVERSIONED-NEXT:     SoonToBeNSOptionsA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("open"))) __attribute__((flag_enum));
+// CHECK-UNVERSIONED-LABEL: enum SoonToBeCFClosedEnum {
+// CHECK-UNVERSIONED-NEXT:     SoonToBeCFClosedEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("closed")));
+// CHECK-UNVERSIONED-LABEL: enum SoonToBeNSClosedEnum {
+// CHECK-UNVERSIONED-NEXT:     SoonToBeNSClosedEnumA = 1
+// CHECK-UNVERSIONED-NEXT: } __attribute__((enum_extensibility("closed")));
+// CHECK-UNVERSIONED-LABEL: enum UndoAllThatHasBeenDoneToMe {
+// CHECK-UNVERSIONED-NEXT:     UndoAllThatHasBeenDoneToMeA = 1
+// CHECK-UNVERSIONED-NEXT: };
diff --git a/test/APINotes/yaml-convert-diags.c b/test/APINotes/yaml-convert-diags.c
new file mode 100644
index 0000000..e8767f2
--- /dev/null
+++ b/test/APINotes/yaml-convert-diags.c
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fsyntax-only -fapinotes -fapinotes-cache-path=%t %s -I %S/Inputs/BrokenHeaders2 2>&1 | FileCheck %s
+
+#include "SomeBrokenLib.h"
+
+// CHECK: error: multiple definitions of global function 'do_something_with_pointers'
diff --git a/test/APINotes/yaml-os-availability.c b/test/APINotes/yaml-os-availability.c
new file mode 100644
index 0000000..62301af
--- /dev/null
+++ b/test/APINotes/yaml-os-availability.c
@@ -0,0 +1,31 @@
+# RUN: %clang -cc1apinotes -yaml-to-binary -target i386-apple-ios7 -o %t-ios.apinotesc %S/Inputs/os-availability.apinotes
+# RUN: %clang -cc1apinotes -binary-to-yaml %t-ios.apinotesc -o %t.os-availability-ios.apinotes
+# RUN: FileCheck %s -check-prefix=IOS < %t.os-availability-ios.apinotes
+
+# RUN: %clang -cc1apinotes -yaml-to-binary -target x86_64-apple-macosx10.9 -o %t-osx.apinotesc %S/Inputs/os-availability.apinotes
+# RUN: %clang -cc1apinotes -binary-to-yaml %t-osx.apinotesc -o %t.os-availability-osx.apinotes
+# RUN: FileCheck %s -check-prefix=OSX < %t.os-availability-osx.apinotes
+
+# IOS: Foundation
+# IOS: NSArray
+# IOS: initWithObjects
+# IOS: familyNameios
+# IOS: fontName
+# IOS: NSCountedSet
+# IOS: UIApplicationDelegate
+# IOS: UIApplicationDelegateIOS
+# IOS: NSAvailableWindowDepths
+# IOS: NSAvailableWindowDepthsiOS
+# IOS-NOT: NSCalibratedWhiteColorSpace
+  
+# OSX: Foundation
+# qqOSX: NSArray
+# OSX-NOT: initWithObjects
+# OSX-NOT: familyNameios
+# OSX: fontName
+# OSX-NOT: NSCountedSet
+# OSX: UIApplicationDelegate
+# OSX-NOT: UIApplicationDelegateIOS
+# OSX: NSAvailableWindowDepths
+# OSX-NOT: NSAvailableWindowDepthsiOS
+# OSX: NSCalibratedWhiteColorSpace
diff --git a/test/APINotes/yaml-parse-diags.c b/test/APINotes/yaml-parse-diags.c
new file mode 100644
index 0000000..4505e29
--- /dev/null
+++ b/test/APINotes/yaml-parse-diags.c
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fsyntax-only -fapinotes -fapinotes-cache-path=%t %s -I %S/Inputs/BrokenHeaders -verify
+
+#include "SomeBrokenLib.h"
+
+// expected-error@APINotes.apinotes:4{{unknown key 'Nu llabilityOfRet'}}
diff --git a/test/APINotes/yaml-reader-errors.c b/test/APINotes/yaml-reader-errors.c
new file mode 100644
index 0000000..c02260b
--- /dev/null
+++ b/test/APINotes/yaml-reader-errors.c
@@ -0,0 +1,86 @@
+# RUN: not %clang -cc1apinotes -yaml-to-binary -target i386-apple-ios7 -o %t.apinotesc %s > %t.err 2>&1
+# RUN: FileCheck %s < %t.err
+
+---
+Name:            UIKit
+Availability:    iOS
+AvailabilityMsg: iOSOnly
+Classes:
+  - Name:            UIFont
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+    Methods:
+      - Selector:        'fontWithName:size:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: O
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+        DesignatedInit:  true
+# CHECK: duplicate definition of method '-[UIFont fontWithName:size:]'
+      - Selector:        'fontWithName:size:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: O
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+        DesignatedInit:  true
+    Properties:
+      - Name:            familyName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+      - Name:            fontName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+# CHECK: duplicate definition of instance property 'UIFont.familyName'
+      - Name:            familyName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+# CHECK: multiple definitions of class 'UIFont'
+  - Name:            UIFont
+Protocols:
+  - Name:            MyProto
+    AuditedForNullability: true
+# CHECK: multiple definitions of protocol 'MyProto'
+  - Name:            MyProto
+    AuditedForNullability: true
+Functions:
+  - Name:        'globalFoo'
+    Nullability:     [ N, N, O, S ]
+    NullabilityOfRet: O
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+  - Name:        'globalFoo2'
+    Nullability:     [ N, N, O, S ]
+    NullabilityOfRet: O
+Globals:
+  - Name:            globalVar
+    Nullability:     O
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+  - Name:            globalVar2
+    Nullability:     O
+Tags:
+# CHECK: cannot mix EnumKind and FlagEnum (for FlagAndEnumKind)
+  - Name: FlagAndEnumKind
+    FlagEnum: true
+    EnumKind: CFOptions
+# CHECK: cannot mix EnumKind and FlagEnum (for FlagAndEnumKind2)
+  - Name: FlagAndEnumKind2
+    EnumKind: CFOptions
+    FlagEnum: false
+# CHECK: cannot mix EnumKind and EnumExtensibility (for ExtensibilityAndEnumKind)
+  - Name: ExtensibilityAndEnumKind
+    EnumExtensibility: open
+    EnumKind: CFOptions
+# CHECK: cannot mix EnumKind and EnumExtensibility (for ExtensibilityAndEnumKind2)
+  - Name: ExtensibilityAndEnumKind2
+    EnumKind: CFOptions
+    EnumExtensibility: closed
+# CHECK: cannot mix EnumKind and EnumExtensibility (for ExtensibilityAndEnumKind3)
+  - Name: ExtensibilityAndEnumKind3
+    EnumKind: none
+    EnumExtensibility: none
diff --git a/test/APINotes/yaml-reader-test.c b/test/APINotes/yaml-reader-test.c
new file mode 100644
index 0000000..01ad90a
--- /dev/null
+++ b/test/APINotes/yaml-reader-test.c
@@ -0,0 +1,102 @@
+# RUN: %clang -cc1apinotes -dump %s | FileCheck %s
+---
+Name:            UIKit
+Availability:    iOS
+AvailabilityMsg: iOSOnly
+Classes:
+  - Name:            UIFont
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+    Methods:
+      - Selector:        'fontWithName:size:'
+        MethodKind:      Instance
+        Nullability:     [ N ]
+        NullabilityOfRet: O
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+        DesignatedInit:  true
+    Properties:
+      - Name:            familyName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+      - Name:            fontName
+        Nullability:     N
+        Availability:    iOS
+        AvailabilityMsg: iOSOnly
+Protocols:
+  - Name:            MyProto
+    AuditedForNullability: true
+  - Name:            MyProto2
+    AuditedForNullability: true
+Functions:
+  - Name:        'globalFoo'
+    Nullability:     [ N, N, O, S ]
+    NullabilityOfRet: O
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+  - Name:        'globalFoo2'
+    Nullability:     [ N, N, O, S ]
+    NullabilityOfRet: O
+Globals:
+  - Name:            globalVar
+    Nullability:     O
+    Availability:    iOS
+    AvailabilityMsg: iOSOnly
+  - Name:            globalVar2
+    Nullability:     O
+
+
+# CHECK: Name:            UIKit
+# CHECK: Availability:    iOS
+# CHECK: AvailabilityMsg: iOSOnly
+# CHECK: Classes:
+# CHECK:   - Name:            UIFont
+# CHECK:     Availability:    iOS
+# CHECK:     AvailabilityMsg: iOSOnly
+# CHECK:     Methods:
+# CHECK:       - Selector:        'fontWithName:size:'
+# CHECK:         MethodKind:      Instance
+# CHECK:         Nullability:     [ N ]
+# CHECK:         NullabilityOfRet: O
+# CHECK:         Availability:    iOS
+# CHECK:         AvailabilityMsg: iOSOnly
+# CHECK:         DesignatedInit:  true
+# CHECK:     Properties:
+# CHECK:       - Name:            familyName
+# CHECK:         Nullability:     N
+# CHECK:         Availability:    iOS
+# CHECK:         AvailabilityMsg: iOSOnly
+# CHECK:       - Name:            fontName
+# CHECK:         Nullability:     N
+# CHECK:         Availability:    iOS
+# CHECK:         AvailabilityMsg: iOSOnly
+# CHECK:Protocols:       
+# CHECK:  - Name:            MyProto
+# CHECK:    AuditedForNullability: true
+# CHECK:    Availability:    available
+# CHECK:    AvailabilityMsg: ''
+# CHECK:  - Name:            MyProto2
+# CHECK:    AuditedForNullability: true
+# CHECK:    Availability:    available
+# CHECK:    AvailabilityMsg: ''
+# CHECK:Functions:       
+# CHECK:  - Name:            globalFoo
+# CHECK:    Nullability:     [ N, N, O, U ]
+# CHECK:    NullabilityOfRet: O
+# CHECK:    Availability:    iOS
+# CHECK:    AvailabilityMsg: iOSOnly
+# CHECK:  - Name:            globalFoo2
+# CHECK:    Nullability:     [ N, N, O, U ]
+# CHECK:    NullabilityOfRet: O
+# CHECK:    Availability:    available
+# CHECK:    AvailabilityMsg: ''
+# CHECK:Globals:         
+# CHECK:  - Name:            globalVar
+# CHECK:    Nullability:     O
+# CHECK:    Availability:    iOS
+# CHECK:    AvailabilityMsg: iOSOnly
+# CHECK:  - Name:            globalVar2
+# CHECK:    Nullability:     O
+# CHECK:    Availability:    available
+# CHECK:    AvailabilityMsg: 
diff --git a/test/APINotes/yaml-roundtrip.c b/test/APINotes/yaml-roundtrip.c
new file mode 100644
index 0000000..b721b6a
--- /dev/null
+++ b/test/APINotes/yaml-roundtrip.c
@@ -0,0 +1,10 @@
+# RUN: %clang -cc1apinotes -yaml-to-binary -o %t.apinotesc %S/Inputs/roundtrip.apinotes
+# RUN: %clang -cc1apinotes -binary-to-yaml -o %t.apinotes %t.apinotesc
+
+# Handle the infurating '...' the YAML writer adds but the parser
+# can't read.
+
+# RUN: cp %S/Inputs/roundtrip.apinotes %t-reference.apinotes
+# RUN: echo "..." >> %t-reference.apinotes
+# RUN: diff %t-reference.apinotes %t.apinotes
+
diff --git a/test/ARCMT/remap-applying.c b/test/ARCMT/remap-applying.c
new file mode 100644
index 0000000..b6280bf
--- /dev/null
+++ b/test/ARCMT/remap-applying.c
@@ -0,0 +1,4 @@
+a bc
+
+// RUN: echo "[{\"file\": \"%s\", \"offset\": 1, \"remove\": 2, }]" > %t.remap
+// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
diff --git a/test/ARCMT/remap-applying.c.result b/test/ARCMT/remap-applying.c.result
new file mode 100644
index 0000000..975dc9e
--- /dev/null
+++ b/test/ARCMT/remap-applying.c.result
@@ -0,0 +1,4 @@
+ac
+
+// RUN: echo "[{\"file\": \"%s\", \"offset\": 1, \"remove\": 2, }]" > %t.remap
+// RUN: c-arcmt-test %t.remap | arcmt-test -verify-transformed-files %s.result
diff --git a/test/Analysis/CFContainers-invalid.c b/test/Analysis/CFContainers-invalid.c
index 3268e1e..ce1284f 100644
--- a/test/Analysis/CFContainers-invalid.c
+++ b/test/Analysis/CFContainers-invalid.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues -triple x86_64-apple-darwin -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues -triple x86_64-apple-darwin -verify %s
 // expected-no-diagnostics
 
 typedef const struct __CFAllocator * CFAllocatorRef;
diff --git a/test/Analysis/CFContainers.mm b/test/Analysis/CFContainers.mm
index f315bc9..0a45bff 100644
--- a/test/Analysis/CFContainers.mm
+++ b/test/Analysis/CFContainers.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues,osx.coreFoundation.containers.OutOfBounds -analyzer-store=region -triple x86_64-apple-darwin -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.coreFoundation.containers.PointerSizedValues,osx.coreFoundation.containers.OutOfBounds -analyzer-store=region -triple x86_64-apple-darwin -verify %s
 
 typedef const struct __CFAllocator * CFAllocatorRef;
 typedef const struct __CFString * CFStringRef;
diff --git a/test/Analysis/CFDateGC.m b/test/Analysis/CFDateGC.m
index fae144f..714e213 100644
--- a/test/Analysis/CFDateGC.m
+++ b/test/Analysis/CFDateGC.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -fobjc-gc %s  -Wno-implicit-function-declaration
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -fobjc-gc %s  -Wno-implicit-function-declaration
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
diff --git a/test/Analysis/CFNumber.c b/test/Analysis/CFNumber.c
index d7dd951..7ac65cc 100644
--- a/test/Analysis/CFNumber.c
+++ b/test/Analysis/CFNumber.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.coreFoundation.CFNumber,osx.cocoa.RetainCount -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.coreFoundation.CFNumber,osx.cocoa.RetainCount -analyzer-store=region -verify -triple x86_64-apple-darwin9 %s
 
 typedef signed long CFIndex;
 typedef const struct __CFAllocator * CFAllocatorRef;
diff --git a/test/Analysis/CFRetainRelease_NSAssertionHandler.m b/test/Analysis/CFRetainRelease_NSAssertionHandler.m
index be1f20d..f358ee6 100644
--- a/test/Analysis/CFRetainRelease_NSAssertionHandler.m
+++ b/test/Analysis/CFRetainRelease_NSAssertionHandler.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -verify %s -analyzer-store=region
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -verify %s -analyzer-store=region
 // expected-no-diagnostics
 
 typedef struct objc_selector *SEL;
diff --git a/test/Analysis/CGColorSpace.c b/test/Analysis/CGColorSpace.c
index 8681e15..38f0512 100644
--- a/test/Analysis/CGColorSpace.c
+++ b/test/Analysis/CGColorSpace.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
 
 typedef struct CGColorSpace *CGColorSpaceRef;
 extern CGColorSpaceRef CGColorSpaceCreateDeviceRGB(void);
diff --git a/test/Analysis/CheckNSError.m b/test/Analysis/CheckNSError.m
index d126d29..6de98e8 100644
--- a/test/Analysis/CheckNSError.m
+++ b/test/Analysis/CheckNSError.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NSError,osx.coreFoundation.CFError -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NSError,osx.coreFoundation.CFError -analyzer-store=region -verify -Wno-objc-root-class %s
 
 
 typedef signed char BOOL;
diff --git a/test/Analysis/DeallocMissingRelease.m b/test/Analysis/DeallocMissingRelease.m
index 651f20a..91af2bd 100644
--- a/test/Analysis/DeallocMissingRelease.m
+++ b/test/Analysis/DeallocMissingRelease.m
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-ios4.0 -DMACOS=0 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-macosx10.6.0 -DMACOS=1 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-darwin10 -fobjc-arc -fobjc-runtime-has-weak -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-ios4.0 -DMACOS=0 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-macosx10.6.0 -DMACOS=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -triple x86_64-apple-darwin10 -fobjc-arc -fobjc-runtime-has-weak -verify %s
 
 #include "Inputs/system-header-simulator-for-objc-dealloc.h"
 
diff --git a/test/Analysis/DeallocUseAfterFreeErrors.m b/test/Analysis/DeallocUseAfterFreeErrors.m
index c131e71..2e1bdc4 100644
--- a/test/Analysis/DeallocUseAfterFreeErrors.m
+++ b/test/Analysis/DeallocUseAfterFreeErrors.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.SuperDealloc,debug.ExprInspection -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.SuperDealloc,debug.ExprInspection -analyzer-output=text -verify %s
 
 void clang_analyzer_warnIfReached();
 
diff --git a/test/Analysis/DynamicTypePropagation.m b/test/Analysis/DynamicTypePropagation.m
index 79ef37c..25a0ae3 100644
--- a/test/Analysis/DynamicTypePropagation.m
+++ b/test/Analysis/DynamicTypePropagation.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.ObjCGenerics -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.ObjCGenerics -verify %s
 
 #if !__has_feature(objc_generics)
 #  error Compiler does not support Objective-C generics?
diff --git a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
index 6fab8bb..b5e47b3 100644
--- a/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
+++ b/test/Analysis/Malloc+MismatchedDeallocator+NewDelete.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
 
 #include "Inputs/system-header-simulator-for-malloc.h"
 
diff --git a/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
index bca223b..88435b8 100644
--- a/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
+++ b/test/Analysis/Malloc+MismatchedDeallocator_intersections.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator -analyzer-store region -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,unix.MismatchedDeallocator -analyzer-store region -std=c++11 -verify %s
 // expected-no-diagnostics
 
 typedef __typeof(sizeof(int)) size_t;
diff --git a/test/Analysis/Malloc+NewDelete_intersections.cpp b/test/Analysis/Malloc+NewDelete_intersections.cpp
index d10020d..9140e1f 100644
--- a/test/Analysis/Malloc+NewDelete_intersections.cpp
+++ b/test/Analysis/Malloc+NewDelete_intersections.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -std=c++11 -verify %s
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
diff --git a/test/Analysis/MemRegion.cpp b/test/Analysis/MemRegion.cpp
index 992b7f1..b8f079a 100644
--- a/test/Analysis/MemRegion.cpp
+++ b/test/Analysis/MemRegion.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.mpi.MPI-Checker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.mpi.MPI-Checker -verify %s
 
 #include "MPIMock.h"
 
diff --git a/test/Analysis/MismatchedDeallocator-checker-test.mm b/test/Analysis/MismatchedDeallocator-checker-test.mm
index 3cc3e18..b80f7df 100644
--- a/test/Analysis/MismatchedDeallocator-checker-test.mm
+++ b/test/Analysis/MismatchedDeallocator-checker-test.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -fblocks -verify %s
 
 #include "Inputs/system-header-simulator-objc.h"
 #include "Inputs/system-header-simulator-cxx.h"
diff --git a/test/Analysis/MismatchedDeallocator-path-notes.cpp b/test/Analysis/MismatchedDeallocator-path-notes.cpp
index 1c8c80c..1354386 100644
--- a/test/Analysis/MismatchedDeallocator-path-notes.cpp
+++ b/test/Analysis/MismatchedDeallocator-path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.MismatchedDeallocator -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void changePointee(int *p);
@@ -287,7 +287,7 @@
 // CHECK-NEXT:    </dict>
 // CHECK-NEXT:   </array>
 // CHECK-NEXT:   <key>description</key><string>Memory allocated by &apos;new[]&apos; should be deallocated by &apos;delete[]&apos;, not &apos;delete&apos;</string>
-// CHECK-NEXT:   <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:   <key>category</key><string>Memory error</string>
 // CHECK-NEXT:   <key>type</key><string>Bad deallocator</string>
 // CHECK-NEXT:   <key>check_name</key><string>unix.MismatchedDeallocator</string>
 // CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
diff --git a/test/Analysis/MissingDealloc.m b/test/Analysis/MissingDealloc.m
index 248dc51..bedd1e7 100644
--- a/test/Analysis/MissingDealloc.m
+++ b/test/Analysis/MissingDealloc.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify -triple x86_64-apple-darwin10 -fobjc-arc %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.Dealloc -fblocks -verify -triple x86_64-apple-darwin10 -fobjc-arc %s
 
 #define NON_ARC !__has_feature(objc_arc)
 
diff --git a/test/Analysis/MisusedMovedObject.cpp b/test/Analysis/MisusedMovedObject.cpp
new file mode 100644
index 0000000..44e055f
--- /dev/null
+++ b/test/Analysis/MisusedMovedObject.cpp
@@ -0,0 +1,619 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.MisusedMovedObject -std=c++11 -verify -analyzer-output=text %s
+
+namespace std {
+
+template <typename>
+struct remove_reference;
+
+template <typename _Tp>
+struct remove_reference { typedef _Tp type; };
+
+template <typename _Tp>
+struct remove_reference<_Tp &> { typedef _Tp type; };
+
+template <typename _Tp>
+struct remove_reference<_Tp &&> { typedef _Tp type; };
+
+template <typename _Tp>
+typename remove_reference<_Tp>::type &&move(_Tp &&__t) {
+  return static_cast<typename remove_reference<_Tp>::type &&>(__t);
+}
+
+template <typename _Tp>
+_Tp &&forward(typename remove_reference<_Tp>::type &__t) noexcept {
+  return static_cast<_Tp &&>(__t);
+}
+
+template <class T>
+void swap(T &a, T &b) {
+  T c(std::move(a));
+  a = std::move(b);
+  b = std::move(c);
+}
+
+} // namespace std
+
+class B {
+public:
+  B() = default;
+  B(const B &) = default;
+  B(B &&) = default;
+  void operator=(B &&b) {
+    return;
+  }
+  void foo() { return; }
+};
+
+class A {
+  int i;
+  double d;
+
+public:
+  B b;
+  A(int ii = 42, double dd = 1.0) : d(dd), i(ii), b(B()) {}
+  void moveconstruct(A &&other) {
+    std::swap(b, other.b);
+    std::swap(d, other.d);
+    std::swap(i, other.i);
+    return;
+  }
+  static A get() {
+    A v(12, 13);
+    return v;
+  }
+  A(A *a) {
+    moveconstruct(std::move(*a));
+  }
+  A(const A &other) : i(other.i), d(other.d), b(other.b) {}
+  A(A &&other) : i(other.i), d(other.d), b(std::move(other.b)) { // expected-note {{'b' became 'moved-from' here}}
+  }
+  A(A &&other, char *k) {
+    moveconstruct(std::move(other));
+  }
+  void operator=(A &&other) {
+    moveconstruct(std::move(other));
+    return;
+  }
+  int getI() { return i; }
+  int foo() const;
+  void bar() const;
+  void reset();
+  void destroy();
+  void clear();
+  bool empty() const;
+  bool isEmpty() const;
+  operator bool() const;
+};
+
+int bignum();
+
+void moveInsideFunctionCall(A a) {
+  A b = std::move(a);
+}
+void leftRefCall(A &a) {
+  a.foo();
+}
+void rightRefCall(A &&a) {
+  a.foo();
+}
+void constCopyOrMoveCall(const A a) {
+  a.foo();
+}
+
+void copyOrMoveCall(A a) {
+  a.foo();
+}
+
+void simpleMoveCtorTest() {
+  A a;
+  A b;
+  b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+  a.foo();          // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+}
+
+void simpleMoveAssignementTest() {
+  A a;
+  A b;
+  b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+  a.foo();          // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+}
+
+void moveInInitListTest() {
+  struct S {
+    A a;
+  };
+  A a;
+  S s{std::move(a)}; // expected-note {{'a' became 'moved-from' here}}
+  a.foo();           // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+}
+
+// Don't report a bug if the variable was assigned to in the meantime.
+void reinitializationTest(int i) {
+  {
+    A a;
+    A b;
+    b = std::move(a);
+    a = A();
+    a.foo();
+  }
+  {
+    A a;
+    if (i == 1) { // expected-note {{Assuming 'i' is not equal to 1}} expected-note {{Taking false branch}}
+      // expected-note@-1 {{Assuming 'i' is not equal to 1}} expected-note@-1 {{Taking false branch}}
+      A b;
+      b = std::move(a);
+      a = A();
+    }
+    if (i == 2) { // expected-note {{Assuming 'i' is not equal to 2}} expected-note {{Taking false branch}}
+      //expected-note@-1 {{Assuming 'i' is not equal to 2}} expected-note@-1 {{Taking false branch}}
+      a.foo();    // no-warning
+    }
+  }
+  {
+    A a;
+    if (i == 1) { // expected-note {{Taking false branch}} expected-note {{Taking false branch}}
+      std::move(a);
+    }
+    if (i == 2) { // expected-note {{Taking false branch}} expected-note {{Taking false branch}}
+      a = A();
+      a.foo();
+    }
+  }
+  // The built-in assignment operator should also be recognized as a
+  // reinitialization. (std::move() may be called on built-in types in template
+  // code.)
+  {
+    int a1 = 1, a2 = 2;
+    std::swap(a1, a2);
+  }
+  // A std::move() after the assignment makes the variable invalid again.
+  {
+    A a;
+    A b;
+    b = std::move(a);
+    a = A();
+    b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    a.foo();          // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+  }
+  // If a path exist where we not reinitialize the variable we report a bug.
+  {
+    A a;
+    A b;
+    b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    if (i < 10) {     // expected-note {{Assuming 'i' is >= 10}} expected-note {{Taking false branch}}
+      a = A();
+    }
+    if (i > 5) { // expected-note {{Taking true branch}}
+      a.foo();   // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+    }
+  }
+}
+
+// Using decltype on an expression is not a use.
+void decltypeIsNotUseTest() {
+  A a;
+  // A b(std::move(a));
+  decltype(a) other_a; // no-warning
+}
+
+void loopTest() {
+  {
+    A a;
+    for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}}
+      rightRefCall(std::move(a));        // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true.  Entering loop body}}
+      //expected-note@-1 {{Loop condition is true.  Entering loop body}}
+			//expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
+      rightRefCall(std::move(a)); // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}}
+      leftRefCall(a);                    // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true.  Entering loop body}} 
+      //expected-note@-1 {{Loop condition is true.  Entering loop body}}
+			//expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
+      leftRefCall(a);             // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}}
+      constCopyOrMoveCall(a);            // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true.  Entering loop body}} 
+      //expected-note@-1 {{Loop condition is true.  Entering loop body}}
+			//expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
+      constCopyOrMoveCall(a);     // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}}
+      moveInsideFunctionCall(a);         // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true.  Entering loop body}}
+      //expected-note@-1 {{Loop condition is true.  Entering loop body}}
+			//expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
+      moveInsideFunctionCall(a);  // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is false. Execution jumps to the end of the function}}
+      copyOrMoveCall(a);                 // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < 2; i++) { // expected-note {{Loop condition is true.}}
+      //expected-note@-1 {{Loop condition is true.  Entering loop body}}
+			//expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
+      copyOrMoveCall(a);          // no-warning
+    }
+  }
+  {
+    A a;
+    for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is true.  Entering loop body}} expected-note {{Loop condition is true.  Entering loop body}}
+      constCopyOrMoveCall(std::move(a)); // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}}
+      // expected-note@-1 {{'a' became 'moved-from' here}}
+    }
+  }
+
+  // Don't warn if we return after the move.
+  {
+    A a;
+    for (int i = 0; i < 3; ++i) {
+      a.bar();
+      if (a.foo() > 0) {
+        A b;
+        b = std::move(a); // no-warning
+        return;
+      }
+    }
+  }
+}
+
+//report a usage of a moved-from object only at the first use
+void uniqueTest(bool cond) {
+  A a(42, 42.0);
+  A b;
+  b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+
+  if (cond) { // expected-note {{Assuming 'cond' is not equal to 0}} expected-note {{Taking true branch}}
+    a.foo();  // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+  }
+  if (cond) {
+    a.bar(); // no-warning
+  }
+
+  a.bar(); // no-warning
+}
+
+void uniqueTest2() {
+  A a;
+  A a1 = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+  a.foo();             // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+
+  A a2 = std::move(a); // no-warning
+  a.foo();             // no-warning
+}
+
+// There are exceptions where we assume in general that the method works fine
+//even on moved-from objects.
+void moveSafeFunctionsTest() {
+  A a;
+  A b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+  a.empty();          // no-warning
+  a.isEmpty();        // no-warning
+  (void)a;            // no-warning
+  (bool)a;            // expected-warning {{expression result unused}}
+  a.foo();            // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+}
+
+void moveStateResetFunctionsTest() {
+  {
+    A a;
+    A b = std::move(a);
+    a.reset(); // no-warning
+    a.foo();   // no-warning
+  }
+  {
+    A a;
+    A b = std::move(a);
+    a.destroy(); // no-warning
+    a.foo();     // no-warning
+  }
+  {
+    A a;
+    A b = std::move(a);
+    a.clear(); // no-warning
+    a.foo();   // no-warning
+  }
+}
+
+// Moves or uses that occur as part of template arguments.
+template <int>
+class ClassTemplate {
+public:
+  void foo(A a);
+};
+
+template <int>
+void functionTemplate(A a);
+
+void templateArgIsNotUseTest() {
+  {
+    // A pattern like this occurs in the EXPECT_EQ and ASSERT_EQ macros in
+    // Google Test.
+    A a;
+    ClassTemplate<sizeof(A(std::move(a)))>().foo(std::move(a)); // no-warning
+  }
+  {
+    A a;
+    functionTemplate<sizeof(A(std::move(a)))>(std::move(a)); // no-warning
+  }
+}
+
+// Moves of global variables are not reported.
+A global_a;
+void globalVariablesTest() {
+  std::move(global_a);
+  global_a.foo(); // no-warning
+}
+
+// Moves of member variables.
+class memberVariablesTest {
+  A a;
+  static A static_a;
+
+  void f() {
+    A b;
+    b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    a.foo();          // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object 'a'}}
+
+    b = std::move(static_a); // expected-note {{'static_a' became 'moved-from' here}}
+    static_a.foo();          // expected-warning {{Method call on a 'moved-from' object 'static_a'}} expected-note {{Method call on a 'moved-from' object 'static_a'}}
+  }
+};
+
+void PtrAndArrayTest() {
+  A *Ptr = new A(1, 1.5);
+  A Arr[10];
+  Arr[2] = std::move(*Ptr); // expected-note {{Became 'moved-from' here}}
+  (*Ptr).foo();             // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object}}
+
+  Ptr = &Arr[1];
+  Arr[3] = std::move(Arr[1]); // expected-note {{Became 'moved-from' here}}
+  Ptr->foo();                 // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object}}
+
+  Arr[3] = std::move(Arr[2]); // expected-note {{Became 'moved-from' here}}
+  Arr[2].foo();               // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object}}
+
+  Arr[2] = std::move(Arr[3]); // reinitialization
+  Arr[2].foo();               // no-warning
+}
+
+void exclusiveConditionsTest(bool cond) {
+  A a;
+  if (cond) {
+    A b;
+    b = std::move(a);
+  }
+  if (!cond) {
+    a.bar(); // no-warning
+  }
+}
+
+void differentBranchesTest(int i) {
+  // Don't warn if the use is in a different branch from the move.
+  {
+    A a;
+    if (i > 0) { // expected-note {{Assuming 'i' is > 0}} expected-note {{Taking true branch}}
+      A b;
+      b = std::move(a);
+    } else {
+      a.foo(); // no-warning
+    }
+  }
+  // Same thing, but with a ternary operator.
+  {
+    A a, b;
+    i > 0 ? (void)(b = std::move(a)) : a.bar(); // no-warning  // expected-note {{'?' condition is true}}
+  }
+  // A variation on the theme above.
+  {
+    A a;
+    a.foo() > 0 ? a.foo() : A(std::move(a)).foo(); // expected-note {{Assuming the condition is false}} expected-note {{'?' condition is false}}
+  }
+  // Same thing, but with a switch statement.
+  {
+    A a, b;
+    switch (i) { // expected-note {{Control jumps to 'case 1:'  at line 448}}
+    case 1:
+      b = std::move(a); // no-warning
+      break;            // expected-note {{Execution jumps to the end of the function}}
+    case 2:
+      a.foo(); // no-warning
+      break;
+    }
+  }
+  // However, if there's a fallthrough, we do warn.
+  {
+    A a, b;
+    switch (i) { // expected-note {{Control jumps to 'case 1:'  at line 460}}
+    case 1:
+      b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    case 2:
+      a.foo(); // expected-warning {{Method call on a 'moved-from' object}} expected-note {{Method call on a 'moved-from' object 'a'}}
+      break;
+    }
+  }
+}
+
+void tempTest() {
+  A a = A::get();
+  A::get().foo(); // no-warning
+  for (int i = 0; i < bignum(); i++) {
+    A::get().foo(); // no-warning
+  }
+}
+
+void interFunTest1(A &a) {
+  a.bar(); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+}
+
+void interFunTest2() {
+  A a;
+  A b;
+  b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+  interFunTest1(a); // expected-note {{Calling 'interFunTest1'}}
+}
+
+void foobar(A a, int i);
+void foobar(int i, A a);
+
+void paramEvaluateOrderTest() {
+  A a;
+  foobar(std::move(a), a.getI()); // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+  // expected-note@-1 {{'a' became 'moved-from' here}}
+
+  //FALSE NEGATIVE since parameters evaluate order is undefined
+  foobar(a.getI(), std::move(a)); //no-warning
+}
+
+void not_known(A &a);
+void not_known(A *a);
+
+void regionAndPointerEscapeTest() {
+  {
+    A a;
+    A b;
+    b = std::move(a);
+    not_known(a);
+    a.foo(); //no-warning
+  }
+  {
+    A a;
+    A b;
+    b = std::move(a);
+    not_known(&a);
+    a.foo(); // no-warning
+  }
+}
+
+// A declaration statement containing multiple declarations sequences the
+// initializer expressions.
+void declarationSequenceTest() {
+  {
+    A a;
+    A a1 = a, a2 = std::move(a); // no-warning
+  }
+  {
+    A a;
+    A a1 = std::move(a), a2 = a; // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}}
+    // expected-note@-1 {{'a' became 'moved-from' here}}
+  }
+}
+
+// The logical operators && and || sequence their operands.
+void logicalOperatorsSequenceTest() {
+  {
+    A a;
+    if (a.foo() > 0 && A(std::move(a)).foo() > 0) { // expected-note {{Assuming the condition is false}} expected-note {{Assuming the condition is false}} 
+      // expected-note@-1 {{Left side of '&&' is false}} expected-note@-1 {{Left side of '&&' is false}}
+			//expected-note@-2 {{Taking false branch}} expected-note@-2 {{Taking false branch}}
+      A().bar();
+    }
+  }
+  // A variation: Negate the result of the && (which pushes the && further down
+  // into the AST).
+  {
+    A a;
+    if (!(a.foo() > 0 && A(std::move(a)).foo() > 0)) { // expected-note {{Assuming the condition is false}} expected-note {{Assuming the condition is false}}
+      // expected-note@-1 {{Left side of '&&' is false}} expected-note@-1 {{Left side of '&&' is false}}
+      // expected-note@-2 {{Taking true branch}} expected-note@-2 {{Taking true branch}}
+      A().bar();
+    }
+  }
+  {
+    A a;
+    if (A(std::move(a)).foo() > 0 && a.foo() > 0) { // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+      // expected-note@-1 {{'a' became 'moved-from' here}} expected-note@-1 {{Assuming the condition is true}} expected-note@-1 {{Assuming the condition is false}}
+      // expected-note@-2 {{Left side of '&&' is false}} expected-note@-2 {{Left side of '&&' is true}}
+      // expected-note@-3 {{Taking false branch}}
+      A().bar();
+    }
+  }
+  {
+    A a;
+    if (a.foo() > 0 || A(std::move(a)).foo() > 0) { // expected-note {{Assuming the condition is true}} 
+			//expected-note@-1 {{Left side of '||' is true}}
+			//expected-note@-2 {{Taking true branch}}
+      A().bar();
+    }
+  }
+  {
+    A a;
+    if (A(std::move(a)).foo() > 0 || a.foo() > 0) { // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+      // expected-note@-1 {{'a' became 'moved-from' here}} expected-note@-1 {{Assuming the condition is false}} expected-note@-1 {{Left side of '||' is false}}
+      A().bar();
+    }
+  }
+}
+
+// A range-based for sequences the loop variable declaration before the body.
+void forRangeSequencesTest() {
+  A v[2] = {A(), A()};
+  for (A &a : v) {
+    A b;
+    b = std::move(a); // no-warning
+  }
+}
+
+// If a variable is declared in an if statement, the declaration of the variable
+// (which is treated like a reinitialization by the check) is sequenced before
+// the evaluation of the condition (which constitutes a use).
+void ifStmtSequencesDeclAndConditionTest() {
+  for (int i = 0; i < 3; ++i) {
+    if (A a = A()) {
+      A b;
+      b = std::move(a); // no-warning
+    }
+  }
+}
+
+void subRegionMoveTest() {
+  {
+    A a;
+    B b = std::move(a.b); // expected-note {{'b' became 'moved-from' here}}
+    a.b.foo();            // expected-warning {{Method call on a 'moved-from' object 'b'}} expected-note {{Method call on a 'moved-from' object 'b'}}
+  }
+  {
+    A a;
+    A a1 = std::move(a); // expected-note {{Calling move constructor for 'A'}} expected-note {{Returning from move constructor for 'A'}}
+    a.b.foo();           // expected-warning {{Method call on a 'moved-from' object 'b'}} expected-note {{Method call on a 'moved-from' object 'b'}}
+  }
+  // Don't report a misuse if any SuperRegion is already reported.
+  {
+    A a;
+    A a1 = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    a.foo();             // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+    a.b.foo();           // no-warning
+  }
+}
diff --git a/test/Analysis/NSContainers.m b/test/Analysis/NSContainers.m
index c868459..ac33efc 100644
--- a/test/Analysis/NSContainers.m
+++ b/test/Analysis/NSContainers.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -Wno-objc-literal-conversion -analyze -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops,debug.ExprInspection -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1  -Wno-objc-literal-conversion -analyzer-checker=core,osx.cocoa.NonNilReturnValue,osx.cocoa.NilArg,osx.cocoa.Loops,debug.ExprInspection -verify -Wno-objc-root-class %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/NSPanel.m b/test/Analysis/NSPanel.m
index 53b18c2..e65b071 100644
--- a/test/Analysis/NSPanel.m
+++ b/test/Analysis/NSPanel.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 // BEGIN delta-debugging reduced header stuff
diff --git a/test/Analysis/NSString.m b/test/Analysis/NSString.m
index 1123d80..a53fc1e 100644
--- a/test/Analysis/NSString.m
+++ b/test/Analysis/NSString.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -analyzer-config mode=shallow -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -DOSATOMIC_USE_INLINED -triple i386-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -analyzer-config mode=shallow -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -DTEST_64 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -DOSATOMIC_USE_INLINED -triple i386-apple-darwin10 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
diff --git a/test/Analysis/NSWindow.m b/test/Analysis/NSWindow.m
index 44a97e4..e247ff1 100644
--- a/test/Analysis/NSWindow.m
+++ b/test/Analysis/NSWindow.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core,deadcode.DeadStores -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core,deadcode.DeadStores -analyzer-store=region -verify %s
 
 // These declarations were reduced using Delta-Debugging from Foundation.h
 // on Mac OS X.  The test cases are below.
diff --git a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
index 49358f6..987ed6a 100644
--- a/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
+++ b/test/Analysis/NewDelete+MismatchedDeallocator_intersections.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,unix.MismatchedDeallocator -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.MismatchedDeallocator -DLEAKS -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.MismatchedDeallocator -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.MismatchedDeallocator -DLEAKS -std=c++11 -verify %s
 // expected-no-diagnostics
 
 typedef __typeof(sizeof(int)) size_t;
diff --git a/test/Analysis/NewDelete-checker-test.cpp b/test/Analysis/NewDelete-checker-test.cpp
index 78a0015..66e8375 100644
--- a/test/Analysis/NewDelete-checker-test.cpp
+++ b/test/Analysis/NewDelete-checker-test.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -fblocks -verify %s
 #include "Inputs/system-header-simulator-cxx.h"
 
 typedef __typeof__(sizeof(int)) size_t;
@@ -244,7 +244,7 @@
 
 void testUninitFree() {
   int *x;
-  free(x); // expected-warning{{Function call argument is an uninitialized value}}
+  free(x); // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 void testUninitDeleteSink() {
diff --git a/test/Analysis/NewDelete-custom.cpp b/test/Analysis/NewDelete-custom.cpp
index d368889..f06ff4a 100644
--- a/test/Analysis/NewDelete-custom.cpp
+++ b/test/Analysis/NewDelete-custom.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -DLEAKS -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,unix.Malloc -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -DLEAKS -fblocks -verify %s
 #include "Inputs/system-header-simulator-cxx.h"
 
 #ifndef LEAKS
diff --git a/test/Analysis/NewDelete-intersections.mm b/test/Analysis/NewDelete-intersections.mm
index cde8122..aa52c79 100644
--- a/test/Analysis/NewDelete-intersections.mm
+++ b/test/Analysis/NewDelete-intersections.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -std=c++11 -DLEAKS -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks -std=c++11 -DLEAKS -fblocks -verify %s
 #include "Inputs/system-header-simulator-cxx.h"
 #include "Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/NewDelete-path-notes.cpp b/test/Analysis/NewDelete-path-notes.cpp
index 64b15b8..ac760ca 100644
--- a/test/Analysis/NewDelete-path-notes.cpp
+++ b/test/Analysis/NewDelete-path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,unix.Malloc -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void test() {
@@ -257,7 +257,7 @@
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Attempt to free released memory</string>
-// CHECK-NEXT:    <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:    <key>category</key><string>Memory error</string>
 // CHECK-NEXT:    <key>type</key><string>Double free</string>
 // CHECK-NEXT:    <key>check_name</key><string>cplusplus.NewDelete</string>
 // CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
@@ -475,7 +475,7 @@
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Attempt to free released memory</string>
-// CHECK-NEXT:    <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:    <key>category</key><string>Memory error</string>
 // CHECK-NEXT:    <key>type</key><string>Double free</string>
 // CHECK-NEXT:    <key>check_name</key><string>cplusplus.NewDelete</string>
 // CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
diff --git a/test/Analysis/NewDelete-variadic.cpp b/test/Analysis/NewDelete-variadic.cpp
index f9ef079b..523785a 100644
--- a/test/Analysis/NewDelete-variadic.cpp
+++ b/test/Analysis/NewDelete-variadic.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,unix.Malloc -std=c++11 -fblocks -verify %s
 // expected-no-diagnostics
 
 namespace std {
diff --git a/test/Analysis/NewDeleteLeaks-PR18394.cpp b/test/Analysis/NewDeleteLeaks-PR18394.cpp
index d0d7037..5a5b82c 100644
--- a/test/Analysis/NewDeleteLeaks-PR18394.cpp
+++ b/test/Analysis/NewDeleteLeaks-PR18394.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyzer-config graph-trim-interval=1 -analyzer-max-loop 1 -analyze -analyzer-checker=core,cplusplus.NewDeleteLeaks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-config graph-trim-interval=1 -analyzer-max-loop 1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -verify %s
 // expected-no-diagnostics
 
 class A {
diff --git a/test/Analysis/NewDeleteLeaks-PR19102.cpp b/test/Analysis/NewDeleteLeaks-PR19102.cpp
index b141301..502db61 100644
--- a/test/Analysis/NewDeleteLeaks-PR19102.cpp
+++ b/test/Analysis/NewDeleteLeaks-PR19102.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,cplusplus.NewDeleteLeaks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -verify %s
 
 class A0 {};
 
diff --git a/test/Analysis/NoReturn.m b/test/Analysis/NoReturn.m
index 5ed92df..c08fd0d 100644
--- a/test/Analysis/NoReturn.m
+++ b/test/Analysis/NoReturn.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 #include <stdarg.h>
 
diff --git a/test/Analysis/OSAtomic_mac.cpp b/test/Analysis/OSAtomic_mac.cpp
index f938958..e45f236 100644
--- a/test/Analysis/OSAtomic_mac.cpp
+++ b/test/Analysis/OSAtomic_mac.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,osx -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,osx -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
 // expected-no-diagnostics
 
 // Test handling of OSAtomicCompareAndSwap when C++ inserts "no-op" casts and we
diff --git a/test/Analysis/ObjCProperties.m b/test/Analysis/ObjCProperties.m
index 201e3e1..1a112ec 100644
--- a/test/Analysis/ObjCProperties.m
+++ b/test/Analysis/ObjCProperties.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s -verify
 // expected-no-diagnostics
 
 // The point of this test cases is to exercise properties in the static
diff --git a/test/Analysis/ObjCPropertiesSyntaxChecks.m b/test/Analysis/ObjCPropertiesSyntaxChecks.m
index 5c642c5..5a25896 100644
--- a/test/Analysis/ObjCPropertiesSyntaxChecks.m
+++ b/test/Analysis/ObjCPropertiesSyntaxChecks.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -fblocks -analyze -analyzer-checker=osx.ObjCProperty %s -verify
+// RUN: %clang_analyze_cc1 -w -fblocks -analyzer-checker=osx.ObjCProperty %s -verify
 
 #include "Inputs/system-header-simulator-objc.h"
 
@@ -59,3 +59,10 @@
 @interface IWithoutImpl : NSObject {}
 @property(copy) NSMutableString *mutableStr; // no-warning
 @end
+
+@protocol SomeProtocol
+// Don't warn on protocol properties because it is possible to
+// conform to them correctly; it is only synthesized setters that
+// that are definitely incorrect.
+@property (copy) NSMutableString *myProp; // no-crash // no-warning
+@end
diff --git a/test/Analysis/ObjCRetSigs.m b/test/Analysis/ObjCRetSigs.m
index 6ee83ec..97d33f9 100644
--- a/test/Analysis/ObjCRetSigs.m
+++ b/test/Analysis/ObjCRetSigs.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-checker=osx.cocoa.IncompatibleMethodTypes -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-checker=osx.cocoa.IncompatibleMethodTypes -verify -Wno-objc-root-class %s
 
 int printf(const char *, ...);
 
diff --git a/test/Analysis/PR12905.c b/test/Analysis/PR12905.c
index 8f678d1..f36b93a 100644
--- a/test/Analysis/PR12905.c
+++ b/test/Analysis/PR12905.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core %s
 // PR12905
 
 void C(void);
diff --git a/test/Analysis/PR24184.cpp b/test/Analysis/PR24184.cpp
index 54eae56..1280334 100644
--- a/test/Analysis/PR24184.cpp
+++ b/test/Analysis/PR24184.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -w -analyze -analyzer-eagerly-assume -fcxx-exceptions -analyzer-checker=core -analyzer-checker=alpha.core.PointerArithm,alpha.core.CastToStruct -analyzer-max-loop 64 -verify %s
-// RUN: %clang_cc1 -w -analyze -analyzer-checker=core -analyzer-checker=cplusplus -fcxx-exceptions -analyzer-checker alpha.core.PointerArithm,alpha.core.CastToStruct -analyzer-max-loop 63 -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-eagerly-assume -fcxx-exceptions -analyzer-checker=core -analyzer-checker=alpha.core.PointerArithm,alpha.core.CastToStruct -analyzer-max-loop 64 -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core -analyzer-checker=cplusplus -fcxx-exceptions -analyzer-checker alpha.core.PointerArithm,alpha.core.CastToStruct -analyzer-max-loop 63 -verify %s
 
 // These tests used to hit an assertion in the bug report. Test case from http://llvm.org/PR24184.
 typedef struct {
diff --git a/test/Analysis/PR2599.m b/test/Analysis/PR2599.m
index ac552ee..1c2270e 100644
--- a/test/Analysis/PR2599.m
+++ b/test/Analysis/PR2599.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -fobjc-gc -verify %s
+// RUN: %clang_analyze_cc1 -triple %itanium_abi_triple -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -fobjc-gc -verify %s
 
 typedef const void * CFTypeRef;
 typedef const struct __CFString * CFStringRef;
diff --git a/test/Analysis/PR2978.m b/test/Analysis/PR2978.m
index b609da5..8b7effc 100644
--- a/test/Analysis/PR2978.m
+++ b/test/Analysis/PR2978.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,osx.cocoa.Dealloc %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,osx.cocoa.Dealloc %s -verify
 
 // Tests for the checker which checks missing/extra ivar 'release' calls 
 // in dealloc.
diff --git a/test/Analysis/PR3991.m b/test/Analysis/PR3991.m
index 68d5660..ffdb7b4 100644
--- a/test/Analysis/PR3991.m
+++ b/test/Analysis/PR3991.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-incomplete-implementation %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-incomplete-implementation %s
 // expected-no-diagnostics
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Analysis/PR7218.c b/test/Analysis/PR7218.c
index 1775e05..10a75c9 100644
--- a/test/Analysis/PR7218.c
+++ b/test/Analysis/PR7218.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store region -verify %s
 char PR7218(char a) {
     char buf[2];
     buf[0] = a;
diff --git a/test/Analysis/additive-folding-range-constraints.c b/test/Analysis/additive-folding-range-constraints.c
index 4baada8..87d1b1c 100644
--- a/test/Analysis/additive-folding-range-constraints.c
+++ b/test/Analysis/additive-folding-range-constraints.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/additive-folding.cpp b/test/Analysis/additive-folding.cpp
index 6ae025b..823b176 100644
--- a/test/Analysis/additive-folding.cpp
+++ b/test/Analysis/additive-folding.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -Wno-tautological-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -Wno-tautological-compare %s
 
 void clang_analyzer_eval(bool);
 
@@ -205,3 +205,12 @@
 
   clang_analyzer_eval(x == 3); // expected-warning{{UNKNOWN}}
 }
+
+void additiveSymSymFolding(int x, int y) {
+  // We should simplify 'x - 1' to '0' and handle the comparison,
+  // despite both sides being complicated symbols.
+  int z = x - 1;
+  if (x == 1)
+    if (y >= 0)
+      clang_analyzer_eval(z <= y); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/analyzeOneFunction.m b/test/Analysis/analyzeOneFunction.m
index e70b2d7..a77abe1 100644
--- a/test/Analysis/analyzeOneFunction.m
+++ b/test/Analysis/analyzeOneFunction.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyze-function="-[Test1 myMethodWithY:withX:]" -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyze-function="-[Test1 myMethodWithY:withX:]" -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify %s
 
 typedef signed char BOOL;
 typedef unsigned int NSUInteger;
diff --git a/test/Analysis/analyzer-checker-config.c b/test/Analysis/analyzer-checker-config.c
index 642c96c..34e3399 100644
--- a/test/Analysis/analyzer-checker-config.c
+++ b/test/Analysis/analyzer-checker-config.c
@@ -1,10 +1,10 @@
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config unix.mallo:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config uni:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config uni.:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config ..:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config unix.:Optimistic=true 2>&1 | FileCheck %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config unrelated:Optimistic=true 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-config unix.Malloc:Optimistic=true
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.mallo:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config uni:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config uni.:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config ..:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.:Optimistic=true 2>&1 | FileCheck %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unrelated:Optimistic=true 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-config unix.Malloc:Optimistic=true
 
 // Just to test clang is working.
 # foo
diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c
index 6faeeb3..c0153a5 100644
--- a/test/Analysis/analyzer-config.c
+++ b/test/Analysis/analyzer-config.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper -Xclang -analyzer-max-loop -Xclang 34 > %t 2>&1
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core,osx.cocoa,debug.ConfigDumper -analyzer-max-loop 34 > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 void bar() {}
diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp
index 23f0828..f84be17 100644
--- a/test/Analysis/analyzer-config.cpp
+++ b/test/Analysis/analyzer-config.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=debug.ConfigDumper -Xclang -analyzer-max-loop -Xclang 34 > %t 2>&1
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core,osx.cocoa,debug.ConfigDumper -analyzer-max-loop 34 > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 void bar() {}
diff --git a/test/Analysis/analyzer-display-progress.cpp b/test/Analysis/analyzer-display-progress.cpp
index 5d9f5e5..b54044a 100644
--- a/test/Analysis/analyzer-display-progress.cpp
+++ b/test/Analysis/analyzer-display-progress.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-display-progress %s 2>&1 | FileCheck %s
 
 void f() {};
 void g() {};
diff --git a/test/Analysis/analyzer-display-progress.m b/test/Analysis/analyzer-display-progress.m
index cc43cf3..8d0b3d6 100644
--- a/test/Analysis/analyzer-display-progress.m
+++ b/test/Analysis/analyzer-display-progress.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-display-progress %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-display-progress %s 2>&1 | FileCheck %s
 
 #include "Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/analyzer-enabled-checkers.c b/test/Analysis/analyzer-enabled-checkers.c
index e60de05..0ea01a0 100644
--- a/test/Analysis/analyzer-enabled-checkers.c
+++ b/test/Analysis/analyzer-enabled-checkers.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-apple-darwin10 --analyze %s -o /dev/null -Xclang -analyzer-checker=core -Xclang -analyzer-list-enabled-checkers > %t 2>&1
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 %s -o /dev/null -analyzer-checker=core -analyzer-list-enabled-checkers > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 // CHECK: OVERVIEW: Clang Static Analyzer Enabled Checkers List
diff --git a/test/Analysis/analyzer-stats.c b/test/Analysis/analyzer-stats.c
index a0a50cb..5a40d19 100644
--- a/test/Analysis/analyzer-stats.c
+++ b/test/Analysis/analyzer-stats.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,debug.Stats -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,deadcode.DeadStores,debug.Stats -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
 
 int foo();
 
diff --git a/test/Analysis/array-struct-region.c b/test/Analysis/array-struct-region.c
index a41d040..cdfec45 100644
--- a/test/Analysis/array-struct-region.c
+++ b/test/Analysis/array-struct-region.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/array-struct-region.cpp b/test/Analysis/array-struct-region.cpp
index 4777686..48a05fd 100644
--- a/test/Analysis/array-struct-region.cpp
+++ b/test/Analysis/array-struct-region.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c
index 34bdc58..45c4c9d 100644
--- a/test/Analysis/array-struct.c
+++ b/test/Analysis/array-struct.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.CastToStruct -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.CastToStruct -analyzer-store=region -verify %s
 
 struct s {
   int data;
diff --git a/test/Analysis/atomics.c b/test/Analysis/atomics.c
index f0f5ff0..6fe4ec5 100644
--- a/test/Analysis/atomics.c
+++ b/test/Analysis/atomics.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 // Tests for c11 atomics. Many of these tests currently yield unknown
 // because we don't fully model the atomics and instead imprecisely
diff --git a/test/Analysis/auto-obj-dtors-cfg-output.cpp b/test/Analysis/auto-obj-dtors-cfg-output.cpp
index 0b4454f..cc47c92 100644
--- a/test/Analysis/auto-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/auto-obj-dtors-cfg-output.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -fexceptions -analyzer-checker=debug.DumpCFG %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 class A {
diff --git a/test/Analysis/base-init.cpp b/test/Analysis/base-init.cpp
index 3c870e1..1f59303 100644
--- a/test/Analysis/base-init.cpp
+++ b/test/Analysis/base-init.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/bitwise-ops.c b/test/Analysis/bitwise-ops.c
index 01daf42..407aa19 100644
--- a/test/Analysis/bitwise-ops.c
+++ b/test/Analysis/bitwise-ops.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -triple x86_64-apple-darwin13 -Wno-shift-count-overflow -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -triple x86_64-apple-darwin13 -Wno-shift-count-overflow -verify %s
 
 void clang_analyzer_eval(int);
 #define CHECK(expr) if (!(expr)) return; clang_analyzer_eval(expr)
diff --git a/test/Analysis/block-in-critical-section.cpp b/test/Analysis/block-in-critical-section.cpp
index 93c0b6d..c65cc61 100644
--- a/test/Analysis/block-in-critical-section.cpp
+++ b/test/Analysis/block-in-critical-section.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.BlockInCriticalSection -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.BlockInCriticalSection -std=c++11 -verify %s
 
 void sleep(int x) {}
 
@@ -9,29 +9,91 @@
 };
 }
 
-void testBlockInCriticalSection() {
+void getc() {}
+void fgets() {}
+void read() {}
+void recv() {}
+
+void pthread_mutex_lock() {}
+void pthread_mutex_trylock() {}
+void pthread_mutex_unlock() {}
+
+void mtx_lock() {}
+void mtx_timedlock() {}
+void mtx_trylock() {}
+void mtx_unlock() {}
+
+void testBlockInCriticalSectionWithStdMutex() {
   std::mutex m;
   m.lock();
-  sleep(3); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
   m.unlock();
 }
 
+void testBlockInCriticalSectionWithPthreadMutex() {
+  pthread_mutex_lock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  pthread_mutex_unlock();
+
+  pthread_mutex_trylock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  pthread_mutex_unlock();
+}
+
+void testBlockInCriticalSectionC11Locks() {
+  mtx_lock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  mtx_unlock();
+
+  mtx_timedlock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  mtx_unlock();
+
+  mtx_trylock();
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+  getc(); // expected-warning {{Call to blocking function 'getc' inside of critical section}}
+  fgets(); // expected-warning {{Call to blocking function 'fgets' inside of critical section}}
+  read(); // expected-warning {{Call to blocking function 'read' inside of critical section}}
+  recv(); // expected-warning {{Call to blocking function 'recv' inside of critical section}}
+  mtx_unlock();
+}
+
 void testBlockInCriticalSectionWithNestedMutexes() {
   std::mutex m, n, k;
   m.lock();
   n.lock();
   k.lock();
-  sleep(3); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
   k.unlock();
-  sleep(5); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(5); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
   n.unlock();
-  sleep(3); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(3); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
   m.unlock();
   sleep(3); // no-warning
 }
 
 void f() {
-  sleep(1000); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(1000); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
 }
 
 void testBlockInCriticalSectionInterProcedural() {
@@ -46,5 +108,5 @@
   m.unlock();
   sleep(1); // no-warning
   m.lock();
-  sleep(1); // expected-warning {{A blocking function %s is called inside a critical section}}
+  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
 }
diff --git a/test/Analysis/blocks-no-inline.c b/test/Analysis/blocks-no-inline.c
index de6f959..859eedf 100644
--- a/test/Analysis/blocks-no-inline.c
+++ b/test/Analysis/blocks-no-inline.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -fblocks -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -fblocks -verify -x c++ %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -fblocks -verify -x c++ %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/blocks.m b/test/Analysis/blocks.m
index bf10c61..98d0f8a 100644
--- a/test/Analysis/blocks.m
+++ b/test/Analysis/blocks.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -analyzer-opt-analyze-nested-blocks -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -analyzer-opt-analyze-nested-blocks -verify -x objective-c++ %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -analyzer-store=region -fblocks -analyzer-opt-analyze-nested-blocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -analyzer-store=region -fblocks -analyzer-opt-analyze-nested-blocks -verify -x objective-c++ %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from Mac OS X headers:
diff --git a/test/Analysis/blocks.mm b/test/Analysis/blocks.mm
index 5f93888..6cff9b4 100644
--- a/test/Analysis/blocks.mm
+++ b/test/Analysis/blocks.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -fblocks -analyzer-opt-analyze-nested-blocks -verify -x objective-c++ %s
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core,debug.DumpCFG -fblocks -analyzer-opt-analyze-nested-blocks  %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -fblocks -analyzer-opt-analyze-nested-blocks -verify -x objective-c++ %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.DumpCFG -fblocks -analyzer-opt-analyze-nested-blocks %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 // expected-no-diagnostics
diff --git a/test/Analysis/bool-assignment.c b/test/Analysis/bool-assignment.c
index 285569e..57a7f0b 100644
--- a/test/Analysis/bool-assignment.c
+++ b/test/Analysis/bool-assignment.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -std=c99 -Dbool=_Bool %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -x c++ %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -std=c99 -Dbool=_Bool %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.BoolAssignment -analyzer-store=region -verify -x c++ %s
 
 // Test C++'s bool and C's _Bool.
 // FIXME: We stopped warning on these when SValBuilder got smarter about
@@ -43,8 +43,11 @@
     return;
   }
   if (y > 200 && y < 250) {
-    // FIXME: Currently we are loosing this warning due to a SymbolCast in RHS.
+#ifdef ANALYZER_CM_Z3
+    BOOL x = y; // expected-warning {{Assignment of a non-Boolean value}}
+#else
     BOOL x = y; // no-warning
+#endif
     return;
   }
   if (y >= 127 && y < 150) {
diff --git a/test/Analysis/bstring.c b/test/Analysis/bstring.c
index 824aa7c..a671d9e 100644
--- a/test/Analysis/bstring.c
+++ b/test/Analysis/bstring.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
 
 //===----------------------------------------------------------------------===
 // Declarations
diff --git a/test/Analysis/bstring.cpp b/test/Analysis/bstring.cpp
index 0b4e7e9..a6d7b40 100644
--- a/test/Analysis/bstring.cpp
+++ b/test/Analysis/bstring.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator-cxx.h"
 #include "Inputs/system-header-simulator-for-malloc.h"
diff --git a/test/Analysis/bug_hash_test.cpp b/test/Analysis/bug_hash_test.cpp
index b73528e..0efcb5f 100644
--- a/test/Analysis/bug_hash_test.cpp
+++ b/test/Analysis/bug_hash_test.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 int function(int p) {
diff --git a/test/Analysis/bug_hash_test.m b/test/Analysis/bug_hash_test.m
index debed32..1e99d3c 100644
--- a/test/Analysis/bug_hash_test.m
+++ b/test/Analysis/bug_hash_test.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 @protocol NSObject
diff --git a/test/Analysis/builtin-functions.cpp b/test/Analysis/builtin-functions.cpp
index d3afab5..4e98597 100644
--- a/test/Analysis/builtin-functions.cpp
+++ b/test/Analysis/builtin-functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection %s -std=c++11 -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,debug.ExprInspection %s -std=c++11 -verify
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/call-invalidation.cpp b/test/Analysis/call-invalidation.cpp
index 80323ff..d3b5fca 100644
--- a/test/Analysis/call-invalidation.cpp
+++ b/test/Analysis/call-invalidation.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/cast-to-struct.cpp b/test/Analysis/cast-to-struct.cpp
index 45d5594..c3aba02 100644
--- a/test/Analysis/cast-to-struct.cpp
+++ b/test/Analysis/cast-to-struct.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.CastToStruct,core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.CastToStruct,core -verify %s
 
 struct AB {
   int A;
@@ -65,3 +65,17 @@
   void *VP = P;
   Abc = (struct ABC *)VP;
 }
+
+// https://llvm.org/bugs/show_bug.cgi?id=31173
+void dontCrash1(struct AB X) {
+  struct UndefS *S = (struct UndefS *)&X;
+}
+
+struct S;
+struct T {
+  struct S *P;
+};
+extern struct S Var1, Var2;
+void dontCrash2() {
+  ((struct T *) &Var1)->P = &Var2;
+}
diff --git a/test/Analysis/castexpr-callback.c b/test/Analysis/castexpr-callback.c
index 73fa17a..3b46093 100644
--- a/test/Analysis/castexpr-callback.c
+++ b/test/Analysis/castexpr-callback.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PreStmtCastExpr=true,debug.AnalysisOrder:PostStmtCastExpr=true %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PreStmtCastExpr=true,debug.AnalysisOrder:PostStmtCastExpr=true %s 2>&1 | FileCheck %s
 
 void test(char c) {
   int i = (int)c;
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
index b5e6e27..3ba12e4 100644
--- a/test/Analysis/casts.c
+++ b/test/Analysis/casts.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
 
 extern void clang_analyzer_eval(_Bool);
 
@@ -118,3 +118,8 @@
   extern float globalFloat;
   clang_analyzer_eval(globalFloat); // expected-warning{{UNKNOWN}}
 }
+
+void locAsIntegerCasts(void *p) {
+  int x = (int) p;
+  clang_analyzer_eval(++x < 10); // no-crash // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/casts.cpp b/test/Analysis/casts.cpp
index 53e1cd0..f96f19b 100644
--- a/test/Analysis/casts.cpp
+++ b/test/Analysis/casts.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify %s
 
 bool PR14634(int x) {
   double y = (double)x;
diff --git a/test/Analysis/casts.m b/test/Analysis/casts.m
index 895c811..5c81ae6 100644
--- a/test/Analysis/casts.m
+++ b/test/Analysis/casts.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 // Test function pointer casts.
diff --git a/test/Analysis/cfg.cpp b/test/Analysis/cfg.cpp
index 3e34a0f..2082773 100644
--- a/test/Analysis/cfg.cpp
+++ b/test/Analysis/cfg.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -triple x86_64-apple-darwin12 -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 // CHECK-LABEL: void checkWrap(int i)
diff --git a/test/Analysis/cfref_PR2519.c b/test/Analysis/cfref_PR2519.c
index d9642e5..5636737 100644
--- a/test/Analysis/cfref_PR2519.c
+++ b/test/Analysis/cfref_PR2519.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 typedef unsigned char Boolean;
diff --git a/test/Analysis/cfref_rdar6080742.c b/test/Analysis/cfref_rdar6080742.c
index 7094660..2f74036 100644
--- a/test/Analysis/cfref_rdar6080742.c
+++ b/test/Analysis/cfref_rdar6080742.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 // This test case was reported in <rdar:problem/6080742>.
diff --git a/test/Analysis/check-deserialization.cpp b/test/Analysis/check-deserialization.cpp
index 2b0bce2..9e4e471 100644
--- a/test/Analysis/check-deserialization.cpp
+++ b/test/Analysis/check-deserialization.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -emit-pch -o %t %s
-// RUN: %clang_cc1 -error-on-deserialized-decl S1_method -include-pch %t -analyze -analyzer-checker=core %s
-// RUN: %clang_cc1 -include-pch %t -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -error-on-deserialized-decl S1_method -include-pch %t -analyzer-checker=core %s
+// RUN: %clang_analyze_cc1 -include-pch %t -analyzer-checker=core -verify %s
 
 #ifndef HEADER
 #define HEADER
diff --git a/test/Analysis/checker-plugins.c b/test/Analysis/checker-plugins.c
index 3882ba6..ee60ec6 100644
--- a/test/Analysis/checker-plugins.c
+++ b/test/Analysis/checker-plugins.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -load %llvmshlibdir/SampleAnalyzerPlugin%pluginext -analyze -analyzer-checker='example.MainCallChecker' -verify %s
+// RUN: %clang_analyze_cc1 -load %llvmshlibdir/SampleAnalyzerPlugin%pluginext -analyzer-checker='example.MainCallChecker' -verify %s
 // REQUIRES: plugins, examples
 
 // Test that the MainCallChecker example analyzer plugin loads and runs.
diff --git a/test/Analysis/chroot.c b/test/Analysis/chroot.c
index 1b818a8..7e514f7 100644
--- a/test/Analysis/chroot.c
+++ b/test/Analysis/chroot.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.Chroot -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.Chroot -analyzer-store region -verify %s
 
 extern int chroot(const char* path);
 extern int chdir(const char* path);
diff --git a/test/Analysis/comparison-implicit-casts.cpp b/test/Analysis/comparison-implicit-casts.cpp
index a991d43..fe5254c 100644
--- a/test/Analysis/comparison-implicit-casts.cpp
+++ b/test/Analysis/comparison-implicit-casts.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple i386-apple-darwin9 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple x86_64-apple-darwin9 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple i386-apple-darwin9 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,debug.ExprInspection -triple x86_64-apple-darwin9 -verify %s
 
 // This file runs in C++ mode so that the comparison type is 'bool', not 'int'.
 void clang_analyzer_eval(int);
diff --git a/test/Analysis/complex-init-list.cpp b/test/Analysis/complex-init-list.cpp
index bbff64b..299f362 100644
--- a/test/Analysis/complex-init-list.cpp
+++ b/test/Analysis/complex-init-list.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
 // expected-no-diagnostics
 
 // Do not crash on initialization to complex numbers.
diff --git a/test/Analysis/complex.c b/test/Analysis/complex.c
index 6aca589..1f61b14 100644
--- a/test/Analysis/complex.c
+++ b/test/Analysis/complex.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify -Wno-unreachable-code -ffreestanding %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify -Wno-unreachable-code -ffreestanding %s
 
 #include <stdint.h>
 
diff --git a/test/Analysis/concrete-address.c b/test/Analysis/concrete-address.c
index 819afca..f1608f8 100644
--- a/test/Analysis/concrete-address.c
+++ b/test/Analysis/concrete-address.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 void foo() {
diff --git a/test/Analysis/conditional-operator.cpp b/test/Analysis/conditional-operator.cpp
index 137dc39..32978c6 100644
--- a/test/Analysis/conditional-operator.cpp
+++ b/test/Analysis/conditional-operator.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection %s -analyzer-output=text -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %s -analyzer-output=text -verify
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/conditional-path-notes.c b/test/Analysis/conditional-path-notes.c
index 448af7f..d842b7f 100644
--- a/test/Analysis/conditional-path-notes.c
+++ b/test/Analysis/conditional-path-notes.c
@@ -1,5 +1,5 @@
-// RUN: %clang --analyze %s -Xanalyzer -analyzer-output=text -Xclang -verify
-// RUN: %clang --analyze %s -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -o %t
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=text -verify
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t
 // RUN: FileCheck --input-file=%t %s
 
 void testCondOp(int *p) {
diff --git a/test/Analysis/const-method-call.cpp b/test/Analysis/const-method-call.cpp
index b8aaeea..17df2a0 100644
--- a/test/Analysis/const-method-call.cpp
+++ b/test/Analysis/const-method-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/constant-folding.c b/test/Analysis/constant-folding.c
index 81d1193..a6d2b74 100644
--- a/test/Analysis/constant-folding.c
+++ b/test/Analysis/constant-folding.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/conversion.c b/test/Analysis/conversion.c
index f202696..a22a567 100644
--- a/test/Analysis/conversion.c
+++ b/test/Analysis/conversion.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-conversion -analyze -analyzer-checker=core,alpha.core.Conversion -verify %s
+// RUN: %clang_analyze_cc1 -Wno-conversion -analyzer-checker=core,alpha.core.Conversion -verify %s
 
 unsigned char U8;
 signed char S8;
@@ -9,9 +9,67 @@
   if (U > 300)
     S8 = U; // expected-warning {{Loss of precision in implicit conversion}}
   if (S > 10)
-    U8 = S;
+    U8 = S; // no-warning
   if (U < 200)
-    S8 = U;
+    S8 = U; // no-warning
+}
+
+void addAssign() {
+  unsigned long L = 1000;
+  int I = -100;
+  U8 += L; // expected-warning {{Loss of precision in implicit conversion}}
+  L += I; // no-warning
+}
+
+void subAssign() {
+  unsigned long L = 1000;
+  int I = -100;
+  U8 -= L; // expected-warning {{Loss of precision in implicit conversion}}
+  L -= I; // no-warning
+}
+
+void mulAssign() {
+  unsigned long L = 1000;
+  int I = -1;
+  U8 *= L; // expected-warning {{Loss of precision in implicit conversion}}
+  L *= I;  // expected-warning {{Loss of sign in implicit conversion}}
+  I = 10;
+  L *= I; // no-warning
+}
+
+void divAssign() {
+  unsigned long L = 1000;
+  int I = -1;
+  U8 /= L; // no-warning
+  L /= I; // expected-warning {{Loss of sign in implicit conversion}}
+}
+
+void remAssign() {
+  unsigned long L = 1000;
+  int I = -1;
+  U8 %= L; // no-warning
+  L %= I; // expected-warning {{Loss of sign in implicit conversion}}
+}
+
+void andAssign() {
+  unsigned long L = 1000;
+  int I = -1;
+  U8 &= L; // no-warning
+  L &= I; // expected-warning {{Loss of sign in implicit conversion}}
+}
+
+void orAssign() {
+  unsigned long L = 1000;
+  int I = -1;
+  U8 |= L; // expected-warning {{Loss of precision in implicit conversion}}
+  L |= I;  // expected-warning {{Loss of sign in implicit conversion}}
+}
+
+void xorAssign() {
+  unsigned long L = 1000;
+  int I = -1;
+  U8 ^= L; // expected-warning {{Loss of precision in implicit conversion}}
+  L ^= I;  // expected-warning {{Loss of sign in implicit conversion}}
 }
 
 void init1() {
@@ -21,7 +79,7 @@
 
 void relational(unsigned U, signed S) {
   if (S > 10) {
-    if (U < S) {
+    if (U < S) { // no-warning
     }
   }
   if (S < -10) {
@@ -32,14 +90,14 @@
 
 void multiplication(unsigned U, signed S) {
   if (S > 5)
-    S = U * S;
+    S = U * S; // no-warning
   if (S < -10)
     S = U * S; // expected-warning {{Loss of sign}}
 }
 
 void division(unsigned U, signed S) {
   if (S > 5)
-    S = U / S;
+    S = U / S; // no-warning
   if (S < -10)
     S = U / S; // expected-warning {{Loss of sign}}
 }
diff --git a/test/Analysis/copypaste/asm.cpp b/test/Analysis/copypaste/asm.cpp
index e93f119..2e3613d 100644
--- a/test/Analysis/copypaste/asm.cpp
+++ b/test/Analysis/copypaste/asm.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -analyze -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/attributes.cpp b/test/Analysis/copypaste/attributes.cpp
index 72d654c..083be74 100644
--- a/test/Analysis/copypaste/attributes.cpp
+++ b/test/Analysis/copypaste/attributes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/blocks.cpp b/test/Analysis/copypaste/blocks.cpp
index 133b5cb..10467b7 100644
--- a/test/Analysis/copypaste/blocks.cpp
+++ b/test/Analysis/copypaste/blocks.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fblocks -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // This tests if we search for clones in blocks.
 
diff --git a/test/Analysis/copypaste/call.cpp b/test/Analysis/copypaste/call.cpp
index 8e95f7c..046229a 100644
--- a/test/Analysis/copypaste/call.cpp
+++ b/test/Analysis/copypaste/call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/catch.cpp b/test/Analysis/copypaste/catch.cpp
index 590ce8f..cf3e807 100644
--- a/test/Analysis/copypaste/catch.cpp
+++ b/test/Analysis/copypaste/catch.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/delete.cpp b/test/Analysis/copypaste/delete.cpp
index dc42c9c..394226b 100644
--- a/test/Analysis/copypaste/delete.cpp
+++ b/test/Analysis/copypaste/delete.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/dependent-exist.cpp b/test/Analysis/copypaste/dependent-exist.cpp
index 5182ba6..9046353 100644
--- a/test/Analysis/copypaste/dependent-exist.cpp
+++ b/test/Analysis/copypaste/dependent-exist.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fms-extensions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fms-extensions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/expr-types.cpp b/test/Analysis/copypaste/expr-types.cpp
index 14eef6e..601f0b1 100644
--- a/test/Analysis/copypaste/expr-types.cpp
+++ b/test/Analysis/copypaste/expr-types.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/fold.cpp b/test/Analysis/copypaste/fold.cpp
index 548dfb1..0aed11b 100644
--- a/test/Analysis/copypaste/fold.cpp
+++ b/test/Analysis/copypaste/fold.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/function-try-block.cpp b/test/Analysis/copypaste/function-try-block.cpp
index 7a69097..d777145 100644
--- a/test/Analysis/copypaste/function-try-block.cpp
+++ b/test/Analysis/copypaste/function-try-block.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // Tests if function try blocks are correctly handled.
 
diff --git a/test/Analysis/copypaste/functions.cpp b/test/Analysis/copypaste/functions.cpp
index c95443d..d2c607b 100644
--- a/test/Analysis/copypaste/functions.cpp
+++ b/test/Analysis/copypaste/functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // This tests if we search for clones in functions.
 
diff --git a/test/Analysis/copypaste/generic.c b/test/Analysis/copypaste/generic.c
index 9d83921..d4d4564 100644
--- a/test/Analysis/copypaste/generic.c
+++ b/test/Analysis/copypaste/generic.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/labels.cpp b/test/Analysis/copypaste/labels.cpp
index 26318ac..eff3330 100644
--- a/test/Analysis/copypaste/labels.cpp
+++ b/test/Analysis/copypaste/labels.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=gnu++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=gnu++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/lambda.cpp b/test/Analysis/copypaste/lambda.cpp
index c13c56f..17c8748 100644
--- a/test/Analysis/copypaste/lambda.cpp
+++ b/test/Analysis/copypaste/lambda.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/macro-complexity.cpp b/test/Analysis/copypaste/macro-complexity.cpp
index aca4df1..70d3f0c 100644
--- a/test/Analysis/copypaste/macro-complexity.cpp
+++ b/test/Analysis/copypaste/macro-complexity.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // Tests that the complexity value of a macro expansion is about the same as
 // the complexity value of a normal function call and the the macro body doesn't
diff --git a/test/Analysis/copypaste/macros.cpp b/test/Analysis/copypaste/macros.cpp
index db9b4c6..bdacd48 100644
--- a/test/Analysis/copypaste/macros.cpp
+++ b/test/Analysis/copypaste/macros.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // Tests that macros and non-macro clones aren't mixed into the same hash
 // group. This is currently necessary as all clones in a hash group need
diff --git a/test/Analysis/copypaste/objc-methods.m b/test/Analysis/copypaste/objc-methods.m
index 9b8002c..e63c7f6 100644
--- a/test/Analysis/copypaste/objc-methods.m
+++ b/test/Analysis/copypaste/objc-methods.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -Wno-objc-root-class -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -Wno-objc-root-class -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // This tests if we search for clones in Objective-C methods.
 
diff --git a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
index 1180d44..7c4f355 100644
--- a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-output=plist -analyzer-config notes-as-events=true -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=plist -analyzer-config notes-as-events=true -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 void log();
diff --git a/test/Analysis/copypaste/plist-diagnostics.cpp b/test/Analysis/copypaste/plist-diagnostics.cpp
index 109d8e4..e2fa759 100644
--- a/test/Analysis/copypaste/plist-diagnostics.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 void log();
diff --git a/test/Analysis/copypaste/sub-sequences.cpp b/test/Analysis/copypaste/sub-sequences.cpp
index ff73632..798662d 100644
--- a/test/Analysis/copypaste/sub-sequences.cpp
+++ b/test/Analysis/copypaste/sub-sequences.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 // This tests if sub-sequences can match with normal sequences.
 
diff --git a/test/Analysis/copypaste/suspicious-clones.cpp b/test/Analysis/copypaste/suspicious-clones.cpp
index c64a1dc..3a760e2 100644
--- a/test/Analysis/copypaste/suspicious-clones.cpp
+++ b/test/Analysis/copypaste/suspicious-clones.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true  -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true  -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -verify %s
 
 // Tests finding a suspicious clone that references local variables.
 
diff --git a/test/Analysis/copypaste/text-diagnostics.cpp b/test/Analysis/copypaste/text-diagnostics.cpp
index a80afdb..a6e358c 100644
--- a/test/Analysis/copypaste/text-diagnostics.cpp
+++ b/test/Analysis/copypaste/text-diagnostics.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-output=text -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=text -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
 
 void log();
 
diff --git a/test/Analysis/coverage.c b/test/Analysis/coverage.c
index 9e437d2..b819f10 100644
--- a/test/Analysis/coverage.c
+++ b/test/Analysis/coverage.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -analyzer-max-loop 4 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-store=region -analyzer-max-loop 4 -verify %s
 #include "Inputs/system-header-simulator.h"
 
 typedef __typeof(sizeof(int)) size_t;
diff --git a/test/Analysis/crash-trace.c b/test/Analysis/crash-trace.c
index bac7447..b79dd02 100644
--- a/test/Analysis/crash-trace.c
+++ b/test/Analysis/crash-trace.c
@@ -1,4 +1,4 @@
-// RUN: not --crash %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
+// RUN: not --crash %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection %s 2>&1 | FileCheck %s
 // REQUIRES: crash-recovery
 
 // FIXME: CHECKs might be incompatible to win32.
diff --git a/test/Analysis/cstring-syntax-cxx.cpp b/test/Analysis/cstring-syntax-cxx.cpp
index 39c978a..b2adef8 100644
--- a/test/Analysis/cstring-syntax-cxx.cpp
+++ b/test/Analysis/cstring-syntax-cxx.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 // Ensure we don't crash on C++ declarations with special names.
diff --git a/test/Analysis/cstring-syntax.c b/test/Analysis/cstring-syntax.c
index 4aa88ed..313ac54 100644
--- a/test/Analysis/cstring-syntax.c
+++ b/test/Analysis/cstring-syntax.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -Wno-strncat-size -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument -Wno-sizeof-pointer-memaccess -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.cstring.BadSizeArg -analyzer-store=region -Wno-strncat-size -Wno-strlcpy-strlcat-size -Wno-sizeof-array-argument -Wno-sizeof-pointer-memaccess -verify %s
 
 typedef __SIZE_TYPE__ size_t;
 char  *strncat(char *, const char *, size_t);
@@ -10,4 +10,6 @@
   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest)); // expected-warning {{Potential buffer overflow. Replace with}}
   strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(dest) - strlen(dest)); // expected-warning {{Potential buffer overflow. Replace with}}
   strncat(dest, src, sizeof(src)); // expected-warning {{Potential buffer overflow. Replace with}}
+  // Should not crash when sizeof has a type argument.
+  strncat(dest, "AAAAAAAAAAAAAAAAAAAAAAAAAAA", sizeof(char));
 }
diff --git a/test/Analysis/ctor.mm b/test/Analysis/ctor.mm
index e7c0c6c..646229a 100644
--- a/test/Analysis/ctor.mm
+++ b/test/Analysis/ctor.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify %s
 
 #include "Inputs/system-header-simulator-cxx.h"
 
diff --git a/test/Analysis/cxx-crashes.cpp b/test/Analysis/cxx-crashes.cpp
index e3f8125..f8234c9 100644
--- a/test/Analysis/cxx-crashes.cpp
+++ b/test/Analysis/cxx-crashes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
 // REQUIRES: LP64
 
 void clang_analyzer_eval(bool);
diff --git a/test/Analysis/cxx-for-range.cpp b/test/Analysis/cxx-for-range.cpp
index 6be8b78..bf3cfbf 100644
--- a/test/Analysis/cxx-for-range.cpp
+++ b/test/Analysis/cxx-for-range.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist-multi-file -o %t.plist -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist-multi-file -o %t.plist -verify %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 extern void work();
diff --git a/test/Analysis/cxx-method-names.cpp b/test/Analysis/cxx-method-names.cpp
index 21be5e4..e57e72d 100644
--- a/test/Analysis/cxx-method-names.cpp
+++ b/test/Analysis/cxx-method-names.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,osx,alpha.unix,alpha.security.taint -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,osx,alpha.unix,alpha.security.taint -analyzer-store region -verify %s
 // expected-no-diagnostics
 
 class Evil {
diff --git a/test/Analysis/cxx11-crashes.cpp b/test/Analysis/cxx11-crashes.cpp
index c6034e6..8905d1c 100644
--- a/test/Analysis/cxx11-crashes.cpp
+++ b/test/Analysis/cxx11-crashes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++11 -verify %s
 
 // radar://11485149, PR12871
 class PlotPoint {
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index c55b34f..05bc64a 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
-// RUN: %clang_cc1 -Wunused-variable -analyze -analyzer-checker=core,deadcode.DeadStores -analyzer-store=region -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -Wunused-variable -analyzer-checker=core,deadcode.DeadStores -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -Wunused-variable -analyzer-checker=core,deadcode.DeadStores -analyzer-store=region -fblocks -verify -Wno-unreachable-code -analyzer-opt-analyze-nested-blocks %s
 
 void f1() {
   int k, y; // expected-warning{{unused variable 'k'}} expected-warning{{unused variable 'y'}}
diff --git a/test/Analysis/dead-stores.cpp b/test/Analysis/dead-stores.cpp
index 77b349e..d926ccf 100644
--- a/test/Analysis/dead-stores.cpp
+++ b/test/Analysis/dead-stores.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyze -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyze -analyzer-store=region -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -fexceptions -fblocks -std=c++11 -analyzer-store=region -analyzer-checker=deadcode.DeadStores -verify -Wno-unreachable-code %s
 
 //===----------------------------------------------------------------------===//
 // Basic dead store checking (but in C++ mode).
diff --git a/test/Analysis/dead-stores.m b/test/Analysis/dead-stores.m
index 8bc6b2e..9f91f39 100644
--- a/test/Analysis/dead-stores.m
+++ b/test/Analysis/dead-stores.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-checker=deadcode.DeadStores,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-checker=deadcode.DeadStores,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 typedef signed char BOOL;
diff --git a/test/Analysis/debug-CallGraph.c b/test/Analysis/debug-CallGraph.c
index 64259e2..9f3865b 100644
--- a/test/Analysis/debug-CallGraph.c
+++ b/test/Analysis/debug-CallGraph.c
@@ -1,4 +1,16 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCallGraph %s -fblocks 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCallGraph %s -fblocks 2>&1 | FileCheck %s
+
+int get5() {
+  return 5;
+}
+
+int add(int val1, int val2) {
+  return val1 + val2;
+}
+
+int test_add() {
+  return add(10, get5());
+}
 
 static void mmm(int y) {
   if (y != 0)
@@ -31,8 +43,18 @@
 void eee() {}
 void fff() { eee(); }
 
+// This test case tests that forward declaration for the top-level function
+// does not affect call graph construction.
+void do_nothing() {}
+void test_single_call();
+void test_single_call() {
+  do_nothing();
+}
+
 // CHECK:--- Call graph Dump ---
-// CHECK-NEXT: {{Function: < root > calls: mmm foo aaa < > bbb ccc ddd eee fff $}}
+// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call $}}
+// CHECK-NEXT: {{Function: test_single_call calls: do_nothing $}}
+// CHECK-NEXT: {{Function: do_nothing calls: $}}
 // CHECK-NEXT: {{Function: fff calls: eee $}}
 // CHECK-NEXT: {{Function: eee calls: $}}
 // CHECK-NEXT: {{Function: ddd calls: ccc $}}
@@ -42,3 +64,6 @@
 // CHECK-NEXT: {{Function: aaa calls: foo $}}
 // CHECK-NEXT: {{Function: foo calls: mmm $}}
 // CHECK-NEXT: {{Function: mmm calls: $}}
+// CHECK-NEXT: {{Function: test_add calls: add get5 $}}
+// CHECK-NEXT: {{Function: add calls: $}}
+// CHECK-NEXT: {{Function: get5 calls: $}}
diff --git a/test/Analysis/default-analyze.m b/test/Analysis/default-analyze.m
index 5fbaa2f..e2f7297 100644
--- a/test/Analysis/default-analyze.m
+++ b/test/Analysis/default-analyze.m
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -o %t
+// RUN: %clang_analyze_cc1 %s -o %t
 
 // Tests that some specific checkers are enabled by default.
 
diff --git a/test/Analysis/default-diagnostic-visitors.c b/test/Analysis/default-diagnostic-visitors.c
index 0bc6a03..c8f64bc 100644
--- a/test/Analysis/default-diagnostic-visitors.c
+++ b/test/Analysis/default-diagnostic-visitors.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core -analyzer-store=region -analyzer-output=text -verify %s
 
 // This file is for testing enhanced diagnostics produced by the default BugReporterVisitors.
 
diff --git a/test/Analysis/delayed-template-parsing-crash.cpp b/test/Analysis/delayed-template-parsing-crash.cpp
index 94a143b..6d189af 100644
--- a/test/Analysis/delayed-template-parsing-crash.cpp
+++ b/test/Analysis/delayed-template-parsing-crash.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -std=c++11 -fdelayed-template-parsing -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++11 -fdelayed-template-parsing -verify %s
 // expected-no-diagnostics
 
 template <class T> struct remove_reference      {typedef T type;};
diff --git a/test/Analysis/delegates.m b/test/Analysis/delegates.m
index 28e9006..2302805 100644
--- a/test/Analysis/delegates.m
+++ b/test/Analysis/delegates.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -Wno-objc-root-class -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -Wno-objc-root-class -verify %s
 // expected-no-diagnostics
 
 
diff --git a/test/Analysis/derived-to-base.cpp b/test/Analysis/derived-to-base.cpp
index e9c7ca8..b9851fd 100644
--- a/test/Analysis/derived-to-base.cpp
+++ b/test/Analysis/derived-to-base.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DCONSTRUCTORS=1 -analyzer-config c++-inlining=constructors -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DCONSTRUCTORS=1 -analyzer-config c++-inlining=constructors -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
diff --git a/test/Analysis/designated-initializer.c b/test/Analysis/designated-initializer.c
index b601f87..920b2f0 100644
--- a/test/Analysis/designated-initializer.c
+++ b/test/Analysis/designated-initializer.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 \
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 \
 // RUN:   | FileCheck %s
 
 struct Q { int a, b, c; };
diff --git a/test/Analysis/diagnostics/deref-track-symbolic-region.c b/test/Analysis/diagnostics/deref-track-symbolic-region.c
index 42060cc..179e736 100644
--- a/test/Analysis/diagnostics/deref-track-symbolic-region.c
+++ b/test/Analysis/diagnostics/deref-track-symbolic-region.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 struct S {
diff --git a/test/Analysis/diagnostics/deref-track-symbolic-region.cpp b/test/Analysis/diagnostics/deref-track-symbolic-region.cpp
index 6d34841..61993f0 100644
--- a/test/Analysis/diagnostics/deref-track-symbolic-region.cpp
+++ b/test/Analysis/diagnostics/deref-track-symbolic-region.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
 
 struct S {
   int *x;
diff --git a/test/Analysis/diagnostics/diag-cross-file-boundaries.c b/test/Analysis/diagnostics/diag-cross-file-boundaries.c
index 270163e..b975af3 100644
--- a/test/Analysis/diagnostics/diag-cross-file-boundaries.c
+++ b/test/Analysis/diagnostics/diag-cross-file-boundaries.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=html -o PR12421.html %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o PR12421.html %s 2>&1 | FileCheck %s
 
 // Test for PR12421
 #include "diag-cross-file-boundaries.h"
diff --git a/test/Analysis/diagnostics/explicit-suppression.cpp b/test/Analysis/diagnostics/explicit-suppression.cpp
index d36def2..193846c 100644
--- a/test/Analysis/diagnostics/explicit-suppression.cpp
+++ b/test/Analysis/diagnostics/explicit-suppression.cpp
@@ -1,5 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=true -DSUPPRESSED=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config suppress-c++-stdlib=true -DSUPPRESSED=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DSUPPRESSED=1 -verify %s
 
 #ifdef SUPPRESSED
 // expected-no-diagnostics
diff --git a/test/Analysis/diagnostics/false-positive-suppression.c b/test/Analysis/diagnostics/false-positive-suppression.c
index cdcd7cc..87c04cb 100644
--- a/test/Analysis/diagnostics/false-positive-suppression.c
+++ b/test/Analysis/diagnostics/false-positive-suppression.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -I %S/Inputs -analyze -analyzer-checker=core,unix -verify %s
+// RUN: %clang_analyze_cc1 -I %S/Inputs -analyzer-checker=core,unix -verify %s
 // expected-no-diagnostics
 
 #include "include/sys/queue.h"
diff --git a/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp b/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp
index 143cbbe..197fad5 100644
--- a/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp
+++ b/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -std=c++11 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/diagnostics/macros.cpp b/test/Analysis/diagnostics/macros.cpp
index 8d7fccd..5aa2c03 100644
--- a/test/Analysis/diagnostics/macros.cpp
+++ b/test/Analysis/diagnostics/macros.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,osx -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,osx -analyzer-output=text -verify %s
 
 #include "../Inputs/system-header-simulator.h"
 #include "../Inputs/system-header-simulator-cxx.h"
diff --git a/test/Analysis/diagnostics/macros.m b/test/Analysis/diagnostics/macros.m
index 7ef80b3..b459974 100644
--- a/test/Analysis/diagnostics/macros.m
+++ b/test/Analysis/diagnostics/macros.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -fblocks -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -fblocks -analyzer-output=text -verify %s
 
 #include "../Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/diagnostics/no-prune-paths.c b/test/Analysis/diagnostics/no-prune-paths.c
index fab5cf8..6e9e457 100644
--- a/test/Analysis/diagnostics/no-prune-paths.c
+++ b/test/Analysis/diagnostics/no-prune-paths.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config prune-paths=false -DNPRUNE=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config prune-paths=false -DNPRUNE=1 -verify %s
 
 // "prune-paths" is a debug option only; this is just a simple test to see that
 // it's being honored.
diff --git a/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp b/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
index 6ed3945..8c66b96 100644
--- a/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
+++ b/test/Analysis/diagnostics/plist-diagnostics-include-check.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -analyzer-output=plist-multi-file %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -analyzer-output=plist-multi-file %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 #include "Inputs/include/plist-diagnostics-include-check-macro.h"
diff --git a/test/Analysis/diagnostics/report-issues-within-main-file.cpp b/test/Analysis/diagnostics/report-issues-within-main-file.cpp
index 5fd7abd..e1dccc8 100644
--- a/test/Analysis/diagnostics/report-issues-within-main-file.cpp
+++ b/test/Analysis/diagnostics/report-issues-within-main-file.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -analyzer-output=plist-multi-file -analyzer-config report-in-main-source-file=true -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-output=plist-multi-file -analyzer-config report-in-main-source-file=true -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 #include "Inputs/include/report-issues-within-main-file.h"
 
@@ -945,7 +945,7 @@
 // CHECK-NEXT:    </dict>
 // CHECK-NEXT:   </array>
 // CHECK-NEXT:   <key>description</key><string>Memory allocated by &apos;new[]&apos; should be deallocated by &apos;delete[]&apos;, not &apos;delete&apos; (within a call to &apos;~auto_ptr&apos;)</string>
-// CHECK-NEXT:   <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:   <key>category</key><string>Memory error</string>
 // CHECK-NEXT:   <key>type</key><string>Bad deallocator</string>
 // CHECK-NEXT:   <key>check_name</key><string>unix.MismatchedDeallocator</string>
 // CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
diff --git a/test/Analysis/diagnostics/shortest-path-suppression.c b/test/Analysis/diagnostics/shortest-path-suppression.c
index 4f648b9..d0fa4b5 100644
--- a/test/Analysis/diagnostics/shortest-path-suppression.c
+++ b/test/Analysis/diagnostics/shortest-path-suppression.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=true -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-null-return-paths=true -analyzer-output=text -verify %s
 // expected-no-diagnostics
 
 int *returnNull() { return 0; }
diff --git a/test/Analysis/diagnostics/text-diagnostics.c b/test/Analysis/diagnostics/text-diagnostics.c
index 5925216..0194647 100644
--- a/test/Analysis/diagnostics/text-diagnostics.c
+++ b/test/Analysis/diagnostics/text-diagnostics.c
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze -Xanalyzer -analyzer-output=text -fno-caret-diagnostics %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.NullDereference -analyzer-output=text -fno-caret-diagnostics %s 2>&1 | FileCheck %s
 
 void testA() {
   int *p = 0;
diff --git a/test/Analysis/diagnostics/undef-value-caller.c b/test/Analysis/diagnostics/undef-value-caller.c
index dc19e0a..4f273bd 100644
--- a/test/Analysis/diagnostics/undef-value-caller.c
+++ b/test/Analysis/diagnostics/undef-value-caller.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
 // RUN: FileCheck --input-file %t %s
 
 #include "undef-value-callee.h"
diff --git a/test/Analysis/diagnostics/undef-value-param.c b/test/Analysis/diagnostics/undef-value-param.c
index 8ebf0da..837b041 100644
--- a/test/Analysis/diagnostics/undef-value-param.c
+++ b/test/Analysis/diagnostics/undef-value-param.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void foo_irrelevant(int c) {
diff --git a/test/Analysis/diagnostics/undef-value-param.m b/test/Analysis/diagnostics/undef-value-param.m
index b9947d8..f8212e0 100644
--- a/test/Analysis/diagnostics/undef-value-param.m
+++ b/test/Analysis/diagnostics/undef-value-param.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 typedef signed char BOOL;
@@ -45,8 +45,8 @@
     CreateRefUndef(&storeRef, 4);
                              //expected-note@-1{{Calling 'CreateRefUndef'}}
                              //expected-note@-2{{Returning from 'CreateRefUndef'}}
-    CFRelease(storeRef); //expected-warning {{Function call argument is an uninitialized value}}
-                         //expected-note@-1{{Function call argument is an uninitialized value}}
+    CFRelease(storeRef); //expected-warning {{1st function call argument is an uninitialized value}}
+                         //expected-note@-1{{1st function call argument is an uninitialized value}}
 }
 @end
 
@@ -918,12 +918,12 @@
 // CHECK-NEXT:      </array>
 // CHECK-NEXT:      <key>depth</key><integer>0</integer>
 // CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Function call argument is an uninitialized value</string>
+// CHECK-NEXT:      <string>1st function call argument is an uninitialized value</string>
 // CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Function call argument is an uninitialized value</string>
+// CHECK-NEXT:      <string>1st function call argument is an uninitialized value</string>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
-// CHECK-NEXT:    <key>description</key><string>Function call argument is an uninitialized value</string>
+// CHECK-NEXT:    <key>description</key><string>1st function call argument is an uninitialized value</string>
 // CHECK-NEXT:    <key>category</key><string>Logic error</string>
 // CHECK-NEXT:    <key>type</key><string>Uninitialized argument value</string>
 // CHECK-NEXT:    <key>check_name</key><string>core.CallAndMessage</string>
diff --git a/test/Analysis/disable-all-checks.c b/test/Analysis/disable-all-checks.c
index 461e6d9..eb55799 100644
--- a/test/Analysis/disable-all-checks.c
+++ b/test/Analysis/disable-all-checks.c
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-disable-all-checks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-disable-all-checks -analyzer-checker=core -analyzer-store=region -verify %s
-// RUN: %clang --analyze -Xanalyzer -analyzer-disable-all-checks -Xclang -verify %s
-// RUN: not %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-disable-checker -verify %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-disable-all-checks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-disable-all-checks -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-disable-all-checks -verify %s
+// RUN: not %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-disable-checker -verify %s 2>&1 | FileCheck %s
 // expected-no-diagnostics
 
 // CHECK: use -analyzer-disable-all-checks to disable all static analyzer checkers
 int buggy() {
   int x = 0;
   return 5/x; // no warning
-}
\ No newline at end of file
+}
diff --git a/test/Analysis/dispatch-once.m b/test/Analysis/dispatch-once.m
index 2f82718..7314dc9 100644
--- a/test/Analysis/dispatch-once.m
+++ b/test/Analysis/dispatch-once.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -w -fblocks -analyze -analyzer-checker=core,osx.API,unix.Malloc -verify %s
-// RUN: %clang_cc1 -w -fblocks -fobjc-arc -analyze -analyzer-checker=core,osx.API,unix.Malloc -verify %s
+// RUN: %clang_analyze_cc1 -w -fblocks -analyzer-checker=core,osx.API,unix.Malloc -verify %s
+// RUN: %clang_analyze_cc1 -w -fblocks -fobjc-arc -analyzer-checker=core,osx.API,unix.Malloc -verify %s
 
 #include "Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/div-zero.cpp b/test/Analysis/div-zero.cpp
index d1261dc..063450d 100644
--- a/test/Analysis/div-zero.cpp
+++ b/test/Analysis/div-zero.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core.DivideZero -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.DivideZero -verify %s
 
 int fooPR10616 (int qX ) {
   int a, c, d;
diff --git a/test/Analysis/division-by-zero.c b/test/Analysis/division-by-zero.c
index d3c228e..33bb6fa 100644
--- a/test/Analysis/division-by-zero.c
+++ b/test/Analysis/division-by-zero.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.Malloc %s
 // Do not crash due to division by zero
 
 int f(unsigned int a) {
diff --git a/test/Analysis/domtest.c b/test/Analysis/domtest.c
index dd72117..e957c8d 100644
--- a/test/Analysis/domtest.c
+++ b/test/Analysis/domtest.c
@@ -1,5 +1,5 @@
 // RUN: rm -f %t
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpDominators %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpDominators %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 // Test the DominatorsTree implementation with various control flows
diff --git a/test/Analysis/dtor-cxx11.cpp b/test/Analysis/dtor-cxx11.cpp
index 7d2e87e..76d5e6c 100644
--- a/test/Analysis/dtor-cxx11.cpp
+++ b/test/Analysis/dtor-cxx11.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config cfg-temporary-dtors=true -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config cfg-temporary-dtors=true -Wno-null-dereference -verify %s
 // expected-no-diagnostics
 
 #include "Inputs/system-header-simulator-cxx.h"
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp
index c677222..bc74130 100644
--- a/test/Analysis/dtor.cpp
+++ b/test/Analysis/dtor.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection,cplusplus -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -Wno-inaccessible-base -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
diff --git a/test/Analysis/dtors-in-dtor-cfg-output.cpp b/test/Analysis/dtors-in-dtor-cfg-output.cpp
index ceda58c..4c1c8dd 100644
--- a/test/Analysis/dtors-in-dtor-cfg-output.cpp
+++ b/test/Analysis/dtors-in-dtor-cfg-output.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
 
 class A {
 public:
diff --git a/test/Analysis/dynamic-cast.cpp b/test/Analysis/dynamic-cast.cpp
index b48ee5b..0c86f81 100644
--- a/test/Analysis/dynamic-cast.cpp
+++ b/test/Analysis/dynamic-cast.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=none -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/dynamic_type_check.m b/test/Analysis/dynamic_type_check.m
index f9b181e..3dc9465 100644
--- a/test/Analysis/dynamic_type_check.m
+++ b/test/Analysis/dynamic_type_check.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.DynamicTypeChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.DynamicTypeChecker -verify %s
 
 
 #define nil 0
diff --git a/test/Analysis/edges-new.mm b/test/Analysis/edges-new.mm
index 5cc21e0..47a125a 100644
--- a/test/Analysis/edges-new.mm
+++ b/test/Analysis/edges-new.mm
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-apple-darwin10 --analyze -Xclang -analyzer-config -Xclang path-diagnostics-alternate=true -Xclang -analyzer-output=plist -o %t %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,deadcode.DeadStores,osx.cocoa.RetainCount,unix.Malloc,unix.MismatchedDeallocator -analyzer-eagerly-assume -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist -o %t -w %s
 // RUN: FileCheck --input-file %t %s
 
 //===----------------------------------------------------------------------===//
@@ -230,7 +230,7 @@
     p = 0;
 
   } while (i< 2);
-  
+
   *p = 0xDEADBEEF;
 }
 
@@ -20042,7 +20042,7 @@
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Potential leak of memory pointed to by &apos;buf&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:    <key>category</key><string>Memory error</string>
 // CHECK-NEXT:    <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:    <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
@@ -20284,7 +20284,7 @@
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Memory allocated by &apos;new[]&apos; should be deallocated by &apos;delete[]&apos;, not &apos;delete&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:    <key>category</key><string>Memory error</string>
 // CHECK-NEXT:    <key>type</key><string>Bad deallocator</string>
 // CHECK-NEXT:    <key>check_name</key><string>unix.MismatchedDeallocator</string>
 // CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
diff --git a/test/Analysis/elementtype.c b/test/Analysis/elementtype.c
index 1b26811..7eba8e1 100644
--- a/test/Analysis/elementtype.c
+++ b/test/Analysis/elementtype.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region %s
 
 typedef struct added_obj_st {
   int type;
diff --git a/test/Analysis/engine/replay-without-inlining.c b/test/Analysis/engine/replay-without-inlining.c
index 14b2b81..0b9820e 100644
--- a/test/Analysis/engine/replay-without-inlining.c
+++ b/test/Analysis/engine/replay-without-inlining.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -verify %s
 // expected-no-diagnostics
 
 typedef struct {
diff --git a/test/Analysis/enum.cpp b/test/Analysis/enum.cpp
index 571fa7b..b561e65 100644
--- a/test/Analysis/enum.cpp
+++ b/test/Analysis/enum.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=debug.ExprInspection %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=debug.ExprInspection %s
 
 void clang_analyzer_eval(bool);
 
@@ -24,3 +24,16 @@
     clang_analyzer_eval(j == 0); // expected-warning{{FALSE}}
   }
 }
+
+enum class EnumBool : bool {
+  F = false,
+  T = true
+};
+
+bool testNoCrashOnSwitchEnumBool(EnumBool E) {
+  switch (E) {
+  case EnumBool::F:
+    return false;
+  }
+  return true;
+}
diff --git a/test/Analysis/exceptions.mm b/test/Analysis/exceptions.mm
index dab1b5e..0e77637 100644
--- a/test/Analysis/exceptions.mm
+++ b/test/Analysis/exceptions.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fexceptions -fobjc-exceptions -fcxx-exceptions -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -fexceptions -fobjc-exceptions -fcxx-exceptions -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
 
 void clang_analyzer_checkInlined(bool);
 
diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c
index 03b6874..577b88b 100644
--- a/test/Analysis/exercise-ps.c
+++ b/test/Analysis/exercise-ps.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 //
 // Just exercise the analyzer on code that has at one point caused issues
 // (i.e., no assertions or crashes).
diff --git a/test/Analysis/explain-svals.c b/test/Analysis/explain-svals.c
new file mode 100644
index 0000000..f1540bb
--- /dev/null
+++ b/test/Analysis/explain-svals.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin,debug.ExprInspection,unix.cstring -verify %s
+
+struct S {
+  int z;
+};
+
+void clang_analyzer_explain_int(int);
+void clang_analyzer_explain_voidp(void *);
+void clang_analyzer_explain_S(struct S);
+
+int glob;
+
+void test_1(int param, void *ptr) {
+  clang_analyzer_explain_voidp(&glob); // expected-warning-re{{{{^pointer to global variable 'glob'$}}}}
+  clang_analyzer_explain_int(param);   // expected-warning-re{{{{^argument 'param'$}}}}
+  clang_analyzer_explain_voidp(ptr);   // expected-warning-re{{{{^argument 'ptr'$}}}}
+  if (param == 42)
+    clang_analyzer_explain_int(param); // expected-warning-re{{{{^signed 32-bit integer '42'$}}}}
+}
+
+void test_2(struct S s) {
+  clang_analyzer_explain_S(s);      //expected-warning-re{{{{^lazily frozen compound value of parameter 's'$}}}}
+  clang_analyzer_explain_voidp(&s); // expected-warning-re{{{{^pointer to parameter 's'$}}}}
+  clang_analyzer_explain_int(s.z);  // expected-warning-re{{{{^initial value of field 'z' of parameter 's'$}}}}
+}
diff --git a/test/Analysis/explain-svals.cpp b/test/Analysis/explain-svals.cpp
index be2f830..d4b56a3 100644
--- a/test/Analysis/explain-svals.cpp
+++ b/test/Analysis/explain-svals.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core.builtin,debug.ExprInspection,unix.cstring -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core.builtin,debug.ExprInspection,unix.cstring -verify %s
 
 typedef unsigned long size_t;
 
diff --git a/test/Analysis/explain-svals.m b/test/Analysis/explain-svals.m
index 34cdacf..dd40946 100644
--- a/test/Analysis/explain-svals.m
+++ b/test/Analysis/explain-svals.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -triple i386-apple-darwin10 -fblocks -analyze -analyzer-checker=core.builtin,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -w -triple i386-apple-darwin10 -fblocks -analyzer-checker=core.builtin,debug.ExprInspection -verify %s
 
 #include "Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/expr-inspection.c b/test/Analysis/expr-inspection.c
index 69e18cb..59406cd 100644
--- a/test/Analysis/expr-inspection.c
+++ b/test/Analysis/expr-inspection.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -verify %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -verify %s 2>&1 | FileCheck %s
 
 // Self-tests for the debug.ExprInspection checker.
 
@@ -19,4 +19,4 @@
 
 // CHECK: Expressions:
 // CHECK-NEXT: clang_analyzer_printState : &code{clang_analyzer_printState}
-// CHECK-NEXT: Ranges are empty.
+// CHECK-NEXT: {{(Ranges are empty.)|(Constraints:[[:space:]]*$)}}
diff --git a/test/Analysis/fields.c b/test/Analysis/fields.c
index a670c50..1aa4840 100644
--- a/test/Analysis/fields.c
+++ b/test/Analysis/fields.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection %s -analyzer-store=region -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection %s -analyzer-store=region -verify
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/free.c b/test/Analysis/free.c
index 3746bf1..acdb282 100644
--- a/test/Analysis/free.c
+++ b/test/Analysis/free.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify -analyzer-config unix.Malloc:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core,unix.Malloc -fblocks -verify -analyzer-config unix.Malloc:Optimistic=true %s
 typedef __typeof(sizeof(int)) size_t;
 void free(void *);
 void *alloca(size_t);
diff --git a/test/Analysis/func.c b/test/Analysis/func.c
index 78afb45..58d4f45 100644
--- a/test/Analysis/func.c
+++ b/test/Analysis/func.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_warnIfReached();
diff --git a/test/Analysis/generics.m b/test/Analysis/generics.m
index da5c512..dac148d 100644
--- a/test/Analysis/generics.m
+++ b/test/Analysis/generics.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s -analyzer-output=plist -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.ObjCGenerics,alpha.core.DynamicTypeChecker -verify -Wno-objc-method-access %s -analyzer-output=plist -o %t.plist
 // RUN: FileCheck --input-file %t.plist %s
 
 #if !__has_feature(objc_generics)
diff --git a/test/Analysis/global-region-invalidation.c b/test/Analysis/global-region-invalidation.c
index bff2201..83df292 100644
--- a/test/Analysis/global-region-invalidation.c
+++ b/test/Analysis/global-region-invalidation.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,alpha.security.taint,debug.TaintTest,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,alpha.security.taint,debug.TaintTest,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/global_region_invalidation.mm b/test/Analysis/global_region_invalidation.mm
index 2369c09..aee3b66 100644
--- a/test/Analysis/global_region_invalidation.mm
+++ b/test/Analysis/global_region_invalidation.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/gmalloc.c b/test/Analysis/gmalloc.c
new file mode 100644
index 0000000..10c4fe2
--- /dev/null
+++ b/test/Analysis/gmalloc.c
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify %s
+
+#include "Inputs/system-header-simulator.h"
+
+typedef void* gpointer;
+typedef const void* gconstpointer;
+typedef unsigned long gsize;
+typedef unsigned int guint;
+
+gpointer g_malloc(gsize n_bytes);
+gpointer g_malloc0(gsize n_bytes);
+gpointer g_realloc(gpointer mem, gsize n_bytes);
+gpointer g_try_malloc(gsize n_bytes);
+gpointer g_try_malloc0(gsize n_bytes);
+gpointer g_try_realloc(gpointer mem, gsize n_bytes);
+void g_free(gpointer mem);
+gpointer g_memdup(gconstpointer mem, guint byte_size);
+
+static const gsize n_bytes = 1024;
+
+void f1() {
+  gpointer g1 = g_malloc(n_bytes);
+  gpointer g2 = g_malloc0(n_bytes);
+  g1 = g_realloc(g1, n_bytes * 2);
+  gpointer g3 = g_try_malloc(n_bytes);
+  gpointer g4 = g_try_malloc0(n_bytes);
+  g3 = g_try_realloc(g3, n_bytes * 2);
+
+  g_free(g1);
+  g_free(g2);
+  g_free(g2); // expected-warning{{Attempt to free released memory}}
+}
+
+void f2() {
+  gpointer g1 = g_malloc(n_bytes);
+  gpointer g2 = g_malloc0(n_bytes);
+  g1 = g_realloc(g1, n_bytes * 2);
+  gpointer g3 = g_try_malloc(n_bytes);
+  gpointer g4 = g_try_malloc0(n_bytes);
+  g3 = g_try_realloc(g3, n_bytes * 2);
+
+  g_free(g1);
+  g_free(g2);
+  g_free(g3);
+  g3 = g_memdup(g3, n_bytes); // expected-warning{{Use of memory after it is freed}}
+}
+
+void f3() {
+  gpointer g1 = g_malloc(n_bytes);
+  gpointer g2 = g_malloc0(n_bytes);
+  g1 = g_realloc(g1, n_bytes * 2);
+  gpointer g3 = g_try_malloc(n_bytes);
+  gpointer g4 = g_try_malloc0(n_bytes);
+  g3 = g_try_realloc(g3, n_bytes * 2); // expected-warning{{Potential leak of memory pointed to by 'g4'}}
+
+  g_free(g1);
+  g_free(g2);
+  g_free(g3);
+}
diff --git a/test/Analysis/gtest.cpp b/test/Analysis/gtest.cpp
index f335695..5797a77 100644
--- a/test/Analysis/gtest.cpp
+++ b/test/Analysis/gtest.cpp
@@ -1,6 +1,6 @@
-//RUN: %clang_cc1 -cc1 -std=c++11 -analyze  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -analyzer-eagerly-assume %s -verify
-//RUN: %clang_cc1 -cc1 -std=c++11 -analyze  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -analyzer-eagerly-assume -DGTEST_VERSION_1_8_AND_LATER=1 %s -verify
-//RUN: %clang_cc1 -cc1 -std=c++11 -analyze  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -analyzer-eagerly-assume -analyzer-config cfg-temporary-dtors=true %s -verify
+//RUN: %clang_analyze_cc1 -cc1 -std=c++11  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -analyzer-eagerly-assume %s -verify
+//RUN: %clang_analyze_cc1 -cc1 -std=c++11  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -analyzer-eagerly-assume -DGTEST_VERSION_1_8_AND_LATER=1 %s -verify
+//RUN: %clang_analyze_cc1 -cc1 -std=c++11  -analyzer-checker=core,apiModeling.google.GTest,debug.ExprInspection -analyzer-eagerly-assume -analyzer-config cfg-temporary-dtors=true %s -verify
 
 void clang_analyzer_eval(int);
 void clang_analyzer_warnIfReached();
diff --git a/test/Analysis/html-diags-multifile.c b/test/Analysis/html-diags-multifile.c
index bb76928..ce1f72b 100644
--- a/test/Analysis/html-diags-multifile.c
+++ b/test/Analysis/html-diags-multifile.c
@@ -1,5 +1,5 @@
 // RUN: mkdir -p %t.dir
-// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %t.dir %s
+// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o %t.dir %s
 // RUN: ls %t.dir | not grep report
 // RUN: rm -fR %t.dir
 
diff --git a/test/Analysis/html-diags.c b/test/Analysis/html-diags.c
index e998020..182bcfb 100644
--- a/test/Analysis/html-diags.c
+++ b/test/Analysis/html-diags.c
@@ -1,11 +1,11 @@
 // RUN: rm -fR %T/dir
 // RUN: mkdir %T/dir
-// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %T/dir %s
+// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o %T/dir %s
 // RUN: ls %T/dir | grep report
 
 // PR16547: Test relative paths
 // RUN: cd %T/dir
-// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o testrelative %s
+// RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o testrelative %s
 // RUN: ls %T/dir/testrelative | grep report
 
 // Currently this test mainly checks that the HTML diagnostics doesn't crash
diff --git a/test/Analysis/identical-expressions.cpp b/test/Analysis/identical-expressions.cpp
index 138cd7c..8bb8237 100644
--- a/test/Analysis/identical-expressions.cpp
+++ b/test/Analysis/identical-expressions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core.IdenticalExpr -w -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core.IdenticalExpr -w -verify %s
 
 /* Only one expected warning per function allowed at the very end. */
 
diff --git a/test/Analysis/index-type.c b/test/Analysis/index-type.c
index fc638df..b86913b 100644
--- a/test/Analysis/index-type.c
+++ b/test/Analysis/index-type.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2 -verify %s
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2 -DM32 -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.security.ArrayBoundV2 -DM32 -verify %s
 // expected-no-diagnostics
 
 #define UINT_MAX (~0u)
diff --git a/test/Analysis/initializer.cpp b/test/Analysis/initializer.cpp
index 0950927..c736356 100644
--- a/test/Analysis/initializer.cpp
+++ b/test/Analysis/initializer.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/initializers-cfg-output.cpp b/test/Analysis/initializers-cfg-output.cpp
index deefbef..ccf4db5 100644
--- a/test/Analysis/initializers-cfg-output.cpp
+++ b/test/Analysis/initializers-cfg-output.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=debug.DumpCFG %s 2>&1 | FileCheck %s
 
 class A {
 public:
diff --git a/test/Analysis/inline-not-supported.c b/test/Analysis/inline-not-supported.c
index 756d5d8..c5f4c74 100644
--- a/test/Analysis/inline-not-supported.c
+++ b/test/Analysis/inline-not-supported.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core -verify %s
 
 // For now, don't inline varargs.
 void foo(int *x, ...) {
diff --git a/test/Analysis/inline-plist.c b/test/Analysis/inline-plist.c
index bccf219..441bb48 100644
--- a/test/Analysis/inline-plist.c
+++ b/test/Analysis/inline-plist.c
@@ -1,5 +1,5 @@
-// RUN: %clang --analyze %s -fblocks -Xanalyzer -analyzer-output=text -Xanalyzer -analyzer-config -Xanalyzer suppress-null-return-paths=false -Xclang -verify %s
-// RUN: %clang --analyze %s -fblocks -Xanalyzer -analyzer-config -Xanalyzer suppress-null-return-paths=false -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -o %t
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference,core.DivideZero -fblocks -analyzer-output=text -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference,core.DivideZero -fblocks -analyzer-output=plist -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false -o %t
 // RUN: FileCheck -input-file %t %s
 
 // <rdar://problem/10967815>
@@ -41,7 +41,7 @@
     // expected-note@-2 {{Taking false branch}}
     return;
   }
-  
+
   if (p == 0) {
     // expected-note@-1 {{Taking true branch}}
     triggers_bug(p);
@@ -59,7 +59,7 @@
   ^(){ // expected-note {{Calling anonymous block}}
     *p = 1; // expected-warning{{Dereference of null pointer (loaded from variable 'p')}} expected-note{{Dereference of null pointer (loaded from variable 'p')}}
   }();
-  
+
 }
 
 void test_block_ret() {
@@ -550,12 +550,12 @@
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>39</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>39</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
@@ -567,7 +567,7 @@
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
 // CHECK-NEXT:       <key>line</key><integer>39</integer>
-// CHECK-NEXT:       <key>col</key><integer>8</integer>
+// CHECK-NEXT:       <key>col</key><integer>7</integer>
 // CHECK-NEXT:       <key>file</key><integer>0</integer>
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:      <key>ranges</key>
@@ -575,7 +575,7 @@
 // CHECK-NEXT:        <array>
 // CHECK-NEXT:         <dict>
 // CHECK-NEXT:          <key>line</key><integer>39</integer>
-// CHECK-NEXT:          <key>col</key><integer>8</integer>
+// CHECK-NEXT:          <key>col</key><integer>7</integer>
 // CHECK-NEXT:          <key>file</key><integer>0</integer>
 // CHECK-NEXT:         </dict>
 // CHECK-NEXT:         <dict>
@@ -600,12 +600,12 @@
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>39</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>39</integer>
-// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
 // CHECK-NEXT:           </dict>
 // CHECK-NEXT:          </array>
diff --git a/test/Analysis/inline-unique-reports.c b/test/Analysis/inline-unique-reports.c
index 4b3c2fe..f827f88 100644
--- a/test/Analysis/inline-unique-reports.c
+++ b/test/Analysis/inline-unique-reports.c
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -o %t > /dev/null 2>&1
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core.NullDereference -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t > /dev/null 2>&1
 // RUN: FileCheck -input-file %t %s
 
 static inline bug(int *p) {
diff --git a/test/Analysis/inline.c b/test/Analysis/inline.c
index 03c4ea8..8fce0fb 100644
--- a/test/Analysis/inline.c
+++ b/test/Analysis/inline.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_checkInlined(int);
diff --git a/test/Analysis/inline.cpp b/test/Analysis/inline.cpp
index 9fc4f81..76eee5b 100644
--- a/test/Analysis/inline.cpp
+++ b/test/Analysis/inline.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
diff --git a/test/Analysis/inline2.c b/test/Analysis/inline2.c
index bae7434..39e6d16 100644
--- a/test/Analysis/inline2.c
+++ b/test/Analysis/inline2.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 
 // Test parameter 'a' is registered to LiveVariables analysis data although it
diff --git a/test/Analysis/inline3.c b/test/Analysis/inline3.c
index e7f4775..2c70fb2 100644
--- a/test/Analysis/inline3.c
+++ b/test/Analysis/inline3.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 
 // Test when entering f1(), we set the right AnalysisDeclContext to Environment.
diff --git a/test/Analysis/inline4.c b/test/Analysis/inline4.c
index 71a379a..a1aac1d 100644
--- a/test/Analysis/inline4.c
+++ b/test/Analysis/inline4.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 
 int g(int a) {    
diff --git a/test/Analysis/inlining/DynDispatchBifurcate.m b/test/Analysis/inlining/DynDispatchBifurcate.m
index 0ce0796..a41a5e3 100644
--- a/test/Analysis/inlining/DynDispatchBifurcate.m
+++ b/test/Analysis/inlining/DynDispatchBifurcate.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 #include "InlineObjCInstanceMethod.h"
 
diff --git a/test/Analysis/inlining/InlineObjCClassMethod.m b/test/Analysis/inlining/InlineObjCClassMethod.m
index c9cc90b..bb869c5 100644
--- a/test/Analysis/inlining/InlineObjCClassMethod.m
+++ b/test/Analysis/inlining/InlineObjCClassMethod.m
@@ -1,6 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 void clang_analyzer_checkInlined(int);
+void clang_analyzer_eval(int);
 
 // Test inlining of ObjC class methods.
 
@@ -194,7 +195,9 @@
 @implementation SelfUsedInParent
 + (int)getNum {return 5;}
 + (int)foo {
-  return [self getNum];
+  int r = [self getNum];
+  clang_analyzer_eval(r == 5); // expected-warning{{TRUE}}
+  return r;
 }
 @end
 @interface SelfUsedInParentChild : SelfUsedInParent
@@ -229,8 +232,80 @@
 + (void)forwardDeclaredVariadicMethod:(int)x, ... {
   clang_analyzer_checkInlined(0); // no-warning
 }
-
 @end
 
+@interface SelfClassTestParent : NSObject
+-(unsigned)returns10;
++(unsigned)returns20;
++(unsigned)returns30;
+@end
 
+@implementation SelfClassTestParent
+-(unsigned)returns10 { return 100; }
++(unsigned)returns20 { return 100; }
++(unsigned)returns30 { return 100; }
+@end
 
+@interface SelfClassTest : SelfClassTestParent
+-(unsigned)returns10;
++(unsigned)returns20;
++(unsigned)returns30;
+@end
+
+@implementation SelfClassTest
+-(unsigned)returns10 { return 10; }
++(unsigned)returns20 { return 20; }
++(unsigned)returns30 { return 30; }
++(void)classMethod {
+  unsigned result1 = [self returns20];
+  clang_analyzer_eval(result1 == 20); // expected-warning{{TRUE}}
+  unsigned result2 = [[self class] returns30];
+  clang_analyzer_eval(result2 == 30); // expected-warning{{TRUE}}
+  unsigned result3 = [[super class] returns30];
+  clang_analyzer_eval(result3 == 100); // expected-warning{{UNKNOWN}}
+}
+-(void)instanceMethod {
+  unsigned result0 = [self returns10];
+  clang_analyzer_eval(result0 == 10); // expected-warning{{TRUE}}
+  unsigned result2 = [[self class] returns30];
+  clang_analyzer_eval(result2 == 30); // expected-warning{{TRUE}}
+  unsigned result3 = [[super class] returns30];
+  clang_analyzer_eval(result3 == 100); // expected-warning{{UNKNOWN}}
+}
+@end
+
+@interface Parent : NSObject
++ (int)a;
++ (int)b;
+@end
+@interface Child : Parent
+@end
+@interface Other : NSObject
++(void)run;
+@end
+int main(int argc, const char * argv[]) {
+  @autoreleasepool {
+    [Other run];
+  }
+  return 0;
+}
+@implementation Other
++(void)run {
+  int result = [Child a];
+  // TODO: This should return 100.
+  clang_analyzer_eval(result == 12); // expected-warning{{TRUE}}
+}
+@end
+@implementation Parent
++ (int)a; {
+  return [self b];
+}
++ (int)b; {
+  return 12;
+}
+@end
+@implementation Child
++ (int)b; {
+  return 100;
+}
+@end
diff --git a/test/Analysis/inlining/InlineObjCInstanceMethod.m b/test/Analysis/inlining/InlineObjCInstanceMethod.m
index f6aa50a..4578a55 100644
--- a/test/Analysis/inlining/InlineObjCInstanceMethod.m
+++ b/test/Analysis/inlining/InlineObjCInstanceMethod.m
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze -Xanalyzer -analyzer-checker=osx.cocoa.IncompatibleMethodTypes,osx.coreFoundation.CFRetainRelease -Xclang -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.DivideZero,core.DynamicTypePropagation,osx.cocoa.IncompatibleMethodTypes -w -verify %s
 
 #include "InlineObjCInstanceMethod.h"
 
diff --git a/test/Analysis/inlining/ObjCDynTypePopagation.m b/test/Analysis/inlining/ObjCDynTypePopagation.m
index ccc2471..0c1d4f2 100644
--- a/test/Analysis/inlining/ObjCDynTypePopagation.m
+++ b/test/Analysis/inlining/ObjCDynTypePopagation.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 #include "InlineObjCInstanceMethod.h"
 
diff --git a/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m b/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m
index 06b271a..d787c7e 100644
--- a/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m
+++ b/test/Analysis/inlining/ObjCImproperDynamictallyDetectableCast.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 typedef signed char BOOL;
 @protocol NSObject  - (BOOL)isEqual:(id)object; @end
diff --git a/test/Analysis/inlining/RetainCountExamples.m b/test/Analysis/inlining/RetainCountExamples.m
index 41479af..938d3e2 100644
--- a/test/Analysis/inlining/RetainCountExamples.m
+++ b/test/Analysis/inlining/RetainCountExamples.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 typedef signed char BOOL;
 typedef struct objc_class *Class;
diff --git a/test/Analysis/inlining/analysis-order.c b/test/Analysis/inlining/analysis-order.c
index 5149818..620732c 100644
--- a/test/Analysis/inlining/analysis-order.c
+++ b/test/Analysis/inlining/analysis-order.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core.builtin.NoReturnFunctions -analyzer-display-progress %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.builtin.NoReturnFunctions -analyzer-display-progress %s 2>&1 | FileCheck %s
 
 // Do not analyze test1() again because it was inlined
 void test1();
diff --git a/test/Analysis/inlining/assume-super-init-does-not-return-nil.m b/test/Analysis/inlining/assume-super-init-does-not-return-nil.m
index fba3e2d..be46776 100644
--- a/test/Analysis/inlining/assume-super-init-does-not-return-nil.m
+++ b/test/Analysis/inlining/assume-super-init-does-not-return-nil.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx -verify %s
 
 typedef signed char BOOL;
 
diff --git a/test/Analysis/inlining/containers.cpp b/test/Analysis/inlining/containers.cpp
index c757da6..16e006b 100644
--- a/test/Analysis/inlining/containers.cpp
+++ b/test/Analysis/inlining/containers.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=false -verify %s
-// RUN: %clang_cc1 -analyze -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=true -DINLINE=1 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=false -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -analyzer-config c++-container-inlining=true -DINLINE=1 -verify %s
 
 #ifndef HEADER
 
diff --git a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
index e23d4e2..0208483 100644
--- a/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
+++ b/test/Analysis/inlining/dyn-dispatch-bifurcate.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify -Wno-reinterpret-base-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config ipa=dynamic-bifurcate -verify -Wno-reinterpret-base-class %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.c b/test/Analysis/inlining/eager-reclamation-path-notes.c
index cd16eb3..7c0f0ec 100644
--- a/test/Analysis/inlining/eager-reclamation-path-notes.c
+++ b/test/Analysis/inlining/eager-reclamation-path-notes.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void use(int *ptr, int val) {
diff --git a/test/Analysis/inlining/eager-reclamation-path-notes.cpp b/test/Analysis/inlining/eager-reclamation-path-notes.cpp
index 8d5e85a..f77a19f 100644
--- a/test/Analysis/inlining/eager-reclamation-path-notes.cpp
+++ b/test/Analysis/inlining/eager-reclamation-path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config graph-trim-interval=5 -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 typedef struct {
diff --git a/test/Analysis/inlining/false-positive-suppression.c b/test/Analysis/inlining/false-positive-suppression.c
index a0bc361..4931695 100644
--- a/test/Analysis/inlining/false-positive-suppression.c
+++ b/test/Analysis/inlining/false-positive-suppression.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-eagerly-assume -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-eagerly-assume -analyzer-checker=core -verify -DSUPPRESSED=1 %s
-// RUN: %clang_cc1 -analyze -analyzer-eagerly-assume -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-eagerly-assume -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-eagerly-assume -analyzer-checker=core -verify -DSUPPRESSED=1 %s
+// RUN: %clang_analyze_cc1 -analyzer-eagerly-assume -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
 
 int opaquePropertyCheck(void *object);
 int coin();
diff --git a/test/Analysis/inlining/false-positive-suppression.cpp b/test/Analysis/inlining/false-positive-suppression.cpp
index bff6907..56659b4 100644
--- a/test/Analysis/inlining/false-positive-suppression.cpp
+++ b/test/Analysis/inlining/false-positive-suppression.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -DSUPPRESSED=1 %s
 
 namespace rdar12676053 {
   // Delta-reduced from a preprocessed file.
diff --git a/test/Analysis/inlining/false-positive-suppression.m b/test/Analysis/inlining/false-positive-suppression.m
index 685e29e..f3532e5 100644
--- a/test/Analysis/inlining/false-positive-suppression.m
+++ b/test/Analysis/inlining/false-positive-suppression.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -DSUPPRESSED=1 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -fobjc-arc -verify -DSUPPRESSED=1 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -DSUPPRESSED=1 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -fobjc-arc -verify -DSUPPRESSED=1 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config avoid-suppressing-null-argument-paths=true -DSUPPRESSED=1 -DNULL_ARGS=1 -verify %s
 
 #define ARC __has_feature(objc_arc)
 
diff --git a/test/Analysis/inlining/inline-defensive-checks.c b/test/Analysis/inlining/inline-defensive-checks.c
index 4ce783c..010d3a7 100644
--- a/test/Analysis/inlining/inline-defensive-checks.c
+++ b/test/Analysis/inlining/inline-defensive-checks.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
 
 // Perform inline defensive checks.
-void idc(int *p) {
+void idc(void *p) {
 	if (p)
 		;
 }
@@ -139,3 +139,42 @@
   int z = y;
   idcTriggerZeroValueThroughCall(z);
 }
+
+struct S {
+  int f1;
+  int f2;
+};
+
+void idcTrackZeroValueThroughUnaryPointerOperators(struct S *s) {
+  idc(s);
+  *(&(s->f1)) = 7; // no-warning
+}
+
+void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset1(struct S *s) {
+  idc(s);
+  int *x = &(s->f2);
+  *x = 7; // no-warning
+}
+
+void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset2(struct S *s) {
+  idc(s);
+  int *x = &(s->f2) - 1;
+  // FIXME: Should not warn.
+  *x = 7; // expected-warning{{Dereference of null pointer}}
+}
+
+void idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S *s) {
+  idc(s);
+  int *x = &(s->f1);
+  *x = 7; // no-warning
+}
+
+
+struct S2 {
+  int a[1];
+};
+
+void idcTrackZeroValueThroughUnaryPointerOperatorsWithArrayField(struct S2 *s) {
+  idc(s);
+  *(&(s->a[0])) = 7; // no-warning
+}
diff --git a/test/Analysis/inlining/inline-defensive-checks.cpp b/test/Analysis/inlining/inline-defensive-checks.cpp
index b69c535..eaae8d2 100644
--- a/test/Analysis/inlining/inline-defensive-checks.cpp
+++ b/test/Analysis/inlining/inline-defensive-checks.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 
 extern void __assert_fail (__const char *__assertion, __const char *__file,
@@ -70,4 +70,17 @@
 void test(int *p1, int *p2) {
   idc(p1);
 	Foo f(p1);
-}
\ No newline at end of file
+}
+
+struct Bar {
+  int x;
+};
+void idcBar(Bar *b) {
+  if (b)
+    ;
+}
+void testRefToField(Bar *b) {
+  idcBar(b);
+  int &x = b->x; // no-warning
+  x = 5;
+}
diff --git a/test/Analysis/inlining/inline-defensive-checks.m b/test/Analysis/inlining/inline-defensive-checks.m
index 0404ee6..38e5446 100644
--- a/test/Analysis/inlining/inline-defensive-checks.m
+++ b/test/Analysis/inlining/inline-defensive-checks.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
 
 typedef signed char BOOL;
 typedef struct objc_class *Class;
diff --git a/test/Analysis/inlining/path-notes.c b/test/Analysis/inlining/path-notes.c
index 403d33d..95adee3 100644
--- a/test/Analysis/inlining/path-notes.c
+++ b/test/Analysis/inlining/path-notes.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config suppress-null-return-paths=false -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config suppress-null-return-paths=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void zero(int **p) {
diff --git a/test/Analysis/inlining/path-notes.cpp b/test/Analysis/inlining/path-notes.cpp
index 2d6886f..4d0b899 100644
--- a/test/Analysis/inlining/path-notes.cpp
+++ b/test/Analysis/inlining/path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-tautological-undefined-compare %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist -Wno-tautological-undefined-compare
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -analyzer-config c++-inlining=destructors -std=c++11 -verify -Wno-tautological-undefined-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config c++-inlining=destructors -std=c++11 -analyzer-config path-diagnostics-alternate=false %s -o %t.plist -Wno-tautological-undefined-compare
 // RUN: FileCheck --input-file=%t.plist %s
 
 class Foo {
diff --git a/test/Analysis/inlining/path-notes.m b/test/Analysis/inlining/path-notes.m
index d9b5a58..7f60ff8 100644
--- a/test/Analysis/inlining/path-notes.m
+++ b/test/Analysis/inlining/path-notes.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=text -analyzer-config suppress-null-return-paths=false -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false -fblocks %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=text -analyzer-config suppress-null-return-paths=false -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.NilArg,osx.cocoa.RetainCount -analyzer-output=plist-multi-file -analyzer-config suppress-null-return-paths=false -analyzer-config path-diagnostics-alternate=false -fblocks %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 typedef struct dispatch_queue_s *dispatch_queue_t;
diff --git a/test/Analysis/inlining/retain-count-self-init.m b/test/Analysis/inlining/retain-count-self-init.m
index 97379db..2081973 100644
--- a/test/Analysis/inlining/retain-count-self-init.m
+++ b/test/Analysis/inlining/retain-count-self-init.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.SelfInit -analyzer-config ipa=dynamic-bifurcate -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.SelfInit -analyzer-config ipa=dynamic-bifurcate -verify %s
 
 typedef signed char BOOL;
 typedef struct objc_class *Class;
diff --git a/test/Analysis/inlining/stl.cpp b/test/Analysis/inlining/stl.cpp
index d89a109..b672be2 100644
--- a/test/Analysis/inlining/stl.cpp
+++ b/test/Analysis/inlining/stl.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -std=c++11 -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -std=c++11 -DINLINE=1 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=false -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDelete,debug.ExprInspection -analyzer-config c++-container-inlining=true -analyzer-config c++-stdlib-inlining=true -std=c++11 -DINLINE=1 -verify %s
 
 #include "../Inputs/system-header-simulator-cxx.h"
 
diff --git a/test/Analysis/inlining/test-always-inline-size-option.c b/test/Analysis/inlining/test-always-inline-size-option.c
index 6b3c13d..85fc8a1 100644
--- a/test/Analysis/inlining/test-always-inline-size-option.c
+++ b/test/Analysis/inlining/test-always-inline-size-option.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-inline-max-stack-depth=3 -analyzer-config ipa-always-inline-size=3 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-inline-max-stack-depth=3 -analyzer-config ipa-always-inline-size=3 -verify %s
 
 void clang_analyzer_eval(int);
 int nested5() {
diff --git a/test/Analysis/inlining/test_objc_inlining_option.m b/test/Analysis/inlining/test_objc_inlining_option.m
index 61408c1..f3a9417 100644
--- a/test/Analysis/inlining/test_objc_inlining_option.m
+++ b/test/Analysis/inlining/test_objc_inlining_option.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config ipa=dynamic-bifurcate -analyzer-config objc-inlining=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config ipa=dynamic-bifurcate -analyzer-config objc-inlining=false -verify %s
 // expected-no-diagnostics
 
 typedef signed char BOOL;
diff --git a/test/Analysis/iterator-past-end.cpp b/test/Analysis/iterator-past-end.cpp
index 4d9ed0c..252d104 100644
--- a/test/Analysis/iterator-past-end.cpp
+++ b/test/Analysis/iterator-past-end.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorPastEnd -analyzer-eagerly-assume -analyzer-config c++-container-inlining=false %s -verify
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorPastEnd -analyzer-eagerly-assume -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorPastEnd -analyzer-eagerly-assume -analyzer-config c++-container-inlining=false %s -verify
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,alpha.cplusplus.IteratorPastEnd -analyzer-eagerly-assume -analyzer-config c++-container-inlining=true -DINLINE=1 %s -verify
 
 #include "Inputs/system-header-simulator-cxx.h"
 
diff --git a/test/Analysis/ivars.m b/test/Analysis/ivars.m
index c717da6..11514d2 100644
--- a/test/Analysis/ivars.m
+++ b/test/Analysis/ivars.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/keychainAPI-diagnostic-visitor.m b/test/Analysis/keychainAPI-diagnostic-visitor.m
index a78b114..d8da697 100644
--- a/test/Analysis/keychainAPI-diagnostic-visitor.m
+++ b/test/Analysis/keychainAPI-diagnostic-visitor.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=osx.SecKeychainAPI -analyzer-store=region -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=osx.SecKeychainAPI -analyzer-store=region -analyzer-output=text -verify %s
 
 // This file is for testing enhanced diagnostics produced by the default SecKeychainAPI checker.
 
diff --git a/test/Analysis/keychainAPI.m b/test/Analysis/keychainAPI.m
index 4fc48c0..1725ce1 100644
--- a/test/Analysis/keychainAPI.m
+++ b/test/Analysis/keychainAPI.m
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.SecKeychainAPI %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.SecKeychainAPI -fblocks %s -verify
+
+#include "Inputs/system-header-simulator-objc.h"
 
 // Fake typedefs.
 typedef unsigned int OSStatus;
@@ -6,8 +8,6 @@
 typedef unsigned int SecKeychainItemRef;
 typedef unsigned int SecItemClass;
 typedef unsigned int UInt32;
-typedef unsigned int CFTypeRef;
-typedef unsigned int UInt16;
 typedef unsigned int SecProtocolType;
 typedef unsigned int SecAuthenticationType;
 typedef unsigned int SecKeychainAttributeInfo;
@@ -77,7 +77,7 @@
   void *outData;
   st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
   if (st == GenericError)
-    SecKeychainItemFreeContent(ptr, outData); // expected-warning{{Only call free if a valid (non-NULL) buffer was returned}}
+    SecKeychainItemFreeContent(ptr, outData);
 } // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
 
 // If null is passed in, the data is not allocated, so no need for the matching free.
@@ -101,14 +101,6 @@
       SecKeychainItemFreeContent(ptr, outData);
 }
 
-void fooOnlyFree() {
-  unsigned int *ptr = 0;
-  OSStatus st = 0;
-  UInt32 length;
-  void *outData = &length;
-  SecKeychainItemFreeContent(ptr, outData);// expected-warning{{Trying to free data which has not been allocated}}
-}
-
 // Do not warn if undefined value is passed to a function.
 void fooOnlyFreeUndef() {
   unsigned int *ptr = 0;
@@ -220,11 +212,27 @@
     if (st == noErr)
       SecKeychainItemFreeContent(ptr, outData[3]);
   }
-  if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}
+  if (length) { // TODO: We do not report a warning here since the symbol is no longer live, but it's not marked as dead.
     length++;
   }
   return 0;
-}// no-warning
+}
+
+int testErrorCodeAsLHS(CFTypeRef keychainOrArray, SecProtocolType protocol,
+        SecAuthenticationType authenticationType, SecKeychainItemRef *itemRef) {
+  unsigned int *ptr = 0;
+  OSStatus st = 0;
+  UInt32 length;
+  void *outData;
+  st = SecKeychainFindInternetPassword(keychainOrArray,
+                                       16, "server", 16, "domain", 16, "account",
+                                       16, "path", 222, protocol, authenticationType,
+                                       &length, &outData, itemRef);
+  if (noErr == st)
+    SecKeychainItemFreeContent(ptr, outData);
+
+  return 0;
+}
 
 void free(void *ptr);
 void deallocateWithFree() {
@@ -251,7 +259,6 @@
 extern const CFAllocatorRef kCFAllocatorNull;
 extern const CFAllocatorRef kCFAllocatorUseContext;
 CFStringRef CFStringCreateWithBytesNoCopy(CFAllocatorRef alloc, const uint8_t *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean externalFormat, CFAllocatorRef contentsDeallocator);
-extern void CFRelease(CFStringRef cf);
 
 void DellocWithCFStringCreate1(CFAllocatorRef alloc) {
   unsigned int *ptr = 0;
@@ -333,11 +340,11 @@
     SecKeychainItemFreeContent(0, pwdBytes);
 }
 
-void radar10508828_2() {
+void radar10508828_20092614() {
   UInt32 pwdLen = 0;
   void*  pwdBytes = 0;
   OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0);
-  SecKeychainItemFreeContent(0, pwdBytes); // expected-warning {{Only call free if a valid (non-NULL) buffer was returned}}
+  SecKeychainItemFreeContent(0, pwdBytes);
 }
 
 //Example from bug 10797.
@@ -426,3 +433,24 @@
       SecKeychainItemFreeContent(attrList, outData);
 }
 
+typedef struct AuthorizationValue {
+    int length;
+    void *data;
+} AuthorizationValue;
+typedef struct AuthorizationCallback {
+    OSStatus (*SetContextVal)(AuthorizationValue *inValue);
+} AuthorizationCallback;
+static AuthorizationCallback cb;
+int radar_19196494() {
+  @autoreleasepool {
+    AuthorizationValue login_password = {};
+    UInt32 passwordLength;
+    void *passwordData = 0;
+    OSStatus err = SecKeychainFindGenericPassword(0, 0, "", 0, "", (UInt32 *)&login_password.length, (void**)&login_password.data, 0);
+    cb.SetContextVal(&login_password);
+    if (err == noErr) {
+      SecKeychainItemFreeContent(0, login_password.data);
+    }
+  }
+  return 0;
+}
diff --git a/test/Analysis/kmalloc-linux.c b/test/Analysis/kmalloc-linux.c
index 87c1107..bac7138 100644
--- a/test/Analysis/kmalloc-linux.c
+++ b/test/Analysis/kmalloc-linux.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-unknown-linux --analyze %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux %s
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/lambda-notes.cpp b/test/Analysis/lambda-notes.cpp
index 661fd05..7abff35 100644
--- a/test/Analysis/lambda-notes.cpp
+++ b/test/Analysis/lambda-notes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core -analyzer-config inline-lambdas=true -analyzer-output plist -verify %s -o %t
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core.DivideZero -analyzer-config inline-lambdas=true -analyzer-output plist -verify %s -o %t
 // RUN: FileCheck --input-file=%t %s
 
 
diff --git a/test/Analysis/lambdas-generalized-capture.cpp b/test/Analysis/lambdas-generalized-capture.cpp
index 790e15e..feaf55d 100644
--- a/test/Analysis/lambdas-generalized-capture.cpp
+++ b/test/Analysis/lambdas-generalized-capture.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -fsyntax-only -analyze -analyzer-checker=core,deadcode,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=core,deadcode,debug.ExprInspection -verify %s
 
 int clang_analyzer_eval(int);
 
diff --git a/test/Analysis/lambdas.cpp b/test/Analysis/lambdas.cpp
index 0b66e6b..f3ff9b9 100644
--- a/test/Analysis/lambdas.cpp
+++ b/test/Analysis/lambdas.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core,deadcode,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -analyze -analyzer-checker=core,debug.DumpCFG -analyzer-config inline-lambdas=true %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,deadcode,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.DumpCFG -analyzer-config inline-lambdas=true %s > %t 2>&1
 // RUN: FileCheck --input-file=%t %s
 
 void clang_analyzer_warnIfReached();
@@ -212,7 +212,7 @@
     callLambda([&](){ ++x; });
     callLambdaFromStatic([&](){ ++x; });
   }
-  
+
   template<typename T>
   static void callLambdaFromStatic(T t) {
     t();
diff --git a/test/Analysis/lambdas.mm b/test/Analysis/lambdas.mm
index dc1a13e..d2b8e7b 100644
--- a/test/Analysis/lambdas.mm
+++ b/test/Analysis/lambdas.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fblocks -Wno-objc-root-class -analyze -analyzer-checker=core,deadcode,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -Wno-objc-root-class -analyzer-checker=core,deadcode,debug.ExprInspection -analyzer-config inline-lambdas=true -verify %s
 
 int clang_analyzer_eval(int);
 
diff --git a/test/Analysis/lifetime-extension.cpp b/test/Analysis/lifetime-extension.cpp
index 124eef3..5e3c5dd 100644
--- a/test/Analysis/lifetime-extension.cpp
+++ b/test/Analysis/lifetime-extension.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-unused -std=c++11 -analyze -analyzer-checker=debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -Wno-unused -std=c++11 -analyzer-checker=debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/lit.local.cfg b/test/Analysis/lit.local.cfg
index da2a68b..1eecdec 100644
--- a/test/Analysis/lit.local.cfg
+++ b/test/Analysis/lit.local.cfg
@@ -1,2 +1,34 @@
+import lit.TestRunner
+import sys
+
+# Custom format class for static analyzer tests
+class AnalyzerTest(lit.formats.ShTest, object):
+
+    def execute(self, test, litConfig):
+        result = self.executeWithAnalyzeSubstitution(test, litConfig, '-analyzer-constraints=range')
+
+        if result.code == lit.Test.FAIL:
+            return result
+
+        # If z3 backend available, add an additional run line for it
+        if test.config.clang_staticanalyzer_z3 == '1':
+            result = self.executeWithAnalyzeSubstitution(test, litConfig, '-analyzer-constraints=z3 -DANALYZER_CM_Z3')
+
+        return result
+
+    def executeWithAnalyzeSubstitution(self, test, litConfig, substitution):
+        saved_substitutions = list(test.config.substitutions)
+        test.config.substitutions.append(('%analyze', substitution))
+        result = lit.TestRunner.executeShTest(test, litConfig, self.execute_external)
+        test.config.substitutions = saved_substitutions
+
+        return result
+
+# This results in a pickling-related failure on Windows
+if (not sys.platform in ['win32']):
+    config.test_format = AnalyzerTest(config.test_format.execute_external)
+else:
+    config.substitutions.append(('%analyze', '-analyzer-constraints=range'))
+
 if config.root.clang_staticanalyzer == 0:
     config.unsupported = True
diff --git a/test/Analysis/live-variables.cpp b/test/Analysis/live-variables.cpp
index 0cfaa1b..2c38b8b 100644
--- a/test/Analysis/live-variables.cpp
+++ b/test/Analysis/live-variables.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // expected-no-diagnostics
 class B {
 public:
diff --git a/test/Analysis/live-variables.m b/test/Analysis/live-variables.m
index eefd292..d2390f3 100644
--- a/test/Analysis/live-variables.m
+++ b/test/Analysis/live-variables.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -fobjc-arc -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -fobjc-arc -verify %s
 // expected-no-diagnostics
 @interface NSObject
 @end
diff --git a/test/Analysis/localization-aggressive.m b/test/Analysis/localization-aggressive.m
index 89950d4..346cf3e 100644
--- a/test/Analysis/localization-aggressive.m
+++ b/test/Analysis/localization-aggressive.m
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -fblocks -x objective-c-header -emit-pch -o %t.pch %S/Inputs/localization-pch.h
 
-// RUN: %clang_cc1 -analyze -fblocks -analyzer-store=region  -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=optin.osx.cocoa.localizability.EmptyLocalizationContextChecker -include-pch %t.pch -verify  -analyzer-config AggressiveReport=true %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-store=region  -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=optin.osx.cocoa.localizability.EmptyLocalizationContextChecker -include-pch %t.pch -verify  -analyzer-config AggressiveReport=true %s
 
 // These declarations were reduced using Delta-Debugging from Foundation.h
 // on Mac OS X.
diff --git a/test/Analysis/localization.m b/test/Analysis/localization.m
index 200eac3..3a6a0d7 100644
--- a/test/Analysis/localization.m
+++ b/test/Analysis/localization.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -fblocks -analyzer-store=region -analyzer-output=text -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=alpha.osx.cocoa.localizability.PluralMisuseChecker -verify  %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-store=region -analyzer-output=text -analyzer-checker=optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker=alpha.osx.cocoa.localizability.PluralMisuseChecker -verify  %s
 
 // The larger set of tests in located in localization.m. These are tests
 // specific for non-aggressive reporting.
diff --git a/test/Analysis/logical-ops.c b/test/Analysis/logical-ops.c
index 0b63bc9..5530501 100644
--- a/test/Analysis/logical-ops.c
+++ b/test/Analysis/logical-ops.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-pointer-bool-conversion -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -Wno-pointer-bool-conversion -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/loop-widening.c b/test/Analysis/loop-widening.c
index 0b9bf70..de17951 100644
--- a/test/Analysis/loop-widening.c
+++ b/test/Analysis/loop-widening.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-max-loop 4 -analyzer-config widen-loops=true -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_warnIfReached();
diff --git a/test/Analysis/lvalue.cpp b/test/Analysis/lvalue.cpp
index 9a6bd59..7621139 100644
--- a/test/Analysis/lvalue.cpp
+++ b/test/Analysis/lvalue.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 int f1() {
diff --git a/test/Analysis/malloc-annotations.c b/test/Analysis/malloc-annotations.c
index 3119cb7..21eaab7 100644
--- a/test/Analysis/malloc-annotations.c
+++ b/test/Analysis/malloc-annotations.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc -analyzer-store=region -verify -analyzer-config unix.Malloc:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc -analyzer-store=region -verify -analyzer-config unix.Malloc:Optimistic=true %s
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
 void free(void *);
diff --git a/test/Analysis/malloc-custom.c b/test/Analysis/malloc-custom.c
index 3c16bbd..f33b150 100644
--- a/test/Analysis/malloc-custom.c
+++ b/test/Analysis/malloc-custom.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -Wno-incompatible-library-redeclaration -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -Wno-incompatible-library-redeclaration -verify %s
 
 // Various tests to make the the analyzer is robust against custom
 // redeclarations of memory routines.
diff --git a/test/Analysis/malloc-interprocedural.c b/test/Analysis/malloc-interprocedural.c
index c78cc6c..4f7daec 100644
--- a/test/Analysis/malloc-interprocedural.c
+++ b/test/Analysis/malloc-interprocedural.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -verify %s
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/malloc-overflow.c b/test/Analysis/malloc-overflow.c
index 99e05ad..d8ad062 100644
--- a/test/Analysis/malloc-overflow.c
+++ b/test/Analysis/malloc-overflow.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.MallocOverflow -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.MallocOverflow -verify %s
 
 #define NULL ((void *) 0)
 typedef __typeof__(sizeof(int)) size_t;
diff --git a/test/Analysis/malloc-overflow.cpp b/test/Analysis/malloc-overflow.cpp
index e3a0408..e070217 100644
--- a/test/Analysis/malloc-overflow.cpp
+++ b/test/Analysis/malloc-overflow.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.MallocOverflow -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.MallocOverflow -verify %s
 // expected-no-diagnostics
 
 class A {
diff --git a/test/Analysis/malloc-overflow2.c b/test/Analysis/malloc-overflow2.c
index 83a2c02..2e1b1d4 100644
--- a/test/Analysis/malloc-overflow2.c
+++ b/test/Analysis/malloc-overflow2.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -analyze -analyzer-checker=alpha.security.MallocOverflow,unix -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -analyzer-checker=alpha.security.MallocOverflow,unix -verify %s
 
 typedef __typeof__(sizeof(int)) size_t;
 extern void *malloc(size_t);
diff --git a/test/Analysis/malloc-plist.c b/test/Analysis/malloc-plist.c
index d6c4f39..e2062e8 100644
--- a/test/Analysis/malloc-plist.c
+++ b/test/Analysis/malloc-plist.c
@@ -1,5 +1,5 @@
 // RUN: rm -f %t
-// RUN: %clang_cc1 -analyze -fblocks -analyzer-checker=core,unix.Malloc -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,unix.Malloc -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
 // RUN: FileCheck -input-file %t %s
 
 typedef __typeof(sizeof(int)) size_t;
@@ -421,7 +421,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;p&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -586,7 +586,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;A&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -974,7 +974,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;buf&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -1376,7 +1376,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;buf&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -1962,7 +1962,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Use of memory after it is freed</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Use-after-free</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -2524,7 +2524,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;buf&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -2795,7 +2795,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;v&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -3144,7 +3144,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Use of memory after it is freed</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Use-after-free</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -3309,7 +3309,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;m&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -3517,7 +3517,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -3725,7 +3725,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -4030,7 +4030,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -4335,7 +4335,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -4543,7 +4543,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -4751,7 +4751,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -4988,7 +4988,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential memory leak</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -5225,7 +5225,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential memory leak</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
@@ -5496,7 +5496,7 @@
 // CHECK-NEXT:      </dict>
 // CHECK-NEXT:     </array>
 // CHECK-NEXT:     <key>description</key><string>Potential memory leak</string>
-// CHECK-NEXT:     <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:     <key>category</key><string>Memory error</string>
 // CHECK-NEXT:     <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:     <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:     <!-- This hash is experimental and going to change! -->
diff --git a/test/Analysis/malloc-protoype.c b/test/Analysis/malloc-protoype.c
index f056f0f..0b8c0f9 100644
--- a/test/Analysis/malloc-protoype.c
+++ b/test/Analysis/malloc-protoype.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -analyze -analyzer-checker=core,unix.Malloc -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,unix.Malloc -verify %s
 // expected-no-diagnostics
 
 // Test that strange prototypes doesn't crash the analyzer
diff --git a/test/Analysis/malloc-sizeof.c b/test/Analysis/malloc-sizeof.c
index 7a8585f..ee10424 100644
--- a/test/Analysis/malloc-sizeof.c
+++ b/test/Analysis/malloc-sizeof.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.MallocSizeof -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.MallocSizeof -verify %s
 
 #include <stddef.h>
 
diff --git a/test/Analysis/malloc-sizeof.cpp b/test/Analysis/malloc-sizeof.cpp
index 8589975..30227a9 100644
--- a/test/Analysis/malloc-sizeof.cpp
+++ b/test/Analysis/malloc-sizeof.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.MallocSizeof -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.MallocSizeof -verify %s
 
 #include <stddef.h>
 
diff --git a/test/Analysis/malloc-three-arg.c b/test/Analysis/malloc-three-arg.c
index 01b08ae..a210337 100644
--- a/test/Analysis/malloc-three-arg.c
+++ b/test/Analysis/malloc-three-arg.c
@@ -1,4 +1,4 @@
-// RUN: %clang -target x86_64-unknown-freebsd --analyze %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-freebsd %s
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index d5bc657..d5f2cfe 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp
index a8a79ca..c323754 100644
--- a/test/Analysis/malloc.cpp
+++ b/test/Analysis/malloc.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -w -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus.NewDelete -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -w -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus.NewDelete -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus.NewDelete -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-unknown-linux-gnu -w -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus.NewDelete -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator-cxx.h"
 
diff --git a/test/Analysis/malloc.m b/test/Analysis/malloc.m
index 9201c2b..1f67dab 100644
--- a/test/Analysis/malloc.m
+++ b/test/Analysis/malloc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -Wno-objc-root-class -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -Wno-objc-root-class -fblocks %s
 #include "Inputs/system-header-simulator-objc.h"
 
 @class NSString;
@@ -29,7 +29,7 @@
     if (error != ((void*)0))
         return error;
 
-    rdar10579586(buffer->str_c); // expected-warning {{Function call argument is an uninitialized value}}
+    rdar10579586(buffer->str_c); // expected-warning {{1st function call argument is an uninitialized value}}
     free(buffer);
     return ((void*)0);
 }
diff --git a/test/Analysis/malloc.mm b/test/Analysis/malloc.mm
index c7fe86b..f8a43b3 100644
--- a/test/Analysis/malloc.mm
+++ b/test/Analysis/malloc.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc -analyzer-store=region -verify -fblocks %s
 #import "Inputs/system-header-simulator-objc.h"
 #import "Inputs/system-header-simulator-for-malloc.h"
 
diff --git a/test/Analysis/max-nodes-suppress-on-sink.c b/test/Analysis/max-nodes-suppress-on-sink.c
index c45bee8..8d955b9 100644
--- a/test/Analysis/max-nodes-suppress-on-sink.c
+++ b/test/Analysis/max-nodes-suppress-on-sink.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config max-nodes=12 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config max-nodes=12 -verify %s
 
 // Here we test how "suppress on sink" feature of certain bugtypes interacts
 // with reaching analysis limits.
diff --git a/test/Analysis/member-expr.cpp b/test/Analysis/member-expr.cpp
index f8dd324..9951943 100644
--- a/test/Analysis/member-expr.cpp
+++ b/test/Analysis/member-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection %s -verify
 
 void clang_analyzer_checkInlined(bool);
 void clang_analyzer_eval(int);
diff --git a/test/Analysis/method-call-intra-p.cpp b/test/Analysis/method-call-intra-p.cpp
index a170942..bead20f 100644
--- a/test/Analysis/method-call-intra-p.cpp
+++ b/test/Analysis/method-call-intra-p.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store region -verify %s
 // expected-no-diagnostics
 
 // Intra-procedural C++ tests.
diff --git a/test/Analysis/method-call-path-notes.cpp b/test/Analysis/method-call-path-notes.cpp
index 8eb07d5..e6253d4 100644
--- a/test/Analysis/method-call-path-notes.cpp
+++ b/test/Analysis/method-call-path-notes.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 // Test warning about null or uninitialized pointer values used as instance member
diff --git a/test/Analysis/method-call.cpp b/test/Analysis/method-call.cpp
index 95db452..4f6a9a4 100644
--- a/test/Analysis/method-call.cpp
+++ b/test/Analysis/method-call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config c++-inlining=constructors -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/misc-ps-64.m b/test/Analysis/misc-ps-64.m
index be50d46..50c0e97 100644
--- a/test/Analysis/misc-ps-64.m
+++ b/test/Analysis/misc-ps-64.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
 // expected-no-diagnostics
 
 // <rdar://problem/6440393> - A bunch of misc. failures involving evaluating
diff --git a/test/Analysis/misc-ps-arm.m b/test/Analysis/misc-ps-arm.m
index a9ea327..9cb7bb2 100644
--- a/test/Analysis/misc-ps-arm.m
+++ b/test/Analysis/misc-ps-arm.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple thumbv7-apple-ios0.0.0 -target-feature +neon -analyze -analyzer-checker=core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple thumbv7-apple-ios0.0.0 -target-feature +neon -analyzer-checker=core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 // <rdar://problem/11405978> - Handle casts of vectors to structs, and loading
diff --git a/test/Analysis/misc-ps-cxx0x.cpp b/test/Analysis/misc-ps-cxx0x.cpp
index 164af5d..1b4516a 100644
--- a/test/Analysis/misc-ps-cxx0x.cpp
+++ b/test/Analysis/misc-ps-cxx0x.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze -std=c++11 %s -Xclang -verify -o /dev/null
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.NullDereference,core.uninitialized.UndefReturn -std=c++11 %s -verify -o /dev/null
 
 void test_static_assert() {
   static_assert(sizeof(void *) == sizeof(void*), "test_static_assert");
diff --git a/test/Analysis/misc-ps-eager-assume.m b/test/Analysis/misc-ps-eager-assume.m
index ca056d8..dbeecf2 100644
--- a/test/Analysis/misc-ps-eager-assume.m
+++ b/test/Analysis/misc-ps-eager-assume.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s -analyzer-eagerly-assume
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s -analyzer-eagerly-assume
 // expected-no-diagnostics
 
 // Delta-reduced header stuff (needed for test cases).
diff --git a/test/Analysis/misc-ps-ranges.m b/test/Analysis/misc-ps-ranges.m
index d8720e9..161d981 100644
--- a/test/Analysis/misc-ps-ranges.m
+++ b/test/Analysis/misc-ps-ranges.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
 
 // <rdar://problem/6776949>
 // main's 'argc' argument is always > 0
diff --git a/test/Analysis/misc-ps-region-store-i386.m b/test/Analysis/misc-ps-region-store-i386.m
index bed6fc3..269a815 100644
--- a/test/Analysis/misc-ps-region-store-i386.m
+++ b/test/Analysis/misc-ps-region-store-i386.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
 // expected-no-diagnostics
 
 // Here is a case where a pointer is treated as integer, invalidated as an
diff --git a/test/Analysis/misc-ps-region-store-x86_64.m b/test/Analysis/misc-ps-region-store-x86_64.m
index 4575ad4..0bdc5a2 100644
--- a/test/Analysis/misc-ps-region-store-x86_64.m
+++ b/test/Analysis/misc-ps-region-store-x86_64.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks %s
 // expected-no-diagnostics
 
 // Here is a case where a pointer is treated as integer, invalidated as an
diff --git a/test/Analysis/misc-ps-region-store.cpp b/test/Analysis/misc-ps-region-store.cpp
index daa6d64..c6dad5d 100644
--- a/test/Analysis/misc-ps-region-store.cpp
+++ b/test/Analysis/misc-ps-region-store.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s -fexceptions -fcxx-exceptions -Wno-tautological-undefined-compare
 
 void clang_analyzer_warnIfReached();
 
diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m
index 5816648..9bd2073 100644
--- a/test/Analysis/misc-ps-region-store.m
+++ b/test/Analysis/misc-ps-region-store.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyze -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyzer-checker=core,alpha.core.CastToStruct,alpha.security.ReturnPtrRange,alpha.security.ArrayBound -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks -Wno-objc-root-class %s
 
 typedef long unsigned int size_t;
 void *memcpy(void *, const void *, size_t);
@@ -396,7 +396,7 @@
 int rdar_7332673_test2_aux(char *x);
 void rdar_7332673_test2() {
     char *value;
-    if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{Function call argument is an uninitialized value}}
+    if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 //===----------------------------------------------------------------------===//
@@ -673,7 +673,7 @@
   builder = ^(id object) {
     id x;
     if (object) {
-      builder(x); // expected-warning{{Block call argument is an uninitialized value}}
+      builder(x); // expected-warning{{1st block call argument is an uninitialized value}}
     }
   };
   builder(target);
diff --git a/test/Analysis/misc-ps-region-store.mm b/test/Analysis/misc-ps-region-store.mm
index c19a90f..4b271c4 100644
--- a/test/Analysis/misc-ps-region-store.mm
+++ b/test/Analysis/misc-ps-region-store.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
 // expected-no-diagnostics
 
 //===------------------------------------------------------------------------------------------===//
diff --git a/test/Analysis/misc-ps.c b/test/Analysis/misc-ps.c
index ad65437..3044dc9 100644
--- a/test/Analysis/misc-ps.c
+++ b/test/Analysis/misc-ps.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -disable-free -analyzer-eagerly-assume -analyzer-checker=core,deadcode,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
index f979cf3..9a75cfd 100644
--- a/test/Analysis/misc-ps.m
+++ b/test/Analysis/misc-ps.m
@@ -1,6 +1,6 @@
 // NOTE: Use '-fobjc-gc' to test the analysis being run twice, and multiple reports are not issued.
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.core,osx.cocoa.AtSync -analyzer-store=region -verify -fblocks -Wno-unreachable-code -Wno-null-dereference -Wno-objc-root-class %s
 
 #ifndef __clang_analyzer__
 #error __clang_analyzer__ not defined
@@ -796,7 +796,7 @@
 void test_bad_call_aux(int x);
 void test_bad_call(void) {
   int y;
-  test_bad_call_aux(y); // expected-warning{{Function call argument is an uninitialized value}}
+  test_bad_call_aux(y); // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 @interface TestBadArg {}
@@ -805,7 +805,7 @@
 
 void test_bad_msg(TestBadArg *p) {
   int y;
-  [p testBadArg:y]; // expected-warning{{Argument in message expression is an uninitialized value}}
+  [p testBadArg:y]; // expected-warning{{1st argument in message expression is an uninitialized value}}
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Analysis/model-file.cpp b/test/Analysis/model-file.cpp
index 41cdf7f..de5a888 100644
--- a/test/Analysis/model-file.cpp
+++ b/test/Analysis/model-file.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config faux-bodies=true,model-path=%S/Inputs/Models -analyzer-output=plist-multi-file -verify %s -o %t
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config faux-bodies=true,model-path=%S/Inputs/Models -analyzer-output=plist-multi-file -verify %s -o %t
 // RUN: FileCheck --input-file=%t %s
 
 typedef int* intptr;
diff --git a/test/Analysis/mpichecker.cpp b/test/Analysis/mpichecker.cpp
index b7a1e00..f764452 100644
--- a/test/Analysis/mpichecker.cpp
+++ b/test/Analysis/mpichecker.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.mpi.MPI-Checker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.mpi.MPI-Checker -verify %s
 
 #include "MPIMock.h"
 
diff --git a/test/Analysis/mpicheckernotes.cpp b/test/Analysis/mpicheckernotes.cpp
index be312fd..994ce8e 100644
--- a/test/Analysis/mpicheckernotes.cpp
+++ b/test/Analysis/mpicheckernotes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.mpi.MPI-Checker -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.mpi.MPI-Checker -analyzer-output=text -verify %s
 
 // MPI-Checker test file to test note diagnostics.
 
diff --git a/test/Analysis/new-with-exceptions.cpp b/test/Analysis/new-with-exceptions.cpp
index 84d77c2..9d02574 100644
--- a/test/Analysis/new-with-exceptions.cpp
+++ b/test/Analysis/new-with-exceptions.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -std=c++11 -fexceptions -fcxx-exceptions -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-store region -std=c++11 -fexceptions -fcxx-exceptions -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/new.cpp b/test/Analysis/new.cpp
index e262aa7..6cfcb1d 100644
--- a/test/Analysis/new.cpp
+++ b/test/Analysis/new.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store region -std=c++11 -verify %s
 #include "Inputs/system-header-simulator-cxx.h"
 
 void clang_analyzer_eval(bool);
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret-region.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret-region.m
index e63e2ca..cbfc266 100644
--- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret-region.m
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret-region.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin8 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin8 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
 
 // <rdar://problem/6888289> - This test case shows that a nil instance
 // variable can possibly be initialized by a method.
diff --git a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
index 4f99390..d4a478d 100644
--- a/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
+++ b/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin8 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.1 2>&1
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin8 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.1 2>&1
 // RUN: FileCheck -input-file=%t.1 -check-prefix=CHECK-darwin8 %s
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.2 2>&1
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.2 2>&1
 // RUN: FileCheck -input-file=%t.2 -check-prefix=CHECK-darwin9 %s
-// RUN: %clang_cc1 -triple thumbv6-apple-ios4.0 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.3 2>&1
+// RUN: %clang_analyze_cc1 -triple thumbv6-apple-ios4.0 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-objc-root-class %s > %t.3 2>&1
 // RUN: FileCheck -input-file=%t.3 -check-prefix=CHECK-darwin9 %s
 
 @interface MyClass {}
diff --git a/test/Analysis/no-exit-cfg.c b/test/Analysis/no-exit-cfg.c
index b3c3fbc..7575152 100644
--- a/test/Analysis/no-exit-cfg.c
+++ b/test/Analysis/no-exit-cfg.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s 
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s 
 // expected-no-diagnostics
 
 // This is a test case for the issue reported in PR 2819:
diff --git a/test/Analysis/no-outofbounds.c b/test/Analysis/no-outofbounds.c
index d401279..ae534a9 100644
--- a/test/Analysis/no-outofbounds.c
+++ b/test/Analysis/no-outofbounds.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,alpha.unix,alpha.security.ArrayBound -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,alpha.unix,alpha.security.ArrayBound -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 //===----------------------------------------------------------------------===//
diff --git a/test/Analysis/no-unreachable-dtors.cpp b/test/Analysis/no-unreachable-dtors.cpp
index e0893b3..1675542 100644
--- a/test/Analysis/no-unreachable-dtors.cpp
+++ b/test/Analysis/no-unreachable-dtors.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.Stats -verify -Wno-unreachable-code %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.Stats -verify -Wno-unreachable-code %s
 
 struct S {
   ~S();
diff --git a/test/Analysis/non-diagnosable-assumptions.c b/test/Analysis/non-diagnosable-assumptions.c
index 50cc8d6..44b69be 100644
--- a/test/Analysis/non-diagnosable-assumptions.c
+++ b/test/Analysis/non-diagnosable-assumptions.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -w -analyze -analyzer-checker=core.DivideZero -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -w -analyzer-checker=core.DivideZero -analyzer-output=text -verify %s
 
 // This test file verifies the "Assuming..." diagnostic pieces that are being
 // reported when the branch condition was too complicated to explain.
diff --git a/test/Analysis/nonnull.m b/test/Analysis/nonnull.m
index c21360d..6db7cfa 100644
--- a/test/Analysis/nonnull.m
+++ b/test/Analysis/nonnull.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -w -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -w -verify %s
 
 @interface MyObject
 - (void)takePointer:(void *)ptr __attribute__((nonnull(1)));
diff --git a/test/Analysis/ns_error_enum.m b/test/Analysis/ns_error_enum.m
new file mode 100644
index 0000000..bf61629
--- /dev/null
+++ b/test/Analysis/ns_error_enum.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -verify %s
+
+#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#define NS_ENUM(_type, _name) CF_ENUM(_type, _name)
+
+#define NS_ERROR_ENUM(_type, _name, _domain)  \
+  enum _name : _type _name; enum __attribute__((ns_error_domain(_domain))) _name : _type
+
+typedef NS_ENUM(unsigned, MyEnum) {
+  MyFirst,
+  MySecond,
+};
+
+typedef NS_ENUM(invalidType, MyInvalidEnum) {
+// expected-error@-1{{unknown type name 'invalidType'}}
+// expected-error@-2{{unknown type name 'invalidType'}}
+  MyFirstInvalid,
+  MySecondInvalid,
+};
+
+const char *MyErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnum, MyErrorDomain) {
+	MyErrFirst,
+	MyErrSecond,
+};
+struct __attribute__((ns_error_domain(MyErrorDomain))) MyStructErrorDomain {};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, InvalidDomain) {
+	// expected-error@-1{{domain argument 'InvalidDomain' does not refer to global constant}}
+	MyErrFirstInvalid,
+	MyErrSecondInvalid,
+};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, "domain-string");
+  // expected-error@-1{{domain argument must be an identifier}}
+
+int __attribute__((ns_error_domain(MyErrorDomain))) NotTagDecl;
+  // expected-error@-1{{ns_error_domain attribute only valid on enums, structs, and unions}}
+
+void foo() {}
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalidFunction, foo);
+  // expected-error@-1{{domain argument 'foo' does not refer to global constant}}
diff --git a/test/Analysis/null-deref-offsets.c b/test/Analysis/null-deref-offsets.c
new file mode 100644
index 0000000..567c479
--- /dev/null
+++ b/test/Analysis/null-deref-offsets.c
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 -w -triple i386-apple-darwin10 -analyzer-checker=core,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(int);
+
+struct S {
+  int x, y;
+  int z[2];
+};
+
+void testOffsets(struct S *s) {
+  if (s != 0)
+    return;
+
+  // FIXME: Here we are testing the hack that computes offsets to null pointers
+  // as 0 in order to find null dereferences of not-exactly-null pointers,
+  // such as &(s->y) below, which is equal to 4 rather than 0 in run-time.
+
+  // These are indeed null.
+  clang_analyzer_eval(s == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&(s->x) == 0); // expected-warning{{TRUE}}
+
+  // FIXME: These should ideally be true.
+  clang_analyzer_eval(&(s->y) == 4); // expected-warning{{FALSE}}
+  clang_analyzer_eval(&(s->z[0]) == 8); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(&(s->z[1]) == 12); // expected-warning{{UNKNOWN}}
+
+  // FIXME: These should ideally be false.
+  clang_analyzer_eval(&(s->y) == 0); // expected-warning{{TRUE}}
+  clang_analyzer_eval(&(s->z[0]) == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(&(s->z[1]) == 0); // expected-warning{{UNKNOWN}}
+
+  // But this should still be a null dereference.
+  s->y = 5; // expected-warning{{Access to field 'y' results in a dereference of a null pointer (loaded from variable 's')}}
+}
diff --git a/test/Analysis/null-deref-path-notes.m b/test/Analysis/null-deref-path-notes.m
index 9e5cab6..242b5da 100644
--- a/test/Analysis/null-deref-path-notes.m
+++ b/test/Analysis/null-deref-path-notes.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-output=text -fblocks -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false -fblocks -Wno-objc-root-class %s -o %t
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-output=text -fblocks -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false -fblocks -Wno-objc-root-class %s -o %t
 // RUN: FileCheck --input-file=%t %s
 
 @interface Root {
diff --git a/test/Analysis/null-deref-ps-region.c b/test/Analysis/null-deref-ps-region.c
index 5bb9454..6ef99ae 100644
--- a/test/Analysis/null-deref-ps-region.c
+++ b/test/Analysis/null-deref-ps-region.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -std=gnu99 -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -std=gnu99 -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index b0d2292..5dee308 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -analyzer-purge=none -verify %s -Wno-error=return-type
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -verify %s -Wno-error=return-type
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -analyzer-purge=none -verify %s -Wno-error=return-type
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=core,deadcode,alpha.core -std=gnu99 -analyzer-store=region -verify %s -Wno-error=return-type
 
 typedef unsigned uintptr_t;
 
@@ -286,7 +286,7 @@
 
 void pr4759() {
   int *p;
-  pr4759_aux(p); // expected-warning{{Function call argument is an uninitialized value}}
+  pr4759_aux(p); // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 // Relax function call arguments invalidation to be aware of const
diff --git a/test/Analysis/nullability-no-arc.mm b/test/Analysis/nullability-no-arc.mm
index e872266..0760186 100644
--- a/test/Analysis/nullability-no-arc.mm
+++ b/test/Analysis/nullability-no-arc.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,nullability -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,nullability -verify %s
 
 #define nil 0
 
diff --git a/test/Analysis/nullability.c b/test/Analysis/nullability.c
index a282969..e0836c6 100644
--- a/test/Analysis/nullability.c
+++ b/test/Analysis/nullability.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability -verify %s
 
 void it_takes_two(int a, int b);
 void function_pointer_arity_mismatch() {
diff --git a/test/Analysis/nullability.mm b/test/Analysis/nullability.mm
index e4f13c6..ddfede5 100644
--- a/test/Analysis/nullability.mm
+++ b/test/Analysis/nullability.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -DNOSYSTEMHEADERS=0 -verify %s
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -DNOSYSTEMHEADERS=0 -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull,nullability.NullablePassedToNonnull,nullability.NullableReturnedFromNonnull,nullability.NullableDereferenced -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
 
 #include "Inputs/system-header-simulator-for-nullability.h"
 
diff --git a/test/Analysis/nullability_nullonly.mm b/test/Analysis/nullability_nullonly.mm
index 359841d..1822539 100644
--- a/test/Analysis/nullability_nullonly.mm
+++ b/test/Analysis/nullability_nullonly.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -DNOSYSTEMHEADERS=0 -verify %s
-// RUN: %clang_cc1 -analyze -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
+// RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -DNOSYSTEMHEADERS=0 -verify %s
+// RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,nullability.NullPassedToNonnull,nullability.NullReturnedFromNonnull -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -DNOSYSTEMHEADERS=1 -verify %s
 
 #include "Inputs/system-header-simulator-for-nullability.h"
 
diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp
index acc525e..229ad7b 100644
--- a/test/Analysis/nullptr.cpp
+++ b/test/Analysis/nullptr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -Wno-conversion-null -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
 
 void clang_analyzer_eval(int);
 
@@ -107,7 +107,7 @@
 void shouldNotCrash() {
   decltype(nullptr) p;
   if (getSymbol())
-    invokeF(p); // expected-warning{{Function call argument is an uninit}}
+    invokeF(p); // expected-warning{{1st function call argument is an uninit}}
   if (getSymbol())
     invokeF(nullptr);
   if (getSymbol()) {
diff --git a/test/Analysis/number-object-conversion.c b/test/Analysis/number-object-conversion.c
index c4ffaaf..8f1e672 100644
--- a/test/Analysis/number-object-conversion.c
+++ b/test/Analysis/number-object-conversion.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -analyzer-checker=osx.NumberObjectConversion %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
 
 #define NULL ((void *)0)
 
diff --git a/test/Analysis/number-object-conversion.cpp b/test/Analysis/number-object-conversion.cpp
index 9dea7b0..7e46a2b 100644
--- a/test/Analysis/number-object-conversion.cpp
+++ b/test/Analysis/number-object-conversion.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyzer-checker=osx.NumberObjectConversion %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
 
 #define NULL ((void *)0)
 #include "Inputs/system-header-simulator-cxx.h" // for nullptr
diff --git a/test/Analysis/number-object-conversion.m b/test/Analysis/number-object-conversion.m
index 08d4a19..8bc0332 100644
--- a/test/Analysis/number-object-conversion.m
+++ b/test/Analysis/number-object-conversion.m
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -w -analyzer-checker=osx.NumberObjectConversion %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -w -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyzer-checker=osx.NumberObjectConversion %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
 
 #include "Inputs/system-header-simulator-objc.h"
 
diff --git a/test/Analysis/objc-arc.m b/test/Analysis/objc-arc.m
index 2d47c18..4b446ab 100644
--- a/test/Analysis/objc-arc.m
+++ b/test/Analysis/objc-arc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-arc -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist-multi-file -o %t.plist %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.RetainCount,deadcode -verify -fblocks -analyzer-opt-analyze-nested-blocks -fobjc-arc -analyzer-config path-diagnostics-alternate=true -analyzer-output=plist-multi-file -o %t.plist %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 typedef signed char BOOL;
diff --git a/test/Analysis/objc-bool.m b/test/Analysis/objc-bool.m
index a2d10cc..98d0cb2 100644
--- a/test/Analysis/objc-bool.m
+++ b/test/Analysis/objc-bool.m
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -o %t -Xclang -verify
+// RUN: %clang_analyze_cc1 %s -o %t -verify
 // expected-no-diagnostics
 
 // Test handling of ObjC bool literals.
diff --git a/test/Analysis/objc-boxing.m b/test/Analysis/objc-boxing.m
index 73386f4..963374b 100644
--- a/test/Analysis/objc-boxing.m
+++ b/test/Analysis/objc-boxing.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-objc-literal-conversion -analyze -analyzer-checker=core,unix.Malloc,osx.cocoa.NonNilReturnValue,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -Wno-objc-literal-conversion -analyzer-checker=core,unix.Malloc,osx.cocoa.NonNilReturnValue,debug.ExprInspection -analyzer-store=region -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/objc-for.m b/test/Analysis/objc-for.m
index d1e044a..41709be 100644
--- a/test/Analysis/objc-for.m
+++ b/test/Analysis/objc-for.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/objc-message.m b/test/Analysis/objc-message.m
index dc0fd1f..f525ce7 100644
--- a/test/Analysis/objc-message.m
+++ b/test/Analysis/objc-message.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
 
 extern void clang_analyzer_warnIfReached();
 void clang_analyzer_eval(int);
diff --git a/test/Analysis/objc-method-coverage.m b/test/Analysis/objc-method-coverage.m
index 489c19b..1915586 100644
--- a/test/Analysis/objc-method-coverage.m
+++ b/test/Analysis/objc-method-coverage.m
@@ -1,5 +1,5 @@
 // REQUIRES: asserts
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-stats -fblocks %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-stats -fblocks %s 2>&1 | FileCheck %s
 @interface I
 int f() {
   return 0;
diff --git a/test/Analysis/objc-properties.m b/test/Analysis/objc-properties.m
index f6ed3e5..88a19a1 100644
--- a/test/Analysis/objc-properties.m
+++ b/test/Analysis/objc-properties.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignment -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignment -verify -fblocks %s
 
 typedef signed char BOOL;
 @protocol NSObject  - (BOOL)isEqual:(id)object; @end
diff --git a/test/Analysis/objc-radar17039661.m b/test/Analysis/objc-radar17039661.m
index fc55ab1..bfb8ef0 100644
--- a/test/Analysis/objc-radar17039661.m
+++ b/test/Analysis/objc-radar17039661.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t
 // RUN: FileCheck --input-file=%t %s
 @class NSString;
 typedef long NSInteger;
diff --git a/test/Analysis/objc-string.mm b/test/Analysis/objc-string.mm
index a32b740..53f3c37 100644
--- a/test/Analysis/objc-string.mm
+++ b/test/Analysis/objc-string.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -Wno-objc-literal-conversion %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -Wno-objc-literal-conversion %s
 
 void clang_analyzer_eval(bool);
 @class NSString;
diff --git a/test/Analysis/objc-subscript.m b/test/Analysis/objc-subscript.m
index ae621c9..155fbb7 100644
--- a/test/Analysis/objc-subscript.m
+++ b/test/Analysis/objc-subscript.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -verify -Wno-objc-root-class %s
 
 typedef signed char BOOL;
 typedef unsigned int NSUInteger;
diff --git a/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m b/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m
index 4777aed..1603a57 100644
--- a/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m
+++ b/test/Analysis/objc/direct-ivar-assignment-in-annotated-functions.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions -verify -fblocks %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions -verify -fblocks %s
 
 typedef signed char BOOL;
 @protocol NSObject  - (BOOL)isEqual:(id)object; @end
diff --git a/test/Analysis/objc_invalidation.m b/test/Analysis/objc_invalidation.m
index cd66444..52a79d8 100644
--- a/test/Analysis/objc_invalidation.m
+++ b/test/Analysis/objc_invalidation.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.osx.cocoa.InstanceVariableInvalidation -DRUN_IVAR_INVALIDATION -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.osx.cocoa.MissingInvalidationMethod -DRUN_MISSING_INVALIDATION_METHOD -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.osx.cocoa.InstanceVariableInvalidation -DRUN_IVAR_INVALIDATION -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.osx.cocoa.MissingInvalidationMethod -DRUN_MISSING_INVALIDATION_METHOD -verify %s
 extern void __assert_fail (__const char *__assertion, __const char *__file,
     unsigned int __line, __const char *__function)
      __attribute__ ((__noreturn__));
diff --git a/test/Analysis/operator-calls.cpp b/test/Analysis/operator-calls.cpp
index 4bd7c12..3107229 100644
--- a/test/Analysis/operator-calls.cpp
+++ b/test/Analysis/operator-calls.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
 void clang_analyzer_eval(bool);
 
 struct X0 { };
diff --git a/test/Analysis/out-of-bounds-new.cpp b/test/Analysis/out-of-bounds-new.cpp
index ee7bb1e..b7ceea7 100644
--- a/test/Analysis/out-of-bounds-new.cpp
+++ b/test/Analysis/out-of-bounds-new.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -Wno-array-bounds -analyze -analyzer-checker=unix,core,alpha.security.ArrayBoundV2 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -Wno-array-bounds -analyzer-checker=unix,core,alpha.security.ArrayBoundV2 -verify %s
 
 // Tests doing an out-of-bounds access after the end of an array using:
 // - constant integer index
diff --git a/test/Analysis/out-of-bounds.c b/test/Analysis/out-of-bounds.c
index ca1e0d0..1970cd6 100644
--- a/test/Analysis/out-of-bounds.c
+++ b/test/Analysis/out-of-bounds.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,alpha.security.ArrayBoundV2,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,alpha.security.ArrayBoundV2,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/outofbound-notwork.c b/test/Analysis/outofbound-notwork.c
index 68b01e0..22ccd9e 100644
--- a/test/Analysis/outofbound-notwork.c
+++ b/test/Analysis/outofbound-notwork.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,alpha.security.ArrayBound -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,alpha.security.ArrayBound -analyzer-store=region -verify %s
 // XFAIL: *
 
 // Once we better handle modeling of sizes of VLAs, we can pull this back
diff --git a/test/Analysis/outofbound.c b/test/Analysis/outofbound.c
index 81ed7ac..35672c0 100644
--- a/test/Analysis/outofbound.c
+++ b/test/Analysis/outofbound.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-array-bounds -analyze -analyzer-checker=core,unix,alpha.security.ArrayBound -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -Wno-array-bounds -analyzer-checker=core,unix,alpha.security.ArrayBound -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
 
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
diff --git a/test/Analysis/override-werror.c b/test/Analysis/override-werror.c
index a68ee1e..7dc09f5 100644
--- a/test/Analysis/override-werror.c
+++ b/test/Analysis/override-werror.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -Werror %s -analyzer-store=region -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -Werror %s -analyzer-store=region -verify
 
 // This test case illustrates that using '-analyze' overrides the effect of
 // -Werror.  This allows basic warnings not to interfere with producing
diff --git a/test/Analysis/padding_c.c b/test/Analysis/padding_c.c
index 93cefca..f4178f5 100644
--- a/test/Analysis/padding_c.c
+++ b/test/Analysis/padding_c.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
 
 #if __has_include(<stdalign.h>)
 #include <stdalign.h>
diff --git a/test/Analysis/padding_cpp.cpp b/test/Analysis/padding_cpp.cpp
index df2f2a8..ee49aea 100644
--- a/test/Analysis/padding_cpp.cpp
+++ b/test/Analysis/padding_cpp.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
 
 // Make sure that the C cases still work fine, even when compiled as C++.
 #include "padding_c.c"
diff --git a/test/Analysis/padding_message.cpp b/test/Analysis/padding_message.cpp
index bbfa453..4c7e061 100644
--- a/test/Analysis/padding_message.cpp
+++ b/test/Analysis/padding_message.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -std=c++14 -analyze -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=2 -verify %s
 
 // expected-warning@+7{{\
 Excessive padding in 'struct IntSandwich' (6 padding bytes, where 2 is optimal). \
diff --git a/test/Analysis/plist-html-macros.c b/test/Analysis/plist-html-macros.c
index dbdbb30..c25346d 100644
--- a/test/Analysis/plist-html-macros.c
+++ b/test/Analysis/plist-html-macros.c
@@ -1,9 +1,9 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 // (sanity check)
 
 // RUN: rm -rf %t.dir
 // RUN: mkdir -p %t.dir
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-output=plist-html -o %t.dir/index.plist %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=plist-html -o %t.dir/index.plist %s
 // RUN: ls %t.dir | grep '\.html' | count 1
 // RUN: grep '\.html' %t.dir/index.plist | count 1
 
diff --git a/test/Analysis/plist-macros.cpp b/test/Analysis/plist-macros.cpp
index 09ad15e..18d3ce1 100644
--- a/test/Analysis/plist-macros.cpp
+++ b/test/Analysis/plist-macros.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -analyzer-eagerly-assume -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -analyzer-eagerly-assume -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=ture %s -o %t.plist
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-eagerly-assume -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -analyzer-eagerly-assume -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=ture %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 
@@ -218,7 +218,7 @@
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Memory allocated by malloc() should be deallocated by free(), not &apos;delete&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:    <key>category</key><string>Memory error</string>
 // CHECK-NEXT:    <key>type</key><string>Bad deallocator</string>
 // CHECK-NEXT:    <key>check_name</key><string>unix.MismatchedDeallocator</string>
 // CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
@@ -315,7 +315,7 @@
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:    </array>
 // CHECK-NEXT:    <key>description</key><string>Potential leak of memory pointed to by &apos;x&apos;</string>
-// CHECK-NEXT:    <key>category</key><string>Memory Error</string>
+// CHECK-NEXT:    <key>category</key><string>Memory error</string>
 // CHECK-NEXT:    <key>type</key><string>Memory leak</string>
 // CHECK-NEXT:    <key>check_name</key><string>unix.Malloc</string>
 // CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
diff --git a/test/Analysis/plist-output-alternate.m b/test/Analysis/plist-output-alternate.m
index 7c8e513..03f3393 100644
--- a/test/Analysis/plist-output-alternate.m
+++ b/test/Analysis/plist-output-alternate.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -fblocks -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -fblocks -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t %s
 // RUN: FileCheck --input-file %t %s
 
 void test_null_init(void) {
diff --git a/test/Analysis/plist-output.m b/test/Analysis/plist-output.m
index affbb5d..a80ab5c 100644
--- a/test/Analysis/plist-output.m
+++ b/test/Analysis/plist-output.m
@@ -1,4 +1,4 @@
-// RUN: %clang --analyze %s -Xanalyzer -analyzer-checker=osx.cocoa.RetainCount -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -Xanalyzer -analyzer-config -Xanalyzer path-diagnostics-alternate=false -o %t.plist
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=osx.cocoa.RetainCount,deadcode.DeadStores,core -analyzer-output=plist -analyzer-config path-diagnostics-alternate=false -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 void test_null_init(void) {
@@ -24,7 +24,7 @@
     *p = 0xDEADBEEF;
   }
 }
-  
+
 void test_null_cond_transitive(int *q) {
   if (!q) {
     int *p = q;
@@ -51,7 +51,7 @@
 }
 
 int *bar_cond_assign();
-int test_cond_assign() { 
+int test_cond_assign() {
   int *p;
   if (p = bar_cond_assign())
     return 1;
@@ -138,7 +138,7 @@
 
 void test_loop_diagnostics_2() {
   int *p = 0;
-  for (int i = 0; i < 2; ) { 
+  for (int i = 0; i < 2; ) {
     ++i;
     p = 0;
   }
@@ -166,9 +166,9 @@
 @interface RDar12114812 { char *p; }
 @end
 
-@implementation RDar12114812 
+@implementation RDar12114812
 - (void)test {
-  p = 0;        
+  p = 0;
   *p = 1;
 }
 @end
@@ -2686,103 +2686,6 @@
 // CHECK-NEXT:       </array>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>108</integer>
-// CHECK-NEXT:       <key>col</key><integer>24</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>108</integer>
-// CHECK-NEXT:          <key>col</key><integer>24</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>108</integer>
-// CHECK-NEXT:          <key>col</key><integer>28</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;i&apos; is &gt;= &apos;x&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;i&apos; is &gt;= &apos;x&apos;</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>24</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>108</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
@@ -2992,103 +2895,6 @@
 // CHECK-NEXT:       </array>
 // CHECK-NEXT:     </dict>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>11</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>11</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>event</string>
-// CHECK-NEXT:      <key>location</key>
-// CHECK-NEXT:      <dict>
-// CHECK-NEXT:       <key>line</key><integer>117</integer>
-// CHECK-NEXT:       <key>col</key><integer>11</integer>
-// CHECK-NEXT:       <key>file</key><integer>0</integer>
-// CHECK-NEXT:      </dict>
-// CHECK-NEXT:      <key>ranges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:        <array>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>117</integer>
-// CHECK-NEXT:          <key>col</key><integer>11</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:         <dict>
-// CHECK-NEXT:          <key>line</key><integer>117</integer>
-// CHECK-NEXT:          <key>col</key><integer>15</integer>
-// CHECK-NEXT:          <key>file</key><integer>0</integer>
-// CHECK-NEXT:         </dict>
-// CHECK-NEXT:        </array>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:      <key>depth</key><integer>0</integer>
-// CHECK-NEXT:      <key>extended_message</key>
-// CHECK-NEXT:      <string>Assuming &apos;i&apos; is &gt;= &apos;x&apos;</string>
-// CHECK-NEXT:      <key>message</key>
-// CHECK-NEXT:      <string>Assuming &apos;i&apos; is &gt;= &apos;x&apos;</string>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>kind</key><string>control</string>
-// CHECK-NEXT:      <key>edges</key>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>start</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>11</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>11</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:         <key>end</key>
-// CHECK-NEXT:          <array>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>3</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:           <dict>
-// CHECK-NEXT:            <key>line</key><integer>117</integer>
-// CHECK-NEXT:            <key>col</key><integer>5</integer>
-// CHECK-NEXT:            <key>file</key><integer>0</integer>
-// CHECK-NEXT:           </dict>
-// CHECK-NEXT:          </array>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <dict>
 // CHECK-NEXT:      <key>kind</key><string>event</string>
 // CHECK-NEXT:      <key>location</key>
 // CHECK-NEXT:      <dict>
diff --git a/test/Analysis/pointer-to-member.cpp b/test/Analysis/pointer-to-member.cpp
index 039782b..0fbb992 100644
--- a/test/Analysis/pointer-to-member.cpp
+++ b/test/Analysis/pointer-to-member.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/pr22954.c b/test/Analysis/pr22954.c
index 01aa5b3..64a00c5 100644
--- a/test/Analysis/pr22954.c
+++ b/test/Analysis/pr22954.c
@@ -3,7 +3,7 @@
 // At the moment the whole of the destination array content is invalidated.
 // If a.s1 region has a symbolic offset, the whole region of 'a' is invalidated.
 // Specific triple set to test structures of size 0.
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
 
 typedef __typeof(sizeof(int)) size_t;
 
diff --git a/test/Analysis/pr4209.m b/test/Analysis/pr4209.m
index 29abe94..8b0eaca 100644
--- a/test/Analysis/pr4209.m
+++ b/test/Analysis/pr4209.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-incomplete-implementation -verify %s
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -Wno-incomplete-implementation -verify %s
 
 // This test case was crashing due to how CFRefCount.cpp resolved the
 // ObjCInterfaceDecl* and ClassName in EvalObjCMessageExpr.
diff --git a/test/Analysis/pr_2542_rdar_6793404.m b/test/Analysis/pr_2542_rdar_6793404.m
index 6f1ebf9..5df40e8 100644
--- a/test/Analysis/pr_2542_rdar_6793404.m
+++ b/test/Analysis/pr_2542_rdar_6793404.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -pedantic -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -pedantic -analyzer-store=region -verify -Wno-objc-root-class %s
 
 // BEGIN delta-debugging reduced header stuff
 
diff --git a/test/Analysis/pr_4164.c b/test/Analysis/pr_4164.c
index 0d2ca41..02c1f41 100644
--- a/test/Analysis/pr_4164.c
+++ b/test/Analysis/pr_4164.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin9 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 
 // PR 4164: http://llvm.org/bugs/show_bug.cgi?id=4164
diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m
index 235a968..e792bb2 100644
--- a/test/Analysis/properties.m
+++ b/test/Analysis/properties.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.Dealloc,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
 
 void clang_analyzer_eval(int);
 
@@ -987,5 +987,21 @@
 }
 
 @end
+
+@interface Wrapper
+@property(nonatomic, readonly) int value;
+@end
+
+@implementation Wrapper
+@synthesize value;
+@end
+
+void testNoCrashWhenAccessPropertyAndThereAreNoDirectBindingsAtAll() {
+   union {
+    Wrapper *wrapper;
+   } u = { 0 };
+   [u.wrapper value];
+}
+
 #endif // non-ARC
 
diff --git a/test/Analysis/properties.mm b/test/Analysis/properties.mm
index e49d034..2d93d6d 100644
--- a/test/Analysis/properties.mm
+++ b/test/Analysis/properties.mm
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,debug.ExprInspection -analyzer-store=region -verify -Wno-objc-root-class -fobjc-arc %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
diff --git a/test/Analysis/pthreadlock.c b/test/Analysis/pthreadlock.c
index a6e29e7..9886817 100644
--- a/test/Analysis/pthreadlock.c
+++ b/test/Analysis/pthreadlock.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.PthreadLock -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.PthreadLock -verify %s
 
 // Tests performing normal locking patterns and wrong locking orders
 
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
index 2b15bad..b78ec50 100644
--- a/test/Analysis/ptr-arith.c
+++ b/test/Analysis/ptr-arith.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple x86_64-apple-darwin9 -Wno-tautological-pointer-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.FixedAddr,alpha.core.PointerArithm,alpha.core.PointerSub,debug.ExprInspection -analyzer-store=region -verify -triple i686-apple-darwin9 -Wno-tautological-pointer-compare %s
 
 void clang_analyzer_eval(int);
 
@@ -213,7 +213,12 @@
   }
 
   clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}}
+// FIXME: In Z3ConstraintManager, ptrdiff_t is mapped to signed bitvector. However, this does not directly imply the unsigned comparison.
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}}
+#endif
   clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}
 
   if (lhs >= rhs) {
@@ -223,7 +228,11 @@
 
   clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
   clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}}
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}}
+#endif
 }
 
 void size_implies_comparison(int *lhs, int *rhs) {
@@ -234,7 +243,11 @@
     return;
   }
 
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(lhs <= rhs); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(lhs <= rhs); // expected-warning{{TRUE}}
+#endif
   clang_analyzer_eval((rhs - lhs) >= 0); // expected-warning{{TRUE}}
   clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{UNKNOWN}}
 
@@ -244,7 +257,11 @@
   }
 
   clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(lhs < rhs); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(lhs < rhs); // expected-warning{{TRUE}}
+#endif
   clang_analyzer_eval((rhs - lhs) > 0); // expected-warning{{TRUE}}
 }
 
@@ -255,30 +272,42 @@
 void zero_implies_reversed_equal(int *lhs, int *rhs) {
   clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{UNKNOWN}}
   if ((rhs - lhs) == 0) {
-    // FIXME: Should be FALSE.
+#ifdef ANALYZER_CM_Z3
+    clang_analyzer_eval(rhs != lhs); // expected-warning{{FALSE}}
+    clang_analyzer_eval(rhs == lhs); // expected-warning{{TRUE}}
+#else
     clang_analyzer_eval(rhs != lhs); // expected-warning{{UNKNOWN}}
-    // FIXME: Should be TRUE.
     clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+#endif
     return;
   }
   clang_analyzer_eval((rhs - lhs) == 0); // expected-warning{{FALSE}}
-  // FIXME: Should be FALSE.
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(rhs == lhs); // expected-warning{{FALSE}}
+  clang_analyzer_eval(rhs != lhs); // expected-warning{{TRUE}}
+#else
   clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
-  // FIXME: Should be TRUE.
   clang_analyzer_eval(rhs != lhs); // expected-warning{{UNKNOWN}}
+#endif
 }
 
 void canonical_equal(int *lhs, int *rhs) {
   clang_analyzer_eval(lhs == rhs); // expected-warning{{UNKNOWN}}
   if (lhs == rhs) {
-    // FIXME: Should be TRUE.
+#ifdef ANALYZER_CM_Z3
+    clang_analyzer_eval(rhs == lhs); // expected-warning{{TRUE}}
+#else
     clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+#endif
     return;
   }
   clang_analyzer_eval(lhs == rhs); // expected-warning{{FALSE}}
 
-  // FIXME: Should be FALSE.
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(rhs == lhs); // expected-warning{{FALSE}}
+#else
   clang_analyzer_eval(rhs == lhs); // expected-warning{{UNKNOWN}}
+#endif
 }
 
 void compare_element_region_and_base(int *p) {
diff --git a/test/Analysis/ptr-arith.cpp b/test/Analysis/ptr-arith.cpp
index 07ddec3..e1860f4 100644
--- a/test/Analysis/ptr-arith.cpp
+++ b/test/Analysis/ptr-arith.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-unused-value -std=c++14 -analyze -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
+// RUN: %clang_analyze_cc1 -Wno-unused-value -std=c++14 -analyzer-checker=core,debug.ExprInspection,alpha.core.PointerArithm -verify %s
 struct X {
   int *p;
   int zero;
diff --git a/test/Analysis/qt_malloc.cpp b/test/Analysis/qt_malloc.cpp
index 200556e..ad25634 100644
--- a/test/Analysis/qt_malloc.cpp
+++ b/test/Analysis/qt_malloc.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus -analyzer-store=region -verify %s
 // expected-no-diagnostics
 #include "Inputs/qt-simulator.h"
 
diff --git a/test/Analysis/range_casts.c b/test/Analysis/range_casts.c
index 682369c..a01ab5d 100644
--- a/test/Analysis/range_casts.c
+++ b/test/Analysis/range_casts.c
@@ -1,5 +1,5 @@
 // This test checks that intersecting ranges does not cause 'system is over constrained' assertions in the case of eg: 32 bits unsigned integers getting their range from 64 bits signed integers.
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,debug.ExprInspection -analyzer-store=region -verify %s
 
 void clang_analyzer_warnIfReached();
 
diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m
index 31a300c..d840000 100644
--- a/test/Analysis/rdar-6442306-1.m
+++ b/test/Analysis/rdar-6442306-1.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-disable-checker=alpha.core.PointerArithm %s -analyzer-store=region -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-disable-checker=alpha.core.PointerArithm %s -analyzer-store=region -verify
 // expected-no-diagnostics
 
 typedef int bar_return_t;
diff --git a/test/Analysis/rdar-6540084.m b/test/Analysis/rdar-6540084.m
index 2119df5..da7d42c 100644
--- a/test/Analysis/rdar-6540084.m
+++ b/test/Analysis/rdar-6540084.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-checker=deadcode.DeadStores -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-checker=deadcode.DeadStores -verify %s
 //
 // This test exercises the live variables analysis (LiveVariables.cpp).
 // The case originally identified a non-termination bug.
diff --git a/test/Analysis/rdar-6541136-region.c b/test/Analysis/rdar-6541136-region.c
index 83b7605..dc75af4 100644
--- a/test/Analysis/rdar-6541136-region.c
+++ b/test/Analysis/rdar-6541136-region.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -analyze -analyzer-checker=core,alpha.security.ArrayBound -analyzer-store=region %s
+// RUN: %clang_analyze_cc1 -verify -analyzer-checker=core,alpha.security.ArrayBound -analyzer-store=region %s
 
 struct tea_cheese { unsigned magic; };
 typedef struct tea_cheese kernel_tea_cheese_t;
diff --git a/test/Analysis/rdar-6562655.m b/test/Analysis/rdar-6562655.m
index 9591f55..8794cac 100644
--- a/test/Analysis/rdar-6562655.m
+++ b/test/Analysis/rdar-6562655.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 //
 // This test case mainly checks that the retain/release checker doesn't crash
diff --git a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
index e9809db..72dbe42 100644
--- a/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
+++ b/test/Analysis/rdar-6600344-nil-receiver-undefined-struct-ret.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 typedef struct Foo { int x; } Bar;
diff --git a/test/Analysis/rdar-7168531.m b/test/Analysis/rdar-7168531.m
index b128d32..b2b1511 100644
--- a/test/Analysis/rdar-7168531.m
+++ b/test/Analysis/rdar-7168531.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -analyzer-store=region %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -triple i386-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -analyzer-store=region %s
 
 // Note that the target triple is important for this test case.  It specifies that we use the
 // fragile Objective-C ABI.
diff --git a/test/Analysis/redefined_system.c b/test/Analysis/redefined_system.c
index 16f03ab..4901b3a 100644
--- a/test/Analysis/redefined_system.c
+++ b/test/Analysis/redefined_system.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx,unix,core,alpha.security.taint -w -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx,unix,core,alpha.security.taint -w -verify %s
 // expected-no-diagnostics
 
 // Make sure we don't crash when someone redefines a system function we reason about.
diff --git a/test/Analysis/refcnt_naming.m b/test/Analysis/refcnt_naming.m
index cff5970..c77909a 100644
--- a/test/Analysis/refcnt_naming.m
+++ b/test/Analysis/refcnt_naming.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-config ipa=none -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.RetainCount,alpha.core -analyzer-config ipa=none -analyzer-store=region -verify %s
 
 typedef const struct __CFString * CFStringRef;
 typedef const struct __CFAllocator * CFAllocatorRef;
diff --git a/test/Analysis/reference.cpp b/test/Analysis/reference.cpp
index 951079d..b323b96 100644
--- a/test/Analysis/reference.cpp
+++ b/test/Analysis/reference.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -Wno-null-dereference -Wno-tautological-undefined-compare %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-store=region -verify -Wno-null-dereference -Wno-tautological-undefined-compare %s
 
 void clang_analyzer_eval(bool);
 
@@ -118,16 +118,30 @@
 }
 
 void testReferenceAddress(int &x) {
+// FIXME: Move non-zero reference assumption out of RangeConstraintManager.cpp:422
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(&x != 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(&ref() != 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(&x != 0); // expected-warning{{TRUE}}
   clang_analyzer_eval(&ref() != 0); // expected-warning{{TRUE}}
+#endif
 
   struct S { int &x; };
 
   extern S getS();
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(&getS().x != 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(&getS().x != 0); // expected-warning{{TRUE}}
+#endif
 
   extern S *getSP();
+#ifdef ANALYZER_CM_Z3
+  clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{UNKNOWN}}
+#else
   clang_analyzer_eval(&getSP()->x != 0); // expected-warning{{TRUE}}
+#endif
 }
 
 
diff --git a/test/Analysis/reference.mm b/test/Analysis/reference.mm
index c5546aa..1d73ccd 100644
--- a/test/Analysis/reference.mm
+++ b/test/Analysis/reference.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -Wno-null-dereference %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -Wno-null-dereference %s
 
 @interface Foo
 - (int &)ref;
diff --git a/test/Analysis/region-1.m b/test/Analysis/region-1.m
index 6940c69..3245bd4 100644
--- a/test/Analysis/region-1.m
+++ b/test/Analysis/region-1.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -analyzer-store=region -verify %s
 // expected-no-diagnostics
 //
 // This test case simply should not crash.  It evaluates the logic of not
diff --git a/test/Analysis/region-store.c b/test/Analysis/region-store.c
index 70bda11..673baaf 100644
--- a/test/Analysis/region-store.c
+++ b/test/Analysis/region-store.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,debug.ExprInspection -verify %s
 
 int printf(const char *restrict,...);
 
diff --git a/test/Analysis/region-store.cpp b/test/Analysis/region-store.cpp
index 5ea5c3f..cb49f48 100644
--- a/test/Analysis/region-store.cpp
+++ b/test/Analysis/region-store.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s
 // expected-no-diagnostics
 
 class Loc {
diff --git a/test/Analysis/reinterpret-cast.cpp b/test/Analysis/reinterpret-cast.cpp
index f3b0a7b..7b8c2f3 100644
--- a/test/Analysis/reinterpret-cast.cpp
+++ b/test/Analysis/reinterpret-cast.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/retain-release-arc.m b/test/Analysis/retain-release-arc.m
index 6f3cbfb..78115ac 100644
--- a/test/Analysis/retain-release-arc.m
+++ b/test/Analysis/retain-release-arc.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fobjc-arc -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fobjc-arc -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify -Wno-objc-root-class %s -analyzer-output=text
 
 typedef __typeof(sizeof(int)) size_t;
 
diff --git a/test/Analysis/retain-release-cache-out.m b/test/Analysis/retain-release-cache-out.m
index 54573a4..5e9ebc4 100644
--- a/test/Analysis/retain-release-cache-out.m
+++ b/test/Analysis/retain-release-cache-out.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze %s -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify
+// RUN: %clang_analyze_cc1 %s -analyzer-checker=core,osx.cocoa.RetainCount -fblocks -verify
 
 // This test is checking behavior when a single checker runs only with the core
 // checkers, testing that the traversal order in the CFG does not affect the
diff --git a/test/Analysis/retain-release-cf-audited.m b/test/Analysis/retain-release-cf-audited.m
index c89172f..414ccd5 100644
--- a/test/Analysis/retain-release-cf-audited.m
+++ b/test/Analysis/retain-release-cf-audited.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.RetainCount -verify %s -x objective-c++
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.RetainCount -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.RetainCount -verify %s -x objective-c++
 
 // The special thing about this file is that CFRetain and CFRelease are marked
 // as cf_audited_transfer.
diff --git a/test/Analysis/retain-release-gc-only.m b/test/Analysis/retain-release-gc-only.m
index 26eb6e1..6305942 100644
--- a/test/Analysis/retain-release-gc-only.m
+++ b/test/Analysis/retain-release-gc-only.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -analyze -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.NSAutoreleasePool -analyzer-store=region -fobjc-gc-only -fblocks -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -triple %itanium_abi_triple -analyzer-checker=core,osx.cocoa.RetainCount,osx.cocoa.NSAutoreleasePool -analyzer-store=region -fobjc-gc-only -fblocks -verify -Wno-objc-root-class %s
 
 //===----------------------------------------------------------------------===//
 // Header stuff.
diff --git a/test/Analysis/retain-release-inline.m b/test/Analysis/retain-release-inline.m
index 8809c8c..0cde2c1 100644
--- a/test/Analysis/retain-release-inline.m
+++ b/test/Analysis/retain-release-inline.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -fblocks -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from Mac OS X headers:
diff --git a/test/Analysis/retain-release-path-notes-gc.m b/test/Analysis/retain-release-path-notes-gc.m
index 5b55582..04f9912 100644
--- a/test/Analysis/retain-release-path-notes-gc.m
+++ b/test/Analysis/retain-release-path-notes-gc.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fobjc-gc-only -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 
 /***
diff --git a/test/Analysis/retain-release-path-notes.m b/test/Analysis/retain-release-path-notes.m
index 23347bc..f44d40f 100644
--- a/test/Analysis/retain-release-path-notes.m
+++ b/test/Analysis/retain-release-path-notes.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -analyzer-output=plist-multi-file -analyzer-config path-diagnostics-alternate=false %s -o %t
 // RUN: FileCheck --input-file=%t %s
 
 /***
diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m
index 3f83fb5..65a31cc 100644
--- a/test/Analysis/retain-release-region-store.m
+++ b/test/Analysis/retain-release-region-store.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -analyze -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-max-loop 6 -verify %s
+// RUN: %clang_analyze_cc1 -triple %itanium_abi_triple -analyzer-checker=core,osx.cocoa.RetainCount -analyzer-store=region -analyzer-max-loop 6 -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index b883a86..39a3baa 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1,6 +1,6 @@
 // RUN: rm -f %t.objc.plist %t.objcpp.plist
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s -analyzer-output=plist -o %t.objc.plist
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ -std=gnu++98 -Wno-objc-root-class %s -analyzer-output=plist -o %t.objcpp.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -Wno-objc-root-class %s -analyzer-output=plist -o %t.objc.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify -x objective-c++ -std=gnu++98 -Wno-objc-root-class %s -analyzer-output=plist -o %t.objcpp.plist
 // FIXLATER: cat %t.objc.plist ; FileCheck --input-file=%t.objc.plist %s
 // FIXLATER: cat %t.objcpp.plist ; FileCheck --input-file=%t.objcpp.plist %s
 
diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm
index 3650d88..c981700 100644
--- a/test/Analysis/retain-release.mm
+++ b/test/Analysis/retain-release.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.ClassRelease,osx.cocoa.RetainCount -analyzer-store=region -fblocks -verify %s
 
 #if __has_feature(attribute_ns_returns_retained)
 #define NS_RETURNS_RETAINED __attribute__((ns_returns_retained))
diff --git a/test/Analysis/return-ptr-range.cpp b/test/Analysis/return-ptr-range.cpp
index 0cc17b0..dd5dcd5 100644
--- a/test/Analysis/return-ptr-range.cpp
+++ b/test/Analysis/return-ptr-range.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.ReturnPtrRange -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.security.ReturnPtrRange -verify %s
 
 int arr[10];
 int *ptr;
diff --git a/test/Analysis/security-syntax-checks-no-emit.c b/test/Analysis/security-syntax-checks-no-emit.c
index 7759aa7..29dd201 100644
--- a/test/Analysis/security-syntax-checks-no-emit.c
+++ b/test/Analysis/security-syntax-checks-no-emit.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple i686-pc-linux-gnu -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i686-pc-linux-gnu -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
 // expected-no-diagnostics
 
 // This file complements 'security-syntax-checks.m', but tests that we omit
diff --git a/test/Analysis/security-syntax-checks.m b/test/Analysis/security-syntax-checks.m
index 9b7fb25..04a4c7d8 100644
--- a/test/Analysis/security-syntax-checks.m
+++ b/test/Analysis/security-syntax-checks.m
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
-// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
 
 #ifdef USE_BUILTINS
 # define BUILTIN(f) __builtin_ ## f
diff --git a/test/Analysis/self-assign.cpp b/test/Analysis/self-assign.cpp
index 74fb0fe..580a3ab 100644
--- a/test/Analysis/self-assign.cpp
+++ b/test/Analysis/self-assign.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -analyze -analyzer-checker=core,cplusplus,unix.Malloc,debug.ExprInspection %s -verify -analyzer-output=text
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus,unix.Malloc,debug.ExprInspection %s -verify -analyzer-output=text
 
 extern "C" char *strdup(const char* s);
 extern "C" void free(void* ptr);
diff --git a/test/Analysis/self-init.m b/test/Analysis/self-init.m
index d1fb88d..cb1a321 100644
--- a/test/Analysis/self-init.m
+++ b/test/Analysis/self-init.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -analyzer-config ipa=dynamic -fno-builtin %s -verify
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.SelfInit -fno-builtin %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.SelfInit -analyzer-config ipa=dynamic -fno-builtin %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.SelfInit -fno-builtin %s -verify
 
 @class NSZone, NSCoder;
 @protocol NSObject
diff --git a/test/Analysis/shallow-mode.m b/test/Analysis/shallow-mode.m
index 23df699..1c71e1b 100644
--- a/test/Analysis/shallow-mode.m
+++ b/test/Analysis/shallow-mode.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-config mode=shallow -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config mode=shallow -verify %s
 // expected-no-diagnostics
 
 void clang_analyzer_checkInlined(unsigned);
diff --git a/test/Analysis/simple-stream-checks.c b/test/Analysis/simple-stream-checks.c
index 2f72574..f47e488 100644
--- a/test/Analysis/simple-stream-checks.c
+++ b/test/Analysis/simple-stream-checks.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.unix.SimpleStream -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.SimpleStream -verify %s
 
 #include "Inputs/system-header-simulator-for-simple-stream.h"
 
diff --git a/test/Analysis/sizeofpointer.c b/test/Analysis/sizeofpointer.c
index a9e045b..14ddbd1 100644
--- a/test/Analysis/sizeofpointer.c
+++ b/test/Analysis/sizeofpointer.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.core.SizeofPtr -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.core.SizeofPtr -verify %s
 
 struct s {
 };
diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c
index d668f8f..4026cee 100644
--- a/test/Analysis/stack-addr-ps.c
+++ b/test/Analysis/stack-addr-ps.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
 
 int* f1() {
   int x = 0;
diff --git a/test/Analysis/stack-addr-ps.cpp b/test/Analysis/stack-addr-ps.cpp
index a4ab2f3..79afd18 100644
--- a/test/Analysis/stack-addr-ps.cpp
+++ b/test/Analysis/stack-addr-ps.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s -Wno-undefined-bool-conversion
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify %s -Wno-undefined-bool-conversion
 
 typedef __INTPTR_TYPE__ intptr_t;
 
diff --git a/test/Analysis/stack-block-returned.cpp b/test/Analysis/stack-block-returned.cpp
index af2cec7..b45cf63 100644
--- a/test/Analysis/stack-block-returned.cpp
+++ b/test/Analysis/stack-block-returned.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
 
 typedef void (^bptr)(void);
 
diff --git a/test/Analysis/stackaddrleak.c b/test/Analysis/stackaddrleak.c
index 717f309..a037d12 100644
--- a/test/Analysis/stackaddrleak.c
+++ b/test/Analysis/stackaddrleak.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -std=c99 -Dbool=_Bool -Wno-bool-conversion %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -x c++ -Wno-bool-conversion %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -std=c99 -Dbool=_Bool -Wno-bool-conversion %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -x c++ -Wno-bool-conversion %s
 
 typedef __INTPTR_TYPE__ intptr_t;
 char const *p;
diff --git a/test/Analysis/static_local.m b/test/Analysis/static_local.m
index dcd49e1..daa7ef5 100644
--- a/test/Analysis/static_local.m
+++ b/test/Analysis/static_local.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -Wno-objc-root-class %s
 // expected-no-diagnostics
 
 // Test reasoning about static locals in ObjCMethods. 
diff --git a/test/Analysis/stats.c b/test/Analysis/stats.c
index 5701dc7..eca83c0 100644
--- a/test/Analysis/stats.c
+++ b/test/Analysis/stats.c
@@ -1,5 +1,5 @@
 // REQUIRES: asserts
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-stats %s 2>&1 | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-stats %s 2>&1 | FileCheck %s
 
 void foo() {
   int x;
diff --git a/test/Analysis/std-c-library-functions.c b/test/Analysis/std-c-library-functions.c
index 6b78a26..042b035 100644
--- a/test/Analysis/std-c-library-functions.c
+++ b/test/Analysis/std-c-library-functions.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -triple i686-unknown-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -triple armv7-a15-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
-// RUN: %clang_cc1 -triple thumbv7-a15-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple i686-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple armv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple thumbv7-a15-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 
diff --git a/test/Analysis/std-c-library-functions.cpp b/test/Analysis/std-c-library-functions.cpp
index e6ac66b..00b341a 100644
--- a/test/Analysis/std-c-library-functions.cpp
+++ b/test/Analysis/std-c-library-functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux -analyze -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=unix.StdCLibraryFunctions,debug.ExprInspection -verify %s
 
 // Test that we don't model functions with broken prototypes.
 // Because they probably work differently as well.
diff --git a/test/Analysis/stream.c b/test/Analysis/stream.c
index 329a782..7adf14b 100644
--- a/test/Analysis/stream.c
+++ b/test/Analysis/stream.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.unix.Stream -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.unix.Stream -analyzer-store region -verify %s
 
 typedef __typeof__(sizeof(int)) size_t;
 typedef struct _IO_FILE FILE;
diff --git a/test/Analysis/string-fail.c b/test/Analysis/string-fail.c
index ac5c6d0..ff95ea9 100644
--- a/test/Analysis/string-fail.c
+++ b/test/Analysis/string-fail.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
 // XFAIL: *
 
 // This file is for tests that may eventually go into string.c, or may be
diff --git a/test/Analysis/string.c b/test/Analysis/string.c
index e541219..8ea2068 100644
--- a/test/Analysis/string.c
+++ b/test/Analysis/string.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_cc1 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
 
 //===----------------------------------------------------------------------===
 // Declarations
diff --git a/test/Analysis/superclass.m b/test/Analysis/superclass.m
index 3102d1f..1729359 100644
--- a/test/Analysis/superclass.m
+++ b/test/Analysis/superclass.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=osx.cocoa.MissingSuperCall -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=osx.cocoa.MissingSuperCall -verify -Wno-objc-root-class %s
 
 // Define used Classes
 @protocol NSObject
diff --git a/test/Analysis/svalbuilder-logic.c b/test/Analysis/svalbuilder-logic.c
index 9cf3f96..1595acb 100644
--- a/test/Analysis/svalbuilder-logic.c
+++ b/test/Analysis/svalbuilder-logic.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix -verify %s
 // expected-no-diagnostics
 
 // Testing core functionality of the SValBuilder.
diff --git a/test/Analysis/switch-case.c b/test/Analysis/switch-case.c
index 08a61a0..0840393 100644
--- a/test/Analysis/switch-case.c
+++ b/test/Analysis/switch-case.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_warnIfReached();
diff --git a/test/Analysis/symbol-reaper.c b/test/Analysis/symbol-reaper.c
index 362a22d..72fcc7e 100644
--- a/test/Analysis/symbol-reaper.c
+++ b/test/Analysis/symbol-reaper.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
 void clang_analyzer_warnOnDeadSymbol(int);
diff --git a/test/Analysis/taint-diagnostic-visitor.c b/test/Analysis/taint-diagnostic-visitor.c
new file mode 100644
index 0000000..50fc0b6
--- /dev/null
+++ b/test/Analysis/taint-diagnostic-visitor.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.security.taint,core -analyzer-output=text -verify %s
+
+// This file is for testing enhanced diagnostics produced by the GenericTaintChecker
+
+int scanf(const char *restrict format, ...);
+int system(const char *command);
+
+void taintDiagnostic()
+{
+  char buf[128];
+  scanf("%s", buf); // expected-note {{Taint originated here}}
+  system(buf); // expected-warning {{Untrusted data is passed to a system call}} // expected-note {{Untrusted data is passed to a system call (CERT/STR02-C. Sanitize data passed to complex subsystems)}}
+}
diff --git a/test/Analysis/taint-generic.c b/test/Analysis/taint-generic.c
index fe27070..8efed66 100644
--- a/test/Analysis/taint-generic.c
+++ b/test/Analysis/taint-generic.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -analyze -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -Wno-format-security -verify %s
+// RUN: %clang_analyze_cc1  -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -Wno-format-security -verify %s
 
 int scanf(const char *restrict format, ...);
 int getchar(void);
@@ -169,6 +169,43 @@
   sock = socket(AF_LOCAL, SOCK_STREAM, 0);
   read(sock, buffer, 100);
   execl(buffer, "filename", 0); // no-warning
+
+  sock = socket(AF_INET, SOCK_STREAM, 0);
+  // References to both buffer and &buffer as an argument should taint the argument
+  read(sock, &buffer, 100);
+  execl(buffer, "filename", 0); // expected-warning {{Untrusted data is passed to a system call}}
+}
+
+void testStruct() {
+  struct {
+    char buf[16];
+    int length;
+  } tainted;
+
+  char buffer[16];
+  int sock;
+
+  sock = socket(AF_INET, SOCK_STREAM, 0);
+  read(sock, &tainted, sizeof(tainted));
+  __builtin_memcpy(buffer, tainted.buf, tainted.length); // expected-warning {{Untrusted data is used to specify the buffer size}}
+}
+
+void testStructArray() {
+  struct {
+    char buf[16];
+    struct {
+      int length;
+    } st[1];
+  } tainted;
+
+  char buffer[16];
+  int sock;
+
+  sock = socket(AF_INET, SOCK_STREAM, 0);
+  read(sock, &tainted.buf[0], sizeof(tainted.buf));
+  read(sock, &tainted.st[0], sizeof(tainted.st));
+  // FIXME: tainted.st[0].length should be marked tainted
+  __builtin_memcpy(buffer, tainted.buf, tainted.st[0].length); // no-warning
 }
 
 int testDivByZero() {
diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c
index 6287198..1b59e7b 100644
--- a/test/Analysis/taint-tester.c
+++ b/test/Analysis/taint-tester.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wno-int-to-pointer-cast -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
+// RUN: %clang_analyze_cc1 -Wno-int-to-pointer-cast -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/taint-tester.cpp b/test/Analysis/taint-tester.cpp
index ca7b729..23a92cc 100644
--- a/test/Analysis/taint-tester.cpp
+++ b/test/Analysis/taint-tester.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
+// RUN: %clang_analyze_cc1  -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
 // expected-no-diagnostics
 
 typedef struct _FILE FILE;
diff --git a/test/Analysis/taint-tester.m b/test/Analysis/taint-tester.m
index b5663ca..531c21b 100644
--- a/test/Analysis/taint-tester.m
+++ b/test/Analysis/taint-tester.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1  -analyze -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
+// RUN: %clang_analyze_cc1  -analyzer-checker=alpha.security.taint,debug.TaintTest %s -verify
 // expected-no-diagnostics
 
 #import <stdarg.h>
diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp
index a9e4556..372443b 100644
--- a/test/Analysis/temp-obj-dtors-cfg-output.cpp
+++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp
@@ -1,7 +1,7 @@
 // RUN: rm -f %t
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true -std=c++98 %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true -std=c++98 %s > %t 2>&1
 // RUN: FileCheck --input-file=%t -check-prefix=CXX98 -check-prefix=CHECK %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true -std=c++11 %s > %t 2>&1
 // RUN: FileCheck --input-file=%t -check-prefix=CXX11 -check-prefix=CHECK %s
 
 class A {
diff --git a/test/Analysis/templates.cpp b/test/Analysis/templates.cpp
index 131794a..c1631e0 100644
--- a/test/Analysis/templates.cpp
+++ b/test/Analysis/templates.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fblocks -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fblocks -analyzer-config c++-template-inlining=false -DNO_INLINE -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -fblocks -analyzer-config c++-template-inlining=false -DNO_INLINE -verify %s
 
 void clang_analyzer_eval(bool);
 
diff --git a/test/Analysis/temporaries-callback-order.cpp b/test/Analysis/temporaries-callback-order.cpp
new file mode 100644
index 0000000..df916cc
--- /dev/null
+++ b/test/Analysis/temporaries-callback-order.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:Bind=true -analyzer-config debug.AnalysisOrder:RegionChanges=true %s 2>&1 | FileCheck %s
+
+struct Super {
+  virtual void m();
+};
+struct Sub : Super {
+  virtual void m() {}
+};
+
+void testTemporaries() {
+  // This triggers RegionChanges twice:
+  // - Once for zero-initialization of the structure.
+  // - Once for creating a temporary region and copying the structure there.
+  // FIXME: This code shouldn't really produce the extra temporary, however
+  // that's how we behave for now.
+  Sub().m();
+}
+
+void seeIfCheckBindWorks() {
+  // This should trigger checkBind. The rest of the code shouldn't.
+  // This also triggers checkRegionChanges after that.
+  // Note that this function is analyzed first, so the messages would be on top.
+  int x = 1;
+}
+
+// seeIfCheckBindWorks():
+// CHECK: Bind
+// CHECK-NEXT: RegionChanges
+
+// testTemporaries():
+// CHECK-NEXT: RegionChanges
+// CHECK-NEXT: RegionChanges
+
+// Make sure there's no further output.
+// CHECK-NOT: Bind
+// CHECK-NOT: RegionChanges
diff --git a/test/Analysis/temporaries.cpp b/test/Analysis/temporaries.cpp
index 49cf070..99851dd 100644
--- a/test/Analysis/temporaries.cpp
+++ b/test/Analysis/temporaries.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++03 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++11 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true %s -std=c++11
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++03 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true %s -std=c++11
 
 extern bool clang_analyzer_eval(bool);
 extern bool clang_analyzer_warnIfReached();
@@ -493,3 +493,40 @@
     clang_analyzer_eval(x == 47); // expected-warning{{TRUE}}
   }
 }
+
+namespace PR32088 {
+  void testReturnFromStmtExprInitializer() {
+    // We shouldn't try to destroy the object pointed to by `obj' upon return.
+    const NonTrivial &obj = ({
+      return; // no-crash
+      NonTrivial(42);
+    });
+  }
+}
+
+namespace CopyToTemporaryCorrectly {
+class Super {
+public:
+  void m() {
+    mImpl();
+  }
+  virtual void mImpl() = 0;
+};
+class Sub : public Super {
+public:
+  Sub(const int &p) : j(p) {}
+  virtual void mImpl() override {
+    // Used to be undefined pointer dereference because we didn't copy
+    // the subclass data (j) to the temporary object properly.
+    (void)(j + 1); // no-warning
+    if (j != 22) {
+      clang_analyzer_warnIfReached(); // no-warning
+    }
+  }
+  const int &j;
+};
+void run() {
+  int i = 22;
+  Sub(i).m();
+}
+}
diff --git a/test/Analysis/test-after-div-zero.c b/test/Analysis/test-after-div-zero.c
index f34c4f7..159c80c 100644
--- a/test/Analysis/test-after-div-zero.c
+++ b/test/Analysis/test-after-div-zero.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -std=c99 -Dbool=_Bool -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
-// RUN: %clang_cc1 -x c++ -analyze -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -std=c99 -Dbool=_Bool -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -x c++ -analyzer-checker=core,alpha.core.TestAfterDivZero -analyzer-output=text -verify %s
 
 int var;
 
diff --git a/test/Analysis/test-include-cpp.cpp b/test/Analysis/test-include-cpp.cpp
index 2ac5e11..6998e3c 100644
--- a/test/Analysis/test-include-cpp.cpp
+++ b/test/Analysis/test-include-cpp.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 #include "test-include-cpp.h"
 
diff --git a/test/Analysis/test-include.c b/test/Analysis/test-include.c
index 6aa80b9..20aa244 100644
--- a/test/Analysis/test-include.c
+++ b/test/Analysis/test-include.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 #include "test-include.h"
 #define DIVYX(X,Y) Y/X
diff --git a/test/Analysis/test-objc-non-nil-return-value-checker.m b/test/Analysis/test-objc-non-nil-return-value-checker.m
index 8b1e6a5..2a90636 100644
--- a/test/Analysis/test-objc-non-nil-return-value-checker.m
+++ b/test/Analysis/test-objc-non-nil-return-value-checker.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=osx.cocoa.NonNilReturnValue,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=osx.cocoa.NonNilReturnValue,debug.ExprInspection -verify %s
 
 typedef unsigned int NSUInteger;
 typedef signed char BOOL;
diff --git a/test/Analysis/test-variably-modified-types.c b/test/Analysis/test-variably-modified-types.c
index a833434..1df57af 100644
--- a/test/Analysis/test-variably-modified-types.c
+++ b/test/Analysis/test-variably-modified-types.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyze-function=testVariablyModifiedTypes -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyze-function=testVariablyModifiedTypes -verify %s
 
 // Test that we process variably modified type correctly - the call graph construction should pick up function_with_bug while recursively visiting test_variably_modifiable_types.
 unsigned getArraySize(int *x) {
diff --git a/test/Analysis/traversal-algorithm.mm b/test/Analysis/traversal-algorithm.mm
index 8a3dc8b..bdf5760 100644
--- a/test/Analysis/traversal-algorithm.mm
+++ b/test/Analysis/traversal-algorithm.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpTraversal -analyzer-max-loop 4 -std=c++11 %s | FileCheck -check-prefix=DFS %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpTraversal -analyzer-max-loop 4 -std=c++11 %s | FileCheck -check-prefix=DFS %s
 
 int a();
 int b();
diff --git a/test/Analysis/traversal-begin-end-function.c b/test/Analysis/traversal-begin-end-function.c
index 810ce1d..9d46f26 100644
--- a/test/Analysis/traversal-begin-end-function.c
+++ b/test/Analysis/traversal-begin-end-function.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.DumpTraversal %s | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.DumpTraversal %s | FileCheck %s
 
 void inline_callee(int i);
 
diff --git a/test/Analysis/traversal-path-unification.c b/test/Analysis/traversal-path-unification.c
index 3bf6df7..28a1511 100644
--- a/test/Analysis/traversal-path-unification.c
+++ b/test/Analysis/traversal-path-unification.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.DumpTraversal %s | FileCheck %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.DumpTraversal -DUSE_EXPR %s | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.DumpTraversal %s | FileCheck %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.DumpTraversal -DUSE_EXPR %s | FileCheck %s
 
 int a();
 int b();
diff --git a/test/Analysis/ubigraph-viz.cpp b/test/Analysis/ubigraph-viz.cpp
index 0cb9bd6..228dd66 100644
--- a/test/Analysis/ubigraph-viz.cpp
+++ b/test/Analysis/ubigraph-viz.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -analyzer-viz-egraph-ubigraph -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API -analyzer-viz-egraph-ubigraph -verify %s
 // expected-no-diagnostics
 
 int f(int x) {
diff --git a/test/Analysis/undef-buffers.c b/test/Analysis/undef-buffers.c
index 1581b2b..d5802fb 100644
--- a/test/Analysis/undef-buffers.c
+++ b/test/Analysis/undef-buffers.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix,core.uninitialized -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,core.uninitialized -analyzer-store=region -verify -analyzer-config unix:Optimistic=true %s
 typedef __typeof(sizeof(int)) size_t;
 void *malloc(size_t);
 void free(void *);
diff --git a/test/Analysis/uninit-const.c b/test/Analysis/uninit-const.c
index 9e42d23..9a6529a 100644
--- a/test/Analysis/uninit-const.c
+++ b/test/Analysis/uninit-const.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc,core,alpha.core.CallAndMessageUnInitRefArg -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=unix.Malloc,core,alpha.core.CallAndMessageUnInitRefArg -analyzer-output=text -verify %s
 
 // Passing uninitialized const data to function
 #include "Inputs/system-header-simulator.h"
@@ -24,16 +24,16 @@
 void f_1(void) {
   int t;
   int* tp = &t;        // expected-note {{'tp' initialized here}}
-  doStuff_pointerToConstInt(tp);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(tp);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_1_1(void) {
   int t;
   int* tp1 = &t;
   int* tp2 = tp1;        // expected-note {{'tp2' initialized here}}
-  doStuff_pointerToConstInt(tp2);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(tp2);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 
@@ -45,8 +45,8 @@
   int t;
   int* p = f_2_sub(&t);
   int* tp = p; // expected-note {{'tp' initialized here}}
-  doStuff_pointerToConstInt(tp); // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                      // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                      // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 int z;
@@ -62,14 +62,14 @@
 void f_5(void) {
   int ta[5];
   int* tp = ta;        // expected-note {{'tp' initialized here}}
-  doStuff_pointerToConstInt(tp);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(tp);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_5_1(void) {
   int ta[5];        // expected-note {{'ta' initialized here}}
-  doStuff_pointerToConstInt(ta);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(ta);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_6(void) {
@@ -92,27 +92,27 @@
 
 void f_8(void) {
       int g;       // expected-note {{'g' declared without an initial value}}
-      doStuff2(g); // expected-warning {{Function call argument is an uninitialized value}}
-                   // expected-note@-1 {{Function call argument is an uninitialized value}}
+      doStuff2(g); // expected-warning {{1st function call argument is an uninitialized value}}
+                   // expected-note@-1 {{1st function call argument is an uninitialized value}}
 }
 
 void f_9(void) {
   int  a[6];
   int const *ptau = a;             // expected-note {{'ptau' initialized here}}
-  doStuff_arrayOfConstInt(ptau);    // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                                   // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_arrayOfConstInt(ptau);    // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                                   // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_10(void) {
   int  a[6];                     // expected-note {{'a' initialized here}}
-  doStuff_arrayOfConstInt(a);    // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                                 // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_arrayOfConstInt(a);    // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                                 // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_11(void) {
   int t[10];                    //expected-note {{'t' initialized here}}
-  doStuff_constStaticSizedArray(t);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                                // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_constStaticSizedArray(t);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                                // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 void f_12(void) {
@@ -126,8 +126,8 @@
 
   ptr = (int *)malloc(sizeof(int)); // expected-note {{Value assigned to 'ptr'}}
 
-  doStuff_pointerToConstInt(ptr); // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_pointerToConstInt(ptr); // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
   free(ptr);
   return 0;
 }
@@ -148,16 +148,16 @@
   int t;
   int v;
   int* tp = &t;           // expected-note {{'tp' initialized here}}
-  doStuff_variadic(tp,v);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                          // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_variadic(tp,v);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                          // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 // uninit pointer, init val
 void f_variadic_unp_inv(void) {
   int t;
   int v = 3;
   int* tp = &t;           // expected-note {{'tp' initialized here}}
-  doStuff_variadic(tp,v);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                          // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_variadic(tp,v);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                          // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 // init pointer, uninit val
@@ -165,8 +165,8 @@
   int t=5;
   int v;                  // expected-note {{'v' declared without an initial value}}
   int* tp = &t;
-  doStuff_variadic(tp,v);// expected-warning {{Function call argument is an uninitialized value}}
-                          // expected-note@-1 {{Function call argument is an uninitialized value}}
+  doStuff_variadic(tp,v);// expected-warning {{2nd function call argument is an uninitialized value}}
+                          // expected-note@-1 {{2nd function call argument is an uninitialized value}}
 }
 
 // init pointer, init val
@@ -192,8 +192,8 @@
   int u=3;
   int *vp = &u ;
   int *tp = &t;             // expected-note {{'tp' initialized here}}
-  doStuff_variadic(tp,vp); // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                            // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_variadic(tp,vp); // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                            // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 //init pointer, uninit pointer
@@ -211,6 +211,6 @@
   int u;
   int *vp = &u ;
   int *tp = &t;             // expected-note {{'tp' initialized here}}
-  doStuff_variadic(tp,vp); // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                            // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_variadic(tp,vp); // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                            // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
diff --git a/test/Analysis/uninit-const.cpp b/test/Analysis/uninit-const.cpp
index 56bfa08..db969bf 100644
--- a/test/Analysis/uninit-const.cpp
+++ b/test/Analysis/uninit-const.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.NewDelete,core,alpha.core.CallAndMessageUnInitRefArg -analyzer-output=text -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.NewDelete,core,alpha.core.CallAndMessageUnInitRefArg -analyzer-output=text -verify %s
 // Passing uninitialized const data to unknown function
 
 #include "Inputs/system-header-simulator-cxx.h"
@@ -66,8 +66,8 @@
   int &p = t;
   int &s = p;
   int &q = s;  //expected-note {{'q' initialized here}}
-  doStuff6(q); //expected-warning {{Function call argument is an uninitialized value}}
-               //expected-note@-1 {{Function call argument is an uninitialized value}}
+  doStuff6(q); //expected-warning {{1st function call argument is an uninitialized value}}
+               //expected-note@-1 {{1st function call argument is an uninitialized value}}
 }
 
 void doStuff6_3(int& q_, int *ptr_) {}
@@ -78,15 +78,15 @@
   int &p = t;
   int &s = p;
   int &q = s;
-  doStuff6_3(q,ptr); //expected-warning {{Function call argument is an uninitialized value}}
-               //expected-note@-1 {{Function call argument is an uninitialized value}}
+  doStuff6_3(q,ptr); //expected-warning {{2nd function call argument is an uninitialized value}}
+               //expected-note@-1 {{2nd function call argument is an uninitialized value}}
 
 }
 
 void f6(void) {
   int k;       // expected-note {{'k' declared without an initial value}}
-  doStuff6(k); // expected-warning {{Function call argument is an uninitialized value}}
-               // expected-note@-1 {{Function call argument is an uninitialized value}}
+  doStuff6(k); // expected-warning {{1st function call argument is an uninitialized value}}
+               // expected-note@-1 {{1st function call argument is an uninitialized value}}
 
 }
 
@@ -95,15 +95,15 @@
 void f5(void) {
   int t;
   int* tp = &t;        // expected-note {{'tp' initialized here}}
-  doStuff_uninit(tp);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                       // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+  doStuff_uninit(tp);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                       // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
 
 
 void f4(void) {
       int y;        // expected-note {{'y' declared without an initial value}}
-      doStuff4(y);  // expected-warning {{Function call argument is an uninitialized value}}
-                    // expected-note@-1 {{Function call argument is an uninitialized value}}
+      doStuff4(y);  // expected-warning {{1st function call argument is an uninitialized value}}
+                    // expected-note@-1 {{1st function call argument is an uninitialized value}}
 }
 
 void f3(void) {
@@ -122,7 +122,7 @@
 }
 
 void f_uninit(void) {
-      int x;
-      doStuff_uninit(&x);  // expected-warning {{Function call argument is a pointer to uninitialized value}}
-                           // expected-note@-1 {{Function call argument is a pointer to uninitialized value}}
+      int x;               // expected-note {{'x' declared without an initial value}}
+      doStuff_uninit(&x);  // expected-warning {{1st function call argument is a pointer to uninitialized value}}
+                           // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}}
 }
diff --git a/test/Analysis/uninit-msg-expr.m b/test/Analysis/uninit-msg-expr.m
index 19fdf61..8454137 100644
--- a/test/Analysis/uninit-msg-expr.m
+++ b/test/Analysis/uninit-msg-expr.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
@@ -52,5 +52,5 @@
 void f3() {
   NSMutableArray *aArray = [NSArray array];
   NSString *aString;
-  [aArray addObject:aString]; // expected-warning {{Argument in message expression is an uninitialized value}}
+  [aArray addObject:aString]; // expected-warning {{1st argument in message expression is an uninitialized value}}
 }
diff --git a/test/Analysis/uninit-ps-rdar6145427.m b/test/Analysis/uninit-ps-rdar6145427.m
index c18116f..d735f17 100644
--- a/test/Analysis/uninit-ps-rdar6145427.m
+++ b/test/Analysis/uninit-ps-rdar6145427.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -analyzer-store=region %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify -analyzer-store=region %s
 
 // Delta-Debugging reduced preamble.
 typedef signed char BOOL;
diff --git a/test/Analysis/uninit-vals-ps-region.m b/test/Analysis/uninit-vals-ps-region.m
index 87256b3..18010f2 100644
--- a/test/Analysis/uninit-vals-ps-region.m
+++ b/test/Analysis/uninit-vals-ps-region.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-store=region -analyzer-checker=core -verify %s
 
 struct s {
   int data;
diff --git a/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c
index ad40b15..ee25d9d 100644
--- a/test/Analysis/uninit-vals-ps.c
+++ b/test/Analysis/uninit-vals-ps.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region -fblocks -verify %s
 
 struct FPRec {
   void (*my_func)(int * x);  
@@ -14,7 +14,7 @@
 
 int f1_b() {
   int x;
-  return bar(x)+1;  // expected-warning{{Function call argument is an uninitialized value}}
+  return bar(x)+1;  // expected-warning{{1st function call argument is an uninitialized value}}
 }
 
 int f2() {
@@ -57,6 +57,12 @@
   return s.x; // no-warning
 }
 
+void f6(int x) {
+  int a[20];
+  if (x == 25) {}
+  if (a[x] == 123) {} // expected-warning{{The left operand of '==' is a garbage value due to array index out of bounds}}
+}
+
 int ret_uninit() {
   int i;
   int *p = &i;
diff --git a/test/Analysis/uninit-vals-union.c b/test/Analysis/uninit-vals-union.c
index 927dfa2..b433e7b 100644
--- a/test/Analysis/uninit-vals-union.c
+++ b/test/Analysis/uninit-vals-union.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core.builtin -analyzer-store=region -verify -Wno-unused %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.builtin -analyzer-store=region -verify -Wno-unused %s
 
 typedef union {
   int y;
diff --git a/test/Analysis/uninit-vals.cpp b/test/Analysis/uninit-vals.cpp
index 387c375..5ab1348 100644
--- a/test/Analysis/uninit-vals.cpp
+++ b/test/Analysis/uninit-vals.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core.builtin -verify -DCHECK_FOR_CRASH %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core.builtin -verify -DCHECK_FOR_CRASH %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 #ifdef CHECK_FOR_CRASH
 // expected-no-diagnostics
@@ -27,7 +27,7 @@
   // case with undefined values, too.
   c1.b.a = c2->b.a;
 #else
-  c1.b.a = c2->b.a; // expected-warning{{Function call argument is an uninitialized value}}
+  c1.b.a = c2->b.a; // expected-warning{{1st function call argument is an uninitialized value}}
 #endif
 }
 }
diff --git a/test/Analysis/uninit-vals.m b/test/Analysis/uninit-vals.m
index 72b6739..7c18dee 100644
--- a/test/Analysis/uninit-vals.m
+++ b/test/Analysis/uninit-vals.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify %s
 
 typedef unsigned int NSUInteger;
 typedef __typeof__(sizeof(int)) size_t;
diff --git a/test/Analysis/unions-region.m b/test/Analysis/unions-region.m
index 636198a..bad159f 100644
--- a/test/Analysis/unions-region.m
+++ b/test/Analysis/unions-region.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-store=region %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-store=region %s -verify
 // expected-no-diagnostics
 
 //===-- unions-region.m ---------------------------------------------------===//
diff --git a/test/Analysis/unions.cpp b/test/Analysis/unions.cpp
index f363ab8..2758cda 100644
--- a/test/Analysis/unions.cpp
+++ b/test/Analysis/unions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -verify
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection %s -verify
 
 extern void clang_analyzer_eval(bool);
 extern "C" char *strdup(const char *s);
diff --git a/test/Analysis/unix-api.c b/test/Analysis/unix-api.c
index 24b145d..64ff3c0 100644
--- a/test/Analysis/unix-api.c
+++ b/test/Analysis/unix-api.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API -verify %s
 
 #ifndef O_RDONLY
 #define O_RDONLY 0
diff --git a/test/Analysis/unix-api.cpp b/test/Analysis/unix-api.cpp
index 1c8f996..2b07d88 100644
--- a/test/Analysis/unix-api.cpp
+++ b/test/Analysis/unix-api.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API -verify %s
 extern "C" {
 #ifndef O_RDONLY
 #define O_RDONLY 0
diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c
index b144578..3eccd51 100644
--- a/test/Analysis/unix-fns.c
+++ b/test/Analysis/unix-fns.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,unix.API,osx.API %s -analyzer-store=region -analyzer-output=plist -analyzer-eagerly-assume -analyzer-config faux-bodies=true -analyzer-config path-diagnostics-alternate=false -fblocks -verify -o %t.plist
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,unix.API,osx.API %s -analyzer-store=region -analyzer-output=plist -analyzer-eagerly-assume -analyzer-config faux-bodies=true -analyzer-config path-diagnostics-alternate=false -fblocks -verify -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
 // RUN: mkdir -p %t.dir
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API,osx.API -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %t.dir %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.API,osx.API -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %t.dir %s
 // RUN: rm -fR %t.dir
 struct _opaque_pthread_once_t {
   long __sig;
diff --git a/test/Analysis/unreachable-code-path.c b/test/Analysis/unreachable-code-path.c
index 4ddfb21..ff58587 100644
--- a/test/Analysis/unreachable-code-path.c
+++ b/test/Analysis/unreachable-code-path.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,deadcode.DeadStores,alpha.deadcode.UnreachableCode -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,deadcode.DeadStores,alpha.deadcode.UnreachableCode -verify -analyzer-opt-analyze-nested-blocks -Wno-unused-value %s
 
 extern void foo(int a);
 
diff --git a/test/Analysis/unsupported-types.c b/test/Analysis/unsupported-types.c
new file mode 100644
index 0000000..9233095
--- /dev/null
+++ b/test/Analysis/unsupported-types.c
@@ -0,0 +1,31 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -triple x86_64-unknown-linux -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -triple powerpc64-linux-gnu -verify %s
+
+#define _Complex_I      (__extension__ 1.0iF)
+
+void clang_analyzer_eval(int);
+
+void complex_float(double _Complex x, double _Complex y) {
+  clang_analyzer_eval(x == y); // expected-warning{{UNKNOWN}}
+  if (x != 1.0 + 3.0 * _Complex_I && y != 1.0 - 4.0 * _Complex_I)
+    return
+  clang_analyzer_eval(x == y); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(x + y == 2.0 - 1.0 * _Complex_I); // expected-warning{{UNKNOWN}}
+}
+
+void complex_int(int _Complex x, int _Complex y) {
+  clang_analyzer_eval(x == y); // expected-warning{{UNKNOWN}}
+  if (x != 1.0 + 3.0 * _Complex_I && y != 1.0 - 4.0 * _Complex_I)
+    return
+  clang_analyzer_eval(x == y); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(x + y == 2.0 - 1.0 * _Complex_I); // expected-warning{{UNKNOWN}}
+}
+
+void longdouble_float(long double x, long double y) {
+  clang_analyzer_eval(x == y); // expected-warning{{UNKNOWN}}
+  if (x != 0.0L && y != 1.0L)
+    return
+  clang_analyzer_eval(x == y); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(x + y == 1.0L); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/unused-ivars.m b/test/Analysis/unused-ivars.m
index f04132b..8f12d9b 100644
--- a/test/Analysis/unused-ivars.m
+++ b/test/Analysis/unused-ivars.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fblocks -analyze -analyzer-checker=osx.cocoa.UnusedIvars -verify -Wno-objc-root-class %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=osx.cocoa.UnusedIvars -verify -Wno-objc-root-class %s
 
 //===--- BEGIN: Delta-debugging reduced headers. --------------------------===//
 
diff --git a/test/Analysis/valist-as-lazycompound.c b/test/Analysis/valist-as-lazycompound.c
new file mode 100644
index 0000000..1b3901c
--- /dev/null
+++ b/test/Analysis/valist-as-lazycompound.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple gcc-linaro-arm-linux-gnueabihf -analyze -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// expected-no-diagnostics
+
+typedef unsigned int size_t;
+typedef __builtin_va_list __gnuc_va_list;
+typedef __gnuc_va_list va_list;
+
+extern int vsprintf(char *__restrict __s,
+                    const char *__restrict __format, __gnuc_va_list
+                                                         __arg);
+
+void _dprintf(const char *function, int flen, int line, int level,
+             const char *prefix, const char *fmt, ...) {
+  char raw[10];
+  int err;
+  va_list ap;
+
+  __builtin_va_start(ap, fmt);
+  err = vsprintf(raw, fmt, ap);
+  __builtin_va_end(ap);
+}
diff --git a/test/Analysis/valist-uninitialized-no-undef.c b/test/Analysis/valist-uninitialized-no-undef.c
new file mode 100644
index 0000000..edcdc99
--- /dev/null
+++ b/test/Analysis/valist-uninitialized-no-undef.c
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+
+#include "Inputs/system-header-simulator-for-valist.h"
+
+// This is called in call_inlined_uses_arg(),
+// and the warning is generated during the analysis of call_inlined_uses_arg().
+void inlined_uses_arg(va_list arg) {
+  (void)va_arg(arg, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
+}
+
+void call_inlined_uses_arg(int fst, ...) {
+  va_list va;
+  inlined_uses_arg(va); // expected-note{{Calling 'inlined_uses_arg'}}
+}
+
+void f6(va_list *fst, ...) {
+  va_start(*fst, fst);
+  // FIXME: There should be no warning for this.
+  (void)va_arg(*fst, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
+  va_end(*fst);
+} 
+
+void call_vprintf_bad(int isstring, ...) {
+  va_list va;
+  vprintf(isstring ? "%s" : "%d", va); // expected-warning{{Function 'vprintf' is called with an uninitialized va_list argument}}
+  // expected-note@-1{{Function 'vprintf' is called with an uninitialized va_list argument}}
+  // expected-note@-2{{Assuming 'isstring' is 0}}
+  // expected-note@-3{{'?' condition is false}}
+}
+
+void call_vsprintf_bad(char *buffer, ...) {
+  va_list va;
+  va_start(va, buffer); // expected-note{{Initialized va_list}}
+  va_end(va); // expected-note{{Ended va_list}}
+  vsprintf(buffer, "%s %d %d %lf %03d", va); // expected-warning{{Function 'vsprintf' is called with an uninitialized va_list argument}}
+  // expected-note@-1{{Function 'vsprintf' is called with an uninitialized va_list argument}}
+}
+
diff --git a/test/Analysis/valist-uninitialized.c b/test/Analysis/valist-uninitialized.c
index b1f11d1..1930853 100644
--- a/test/Analysis/valist-uninitialized.c
+++ b/test/Analysis/valist-uninitialized.c
@@ -1,17 +1,20 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,alpha.valist.Uninitialized,alpha.valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-disable-checker=core.CallAndMessage -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Uninitialized,valist.CopyToSelf -analyzer-disable-checker=core.CallAndMessage -analyzer-output=text -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator-for-valist.h"
 
 void f1(int fst, ...) {
   va_list va;
-  (void)va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
+  (void)va_arg(va, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
 }
 
 int f2(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
   va_end(va); // expected-note{{Ended va_list}}
-  return va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
+  return va_arg(va, int); // expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
 }
 
 void f3(int fst, ...) {
@@ -25,11 +28,13 @@
 
 void f4(int cond, ...) {
   va_list va;
-  if (cond) { // expected-note{{Assuming 'cond' is 0}} expected-note{{Taking false branch}}
+  if (cond) { // expected-note{{Assuming 'cond' is 0}}
+    // expected-note@-1{{Taking false branch}}
     va_start(va, cond);
     (void)va_arg(va,int);
   }
-  va_end(va); //expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
+  va_end(va); //expected-warning{{va_end() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_end() is called on an uninitialized va_list}}
 }
 
 void f5(va_list fst, ...) {
@@ -38,13 +43,6 @@
   va_end(fst);
 } // no-warning
 
-//FIXME: this should not cause a warning
-void f6(va_list *fst, ...) {
-  va_start(*fst, fst);
-  (void)va_arg(*fst, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-  va_end(*fst);
-}
-
 void f7(int *fst, ...) {
   va_list x;
   va_list *y = &x;
@@ -58,8 +56,9 @@
   va_list *y = &x;
   va_start(*y,fst); // expected-note{{Initialized va_list}}
   va_end(x); // expected-note{{Ended va_list}}
-  (void)va_arg(*y, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-} // no-warning
+  (void)va_arg(*y, int); //expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
+}
 
 // This only contains problems which are handled by varargs.Unterminated.
 void reinit(int *fst, ...) {
@@ -87,48 +86,56 @@
   va_start(va, fst); // expected-note{{Initialized va_list}}
   (void)va_arg(va, int);
   va_end(va); // expected-note{{Ended va_list}}
-  (void)va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
+  (void)va_arg(va, int); //expected-warning{{va_arg() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_arg() is called on an uninitialized va_list}}
 }
 
 void copyself(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}}
+  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
+  // expected-note@-1{{va_list 'va' is copied onto itself}}
   va_end(va);
-} // no-warning
+}
 
 void copyselfUninit(int fst, ...) {
   va_list va;
-  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}}
-} // no-warning
+  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
+  // expected-note@-1{{va_list 'va' is copied onto itself}}
+}
 
 void copyOverwrite(int fst, ...) {
   va_list va, va2;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}} expected-note{{Initialized va_list 'va' is overwritten by an uninitialized one}}
-} // no-warning
+  va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}}
+  // expected-note@-1{{Initialized va_list 'va' is overwritten by an uninitialized one}}
+}
 
 void copyUnint(int fst, ...) {
   va_list va, va2;
-  va_copy(va, va2); // expected-warning{{Uninitialized va_list is copied}} expected-note{{Uninitialized va_list is copied}}
+  va_copy(va, va2); // expected-warning{{Uninitialized va_list is copied}}
+  // expected-note@-1{{Uninitialized va_list is copied}}
 }
 
 void g1(int fst, ...) {
   va_list va;
-  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
+  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_end() is called on an uninitialized va_list}}
 }
 
 void g2(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
   va_end(va); // expected-note{{Ended va_list}}
-  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
+  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_end() is called on an uninitialized va_list}}
 }
 
 void is_sink(int fst, ...) {
   va_list va;
-  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}} expected-note{{va_end() is called on an uninitialized va_list}}
-  *((volatile int *)0) = 1; //no-warning
+  va_end(va); // expected-warning{{va_end() is called on an uninitialized va_list}}
+  // expected-note@-1{{va_end() is called on an uninitialized va_list}}
+  *((volatile int *)0) = 1;
 }
 
 // NOTE: this is invalid, as the man page of va_end requires that "Each invocation of va_start()
@@ -141,17 +148,6 @@
   (void)va_arg(arg, int);
 } //no-warning
 
-// This is the same function as the previous one, but it is called in call_uses_arg2(),
-// and the warning is generated during the analysis of call_uses_arg2().
-void inlined_uses_arg(va_list arg) {
-  (void)va_arg(arg, int); //expected-warning{{va_arg() is called on an uninitialized va_list}} expected-note{{va_arg() is called on an uninitialized va_list}}
-}
-
-void call_inlined_uses_arg(int fst, ...) {
-  va_list va;
-  inlined_uses_arg(va); // expected-note{{Calling 'inlined_uses_arg'}}
-}
-
 void call_vprintf_ok(int isstring, ...) {
   va_list va;
   va_start(va, isstring);
@@ -159,20 +155,24 @@
   va_end(va);
 } //no-warning
 
-void call_vprintf_bad(int isstring, ...) {
-  va_list va;
-  vprintf(isstring ? "%s" : "%d", va); //expected-warning{{Function 'vprintf' is called with an uninitialized va_list argument}} expected-note{{Function 'vprintf' is called with an uninitialized va_list argument}} expected-note{{Assuming 'isstring' is 0}} expected-note{{'?' condition is false}}
-}
-
-void call_vsprintf_bad(char *buffer, ...) {
-  va_list va;
-  va_start(va, buffer); // expected-note{{Initialized va_list}}
-  va_end(va); // expected-note{{Ended va_list}}
-  vsprintf(buffer, "%s %d %d %lf %03d", va); //expected-warning{{Function 'vsprintf' is called with an uninitialized va_list argument}} expected-note{{Function 'vsprintf' is called with an uninitialized va_list argument}}
-}
-
 void call_some_other_func(int n, ...) {
   va_list va;
   some_library_function(n, va);
 } //no-warning
 
+void inlined_uses_arg_good(va_list arg) {
+  (void)va_arg(arg, int);
+}
+
+void call_inlined_uses_arg_good(int fst, ...) {
+  va_list va;
+  va_start(va, fst);
+  inlined_uses_arg_good(va);
+  va_end(va);
+}
+
+void va_copy_test(va_list arg) {
+  va_list dst;
+  va_copy(dst, arg);
+  va_end(dst);
+}
diff --git a/test/Analysis/valist-unterminated.c b/test/Analysis/valist-unterminated.c
index 63ee992..e19c676 100644
--- a/test/Analysis/valist-unterminated.c
+++ b/test/Analysis/valist-unterminated.c
@@ -1,11 +1,13 @@
-// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -analyze -analyzer-checker=core,alpha.valist.Unterminated,alpha.valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple hexagon-unknown-linux -analyzer-checker=core,valist.Unterminated,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,valist.Unterminated,valist.CopyToSelf -analyzer-output=text -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator-for-valist.h"
 
 void f1(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  return; // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}
+  return; // expected-warning{{Initialized va_list 'va' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va' is leaked}}
 }
 
 void f2(int fst, ...) {
@@ -13,37 +15,42 @@
   va_start(va, fst); // expected-note{{Initialized va_list}}
   va_end(va); // expected-note{{Ended va_list}}
   va_start(va, fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}}
+} // expected-warning{{Initialized va_list 'va' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va' is leaked}}
 
 void f3(int fst, ...) {
   va_list va, va2;
   va_start(va, fst);
   va_copy(va2, va); // expected-note{{Initialized va_list}}
-  va_end(va); // expected-warning{{Initialized va_list 'va2' is leaked}} expected-note{{Initialized va_list 'va2' is leaked}}
+  va_end(va); // expected-warning{{Initialized va_list 'va2' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va2' is leaked}}
 }
 
 void f4(va_list *fst, ...) {
   va_start(*fst, fst); // expected-note{{Initialized va_list}}
-  return; // expected-warning{{Initialized va_list is leaked}} expected-note{{Initialized va_list is leaked}}
+  return; // expected-warning{{Initialized va_list is leaked}}
+  // expected-note@-1{{Initialized va_list is leaked}}
 }
 
 void f5(va_list fst, ...) {
-  va_start(fst, fst);
-  //FIXME: this should cause a warning
-} // no-warning
+  va_start(fst, fst); // expected-note{{Initialized va_list}}
+} // expected-warning{{Initialized va_list}}
+  // expected-note@-1{{Initialized va_list}}
 
 void f6(va_list *fst, ...) {
   va_start(*fst, fst); // expected-note{{Initialized va_list}}
   (void)va_arg(*fst, int);
   //FIXME: this should NOT cause a warning
-  va_end(*fst); // expected-warning{{Initialized va_list is leaked}} expected-note{{Initialized va_list is leaked}}
+  va_end(*fst); // expected-warning{{Initialized va_list is leaked}}
+  // expected-note@-1{{Initialized va_list is leaked}}
 }
 
 void f7(int *fst, ...) {
   va_list x;
   va_list *y = &x;
   va_start(*y,fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'x' is leaked}} expected-note{{Initialized va_list 'x' is leaked}}
+} // expected-warning{{Initialized va_list 'x' is leaked}}
+  // expected-note@-1{{Initialized va_list 'x' is leaked}}
 
 void f8(int *fst, ...) {
   va_list x;
@@ -54,9 +61,12 @@
 
 void reinit(int *fst, ...) {
   va_list va;
-  va_start(va, fst); // expected-note{{Initialized va_list}} expected-note{{Initialized va_list}}
-  va_start(va, fst); // expected-warning{{Initialized va_list 'va' is initialized again}} expected-note{{Initialized va_list 'va' is initialized again}}
-} // expected-warning{{Initialized va_list 'va' is leaked}} expected-note{{Initialized va_list 'va' is leaked}}
+  va_start(va, fst); // expected-note{{Initialized va_list}}
+                     // expected-note@-1{{Initialized va_list}}
+  va_start(va, fst); // expected-warning{{Initialized va_list 'va' is initialized again}}
+  // expected-note@-1{{Initialized va_list 'va' is initialized again}}
+} // expected-warning{{Initialized va_list 'va' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va' is leaked}}
 
 void reinitOk(int *fst, ...) {
   va_list va;
@@ -69,20 +79,23 @@
 void copyself(int fst, ...) {
   va_list va;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}}
+  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
+                   // expected-note@-1{{va_list 'va' is copied onto itself}}
   va_end(va);
-} // no-warning
+}
 
 void copyselfUninit(int fst, ...) {
   va_list va;
-  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}} expected-note{{va_list 'va' is copied onto itself}} 
-} // no-warning
+  va_copy(va, va); // expected-warning{{va_list 'va' is copied onto itself}}
+  // expected-note@-1{{va_list 'va' is copied onto itself}}
+}
 
 void copyOverwrite(int fst, ...) {
   va_list va, va2;
   va_start(va, fst); // expected-note{{Initialized va_list}}
-  va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}} expected-note{{Initialized va_list 'va' is overwritten by an uninitialized one}}
-} // no-warning
+  va_copy(va, va2); // expected-warning{{Initialized va_list 'va' is overwritten by an uninitialized one}}
+  // expected-note@-1{{Initialized va_list 'va' is overwritten by an uninitialized one}}
+}
 
 //This only generates a warning for the valist.Uninitialized checker
 void copyUnint(int fst, ...) {
@@ -94,20 +107,27 @@
   va_list va, va2;
   va_start(va, fst);
   va_copy(va2, va); // expected-note{{Initialized va_list}}
-  va_copy(va2, va); // expected-warning{{Initialized va_list 'va2' is initialized again}} expected-note{{Initialized va_list 'va2' is initialized again}}
+  va_copy(va2, va); // expected-warning{{Initialized va_list 'va2' is initialized again}}
+  // expected-note@-1{{Initialized va_list 'va2' is initialized again}}
   va_end(va);
   va_end(va2);
-} //no-warning
+}
 
 void doublemsg(int fst, ...) {
   va_list va, va2;
-  va_start(va, fst), va_start(va2, fst); // expected-warning{{Initialized va_list 'va' is leaked}} expected-warning{{Initialized va_list 'va2' is leaked}} expected-note{{Initialized va_list}} expected-note{{Initialized va_list}} expected-note{{Initialized va_list}} expected-note{{Initialized va_list 'va' is leaked}} 
+  va_start(va, fst), va_start(va2, fst); // expected-warning{{Initialized va_list 'va' is leaked}}
+  // expected-warning@-1{{Initialized va_list 'va2' is leaked}}
+  // expected-note@-2{{Initialized va_list}}
+  // expected-note@-3{{Initialized va_list}}
+  // expected-note@-4{{Initialized va_list}}
+  // expected-note@-5{{Initialized va_list 'va' is leaked}} 
 } 
 
 void in_array(int fst, ...) {
   va_list va_array[8];
   va_start(va_array[3], fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'va_array[3]' is leaked}} expected-note{{Initialized va_list 'va_array[3]' is leaked}}
+} // expected-warning{{Initialized va_list 'va_array[3]' is leaked}}
+  // expected-note@-1{{Initialized va_list 'va_array[3]' is leaked}}
 
 struct containing_a_valist {
   va_list vafield;
@@ -117,12 +137,14 @@
 void in_struct(int fst, ...) {
   struct containing_a_valist s;
   va_start(s.vafield, fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 's.vafield' is leaked}} expected-note{{Initialized va_list 's.vafield' is leaked}}
+} // expected-warning{{Initialized va_list 's.vafield' is leaked}}
+  // expected-note@-1{{Initialized va_list 's.vafield' is leaked}}
 
 void casting(int fst, ...) {
   char mem[sizeof(va_list)];
   va_start(*(va_list *) mem, fst); // expected-note{{Initialized va_list}}
-} // expected-warning{{Initialized va_list 'mem[0]' is leaked}} expected-note{{Initialized va_list 'mem[0]' is leaked}}
+} // expected-warning{{Initialized va_list 'mem[0]' is leaked}}
+  // expected-note@-1{{Initialized va_list 'mem[0]' is leaked}}
 
 
 void castingOk(int fst, ...) {
diff --git a/test/Analysis/variadic-method-types.m b/test/Analysis/variadic-method-types.m
index 9f90e5f..6db93ac 100644
--- a/test/Analysis/variadic-method-types.m
+++ b/test/Analysis/variadic-method-types.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,osx.cocoa.VariadicMethodTypes -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,osx.cocoa.VariadicMethodTypes -analyzer-store=region -fblocks -verify %s
 
 //===----------------------------------------------------------------------===//
 // The following code is reduced using delta-debugging from
diff --git a/test/Analysis/vfork.c b/test/Analysis/vfork.c
index c7a02fa..da1b5da 100644
--- a/test/Analysis/vfork.c
+++ b/test/Analysis/vfork.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify -x c++ %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify -x c++ %s
 
 #include "Inputs/system-header-simulator.h"
 
diff --git a/test/Analysis/virtualcall.cpp b/test/Analysis/virtualcall.cpp
index 311f0a1..56bd324 100644
--- a/test/Analysis/virtualcall.cpp
+++ b/test/Analysis/virtualcall.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -verify -std=c++11 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:Interprocedural=true -DINTERPROCEDURAL=1 -verify -std=c++11 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -verify -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -verify -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:Interprocedural=true -DINTERPROCEDURAL=1 -verify -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -verify -std=c++11 %s
 
 /* When INTERPROCEDURAL is set, we expect diagnostics in all functions reachable
    from a constructor or destructor. If it is not set, we expect diagnostics
diff --git a/test/Analysis/vla.c b/test/Analysis/vla.c
index f94bea9..eb06c24 100644
--- a/test/Analysis/vla.c
+++ b/test/Analysis/vla.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
 
 // Zero-sized VLAs.
 void check_zero_sized_VLA(int x) {
diff --git a/test/Analysis/weak-functions.c b/test/Analysis/weak-functions.c
index a983f92..514a943 100644
--- a/test/Analysis/weak-functions.c
+++ b/test/Analysis/weak-functions.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection,unix.Malloc,unix.cstring,alpha.unix.cstring,unix.API,osx.API,osx.cocoa.RetainCount -Wno-null-dereference -Wno-tautological-compare -analyzer-store=region -fblocks -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core,debug.ExprInspection,unix.Malloc,unix.cstring,alpha.unix.cstring,unix.API,osx.API,osx.cocoa.RetainCount -Wno-null-dereference -Wno-tautological-compare -analyzer-store=region -fblocks -verify %s
 #define NULL 0
 void clang_analyzer_eval(int);
 void myFunc();
diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
index a27cea8..58c7c0c 100644
--- a/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
+++ b/test/CXX/dcl.dcl/dcl.attr/dcl.attr.deprecated/p1.cpp
@@ -23,7 +23,38 @@
 X<char> x1;
 X<int> x2; // expected-warning {{'X<int>' is deprecated}}
 
-template <typename T> class [[deprecated]] X2 {};
+template <typename T> class [[deprecated]] X2 {}; //expected-note {{'X2<char>' has been explicitly marked deprecated here}}
 template <> class X2<int> {};
-X2<char> x3; // FIXME: no warning!
-X2<int> x4;
+X2<char> x3; // expected-warning {{'X2<char>' is deprecated}}
+X2<int> x4; // No warning, the specialization removes it.
+
+template <typename T> class [[deprecated]] X3; //expected-note {{'X3<char>' has been explicitly marked deprecated here}}
+template <> class X3<int>;
+X3<char> *x5; // expected-warning {{'X3<char>' is deprecated}}
+X3<int> *x6; // No warning, the specialization removes it.
+
+template <typename T> struct A;
+A<int> *p;
+template <typename T> struct [[deprecated]] A;//expected-note {{'A<int>' has been explicitly marked deprecated here}} expected-note {{'A<float>' has been explicitly marked deprecated here}}
+A<int> *q; // expected-warning {{'A<int>' is deprecated}}
+A<float> *r; // expected-warning {{'A<float>' is deprecated}}
+
+template <typename T> struct B;
+B<int> *p2;
+template <typename T> struct [[deprecated]] B;//expected-note {{'B<int>' has been explicitly marked deprecated here}} expected-note {{'B<float>' has been explicitly marked deprecated here}}
+B<int> *q2; // expected-warning {{'B<int>' is deprecated}}
+B<float> *r2; // expected-warning {{'B<float>' is deprecated}}
+
+template <typename T> 
+T some_func(T t) {
+  struct [[deprecated]] FunS{}; // expected-note {{'FunS' has been explicitly marked deprecated here}}
+  FunS f;// expected-warning {{'FunS' is deprecated}}
+
+}
+
+template <typename T>
+[[deprecated]]T some_func2(T t) {
+  struct FunS2{};
+  FunS2 f;// No warning, entire function is deprecated, so usage here should be fine.
+
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
index f381ed7..ade3274 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.list/p3.cpp
@@ -150,35 +150,44 @@
 
     void f(T);
     f(T{0});
+
+    char c;
+    auto t3 = T{c};
   }
 #if __cplusplus <= 201402L
-  // expected-error@-15 5{{cannot initialize}}
-  // expected-error@-15 5{{cannot initialize}}
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
   //
   //
-  // expected-error@-15 5{{cannot initialize}}
+  // expected-error@-18 5{{cannot initialize}}
+  //
+  //
+  // expected-error@-18 5{{cannot initialize}}
 #else
-  // expected-error@-29 {{cannot initialize}}
-  // expected-error@-29 {{cannot initialize}}
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
   //
   //
-  // expected-error@-29 {{cannot initialize}}
+  // expected-error@-35 {{cannot initialize}}
+  //
+  //
+  // expected-error@-35 {{cannot initialize}}
 #endif
 
   template<typename T> void bad() {
@@ -252,4 +261,12 @@
     (void)B{0.0}; // expected-error {{type 'double' cannot be narrowed}}
 #endif
   }
+
+#if __cplusplus > 201402L
+  enum class F : unsigned {};
+  F f1(unsigned x) { return F{x}; }
+  F f2(const unsigned x) { return F{x}; }
+  F f3(bool x) { return F{x}; }
+  F f4(const bool x) { return F{x}; }
+#endif
 }
diff --git a/test/CXX/special/class.dtor/p10-0x.cpp b/test/CXX/special/class.dtor/p10-0x.cpp
index 3b8a0ad..3be0a98 100644
--- a/test/CXX/special/class.dtor/p10-0x.cpp
+++ b/test/CXX/special/class.dtor/p10-0x.cpp
@@ -33,7 +33,7 @@
                              expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
   i.~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
   pi->~decltype(int())();
-  pi.~decltype(int())(); // expected-error{{the type of object expression ('int *') does not match the type being destroyed ('decltype(int())' (aka 'int')) in pseudo-destructor expression}}
+  pi.~decltype(int())(); // expected-error{{member reference type 'int *' is a pointer; did you mean to use '->'?}}
   pi.~decltype(intp())();
   pi->~decltype(intp())(); // expected-error{{the type of object expression ('int') does not match the type being destroyed ('decltype(intp())' (aka 'int *')) in pseudo-destructor expression}}
 }
diff --git a/test/CodeCompletion/auto_type.c b/test/CodeCompletion/auto_type.c
new file mode 100644
index 0000000..3fcfff0
--- /dev/null
+++ b/test/CodeCompletion/auto_type.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -code-completion-at=%s:3:1 %s | FileCheck %s
+void func() {
+
+}
+// CHECK: COMPLETION: __auto_type
diff --git a/test/CodeCompletion/keywords.cpp b/test/CodeCompletion/keywords.cpp
new file mode 100644
index 0000000..6e5824c
--- /dev/null
+++ b/test/CodeCompletion/keywords.cpp
@@ -0,0 +1,79 @@
+int function(int x) {
+  return x + 1;
+}
+
+int variable = 0;
+
+class Class {
+public:
+  Class() { }
+
+  int method(int x) {
+    return x + 1;
+  }
+
+  virtual void virtualMethod() {
+  }
+
+  static void staticMethod() {
+  }
+
+  static int staticVar;
+};
+
+class SubClass : public Class {
+  void virtualMethod() override final {
+  }
+};
+
+struct Struct {
+};
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:1:1 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:5:1 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:11:1 %s | FileCheck --check-prefix=CHECK-TOP-LEVEL %s
+// CHECK-TOP-LEVEL: alignas(<#expression#>)
+// CHECK-TOP-LEVEL: constexpr
+// CHECK-TOP-LEVEL: static_assert(<#expression#>, <#message#>)
+// CHECK-TOP-LEVEL: thread_local
+// CHECK-TOP-LEVEL-NOT: final
+// CHECK-TOP-LEVEL-NOT: noexcept
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:1:14 %s | FileCheck --check-prefix=CHECK-PARAM %s
+// CHECK-PARAM-NOT: alignas
+// CHECK-PARAM-NOT: constexpr
+// CHECK-PARAM-NOT: final
+// CHECK-PARAM-NOT: thread_local
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:21:10 %s | FileCheck --check-prefix=CHECK-STATICVAR1 %s
+// CHECK-STATICVAR1: constexpr
+// CHECK-STATICVAR1: thread_local
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:7:13 %s | FileCheck --check-prefix=CHECK-CLASS-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:24:16 %s | FileCheck --check-prefix=CHECK-CLASS-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:29:15 %s | FileCheck --check-prefix=CHECK-CLASS-QUALIFIER %s
+// CHECK-CLASS-QUALIFIER: final
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:1:21 %s | FileCheck --check-prefix=CHECK-FUNCTION-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:9:11 %s | FileCheck --check-prefix=CHECK-FUNCTION-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:18:30 %s | FileCheck --check-prefix=CHECK-FUNCTION-QUALIFIER %s
+// CHECK-FUNCTION-QUALIFIER: noexcept
+// CHECK-FUNCTION-QUALIFIER-NOT: final
+// CHECK-FUNCTION-QUALIFIER-NOT: override
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:11:21 %s | FileCheck --check-prefix=CHECK-METHOD-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:15:32 %s | FileCheck --check-prefix=CHECK-METHOD-QUALIFIER %s
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:25:24 %s | FileCheck --check-prefix=CHECK-METHOD-QUALIFIER %s
+// CHECK-METHOD-QUALIFIER: final
+// CHECK-METHOD-QUALIFIER: noexcept
+// CHECK-METHOD-QUALIFIER: override
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:25:33 %s | FileCheck --check-prefix=CHECK-OVERRIDE-SPECIFIED %s
+// CHECK-OVERRIDE-SPECIFIED: final
+// CHECK-OVERRIDE-SPECIFIED: noexcept
+// CHECK-OVERRIDE-SPECIFIED-NOT: override
+
+// RUN: %clang_cc1 -std=c++11 -code-completion-at=%s:25:39 %s | FileCheck --check-prefix=CHECK-OVERRIDE-FINAL-SPECIFIED %s
+// CHECK-OVERRIDE-FINAL-SPECIFIED: noexcept
+// CHECK-OVERRIDE-FINAL-SPECIFIED-NOT: final
+// CHECK-OVERRIDE-FINAL-SPECIFIED-NOT: override
diff --git a/test/CodeCompletion/member-access.cpp b/test/CodeCompletion/member-access.cpp
index 8195f76..53af121 100644
--- a/test/CodeCompletion/member-access.cpp
+++ b/test/CodeCompletion/member-access.cpp
@@ -37,6 +37,17 @@
   }
 };
 
+struct Foo {
+  void foo() const;
+  static void foo(bool);
+};
+
+struct Bar {
+  void foo(bool param) {
+    Foo::foo(  );// unresolved member expression with an implicit base
+  }
+};
+
   // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:29:6 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s
   // CHECK-CC1: Base1 : Base1::
   // CHECK-CC1: member1 : [#int#][#Base1::#]member1
@@ -52,3 +63,86 @@
 
 // Make sure this doesn't crash
 // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:36:7 %s -verify
+
+// Make sure this also doesn't crash
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:47:14 %s
+
+
+template<typename T>
+class BaseTemplate {
+public:
+  T baseTemplateFunction();
+
+  T baseTemplateField;
+};
+
+template<typename T, typename S>
+class TemplateClass: public Base1 , public BaseTemplate<T> {
+public:
+  T function() { }
+  T field;
+
+  void overload1(const T &);
+  void overload1(const S &);
+};
+
+template<typename T, typename S>
+void completeDependentMembers(TemplateClass<T, S> &object,
+                              TemplateClass<int, S> *object2) {
+  object.field;
+  object2->field;
+// CHECK-CC2: baseTemplateField : [#T#][#BaseTemplate<T>::#]baseTemplateField
+// CHECK-CC2: baseTemplateFunction : [#T#][#BaseTemplate<T>::#]baseTemplateFunction()
+// CHECK-CC2: field : [#T#]field
+// CHECK-CC2: function : [#T#]function()
+// CHECK-CC2: member1 : [#int#][#Base1::#]member1
+// CHECK-CC2: member2 : [#float#][#Base1::#]member2
+// CHECK-CC2: overload1 : [#void#]overload1(<#const T &#>)
+// CHECK-CC2: overload1 : [#void#]overload1(<#const S &#>)
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:92:10 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:93:12 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+}
+
+
+void completeDependentSpecializedMembers(TemplateClass<int, double> &object,
+                                         TemplateClass<int, double> *object2) {
+  object.field;
+  object2->field;
+// CHECK-CC3: baseTemplateField : [#int#][#BaseTemplate<int>::#]baseTemplateField
+// CHECK-CC3: baseTemplateFunction : [#int#][#BaseTemplate<int>::#]baseTemplateFunction()
+// CHECK-CC3: field : [#int#]field
+// CHECK-CC3: function : [#int#]function()
+// CHECK-CC3: member1 : [#int#][#Base1::#]member1
+// CHECK-CC3: member2 : [#float#][#Base1::#]member2
+// CHECK-CC3: overload1 : [#void#]overload1(<#const int &#>)
+// CHECK-CC3: overload1 : [#void#]overload1(<#const double &#>)
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:110:10 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:111:12 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+}
+
+template <typename T>
+class Template {
+public:
+  BaseTemplate<int> o1;
+  BaseTemplate<T> o2;
+
+  void function() {
+    o1.baseTemplateField;
+// CHECK-CC4: BaseTemplate : BaseTemplate::
+// CHECK-CC4: baseTemplateField : [#int#]baseTemplateField
+// CHECK-CC4: baseTemplateFunction : [#int#]baseTemplateFunction()
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:132:8 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
+    o2.baseTemplateField;
+// CHECK-CC5: BaseTemplate : BaseTemplate::
+// CHECK-CC5: baseTemplateField : [#T#]baseTemplateField
+// CHECK-CC5: baseTemplateFunction : [#T#]baseTemplateFunction()
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:137:8 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s
+    this->o1;
+// CHECK-CC6: [#void#]function()
+// CHECK-CC6: o1 : [#BaseTemplate<int>#]o1
+// CHECK-CC6: o2 : [#BaseTemplate<T>#]o2
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:142:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s
+  }
+};
diff --git a/test/CodeCompletion/ordinary-name-cxx11.cpp b/test/CodeCompletion/ordinary-name-cxx11.cpp
index 8e6f383..34c3bf9 100644
--- a/test/CodeCompletion/ordinary-name-cxx11.cpp
+++ b/test/CodeCompletion/ordinary-name-cxx11.cpp
@@ -39,10 +39,12 @@
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#size_t#]sizeof...(<#parameter-pack#>)
   // CHECK-CC1-NEXT: COMPLETION: static
+  // CHECK-CC1-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-CC1-NEXT: COMPLETION: Pattern : static_cast<<#type#>>(<#expression#>)
   // CHECK-CC1-NEXT: COMPLETION: struct
   // CHECK-CC1-NEXT: COMPLETION: Pattern : switch(<#condition#>){
   // CHECK-CC1: COMPLETION: t : t
+  // CHECK-CC1-NEXT: COMPLETION: thread_local
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#void#]throw <#expression#>
   // CHECK-CC1-NEXT: COMPLETION: Pattern : [#bool#]true
   // CHECK-CC1-NEXT: COMPLETION: Pattern : try{<#statements#>
@@ -72,6 +74,7 @@
   // CHECK-CC2-NEXT: COMPLETION: char32
   // CHECK-CC2-NEXT: COMPLETION: class
   // CHECK-CC2-NEXT: COMPLETION: const
+  // CHECK-CC2-NEXT: COMPLETION: constexpr
   // CHECK-CC2-NEXT: COMPLETION: Pattern : decltype(<#expression#>)
   // CHECK-CC2-NEXT: COMPLETION: double
   // CHECK-CC2-NEXT: COMPLETION: enum
@@ -86,10 +89,12 @@
   // CHECK-CC2-NEXT: COMPLETION: short
   // CHECK-CC2-NEXT: COMPLETION: signed
   // CHECK-CC2-NEXT: COMPLETION: static
+  // CHECK-CC2-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-CC2-NEXT: COMPLETION: struct
   // CHECK-CC2-NEXT: COMPLETION: t : t
   // CHECK-CC2-NEXT: COMPLETION: Pattern : template <#declaration#>
   // CHECK-CC2-NEXT: COMPLETION: Pattern : template<<#parameters#>>
+  // CHECK-CC2-NEXT: COMPLETION: thread_local
   // CHECK-CC2-NEXT: COMPLETION: TYPEDEF : TYPEDEF
   // CHECK-CC2-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>
   // CHECK-CC2-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#>
@@ -111,6 +116,7 @@
   // CHECK-CC3-NEXT: COMPLETION: char32_t
   // CHECK-CC3-NEXT: COMPLETION: class
   // CHECK-CC3-NEXT: COMPLETION: const
+  // CHECK-CC3-NEXT: COMPLETION: constexpr
   // CHECK-CC3-NEXT: COMPLETION: Pattern : decltype(<#expression#>)
   // CHECK-CC3-NEXT: COMPLETION: double
   // CHECK-CC3-NEXT: COMPLETION: enum
@@ -129,8 +135,10 @@
   // CHECK-CC3-NEXT: COMPLETION: short
   // CHECK-CC3-NEXT: COMPLETION: signed
   // CHECK-CC3-NEXT: COMPLETION: static
+  // CHECK-CC3-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-CC3-NEXT: COMPLETION: struct
   // CHECK-CC3-NEXT: COMPLETION: Pattern : template<<#parameters#>>
+  // CHECK-CC3-NEXT: COMPLETION: thread_local
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typedef <#type#> <#name#>
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typename <#qualifier#>::<#name#>
   // CHECK-CC3-NEXT: COMPLETION: Pattern : typeof <#expression#>
@@ -227,6 +235,7 @@
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof(<#expression-or-type#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : [#size_t#]sizeof...(<#parameter-pack#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: static
+  // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : static_assert(<#expression#>, <#message#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : static_cast<<#type#>>(<#expression#>)
   // CHECK-NO-RTTI-NEXT: COMPLETION: struct
   // CHECK-NO-RTTI-NEXT: COMPLETION: Pattern : switch(<#condition#>){
diff --git a/test/CodeCompletion/pragma-macro-token-caching.c b/test/CodeCompletion/pragma-macro-token-caching.c
new file mode 100644
index 0000000..432706e
--- /dev/null
+++ b/test/CodeCompletion/pragma-macro-token-caching.c
@@ -0,0 +1,18 @@
+
+#define Outer(action) action
+
+void completeParam(int param) {
+    ;
+    Outer(__extension__({ _Pragma("clang diagnostic push") }));
+    param;
+}
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:7:1 %s | FileCheck %s
+// CHECK: param : [#int#]param
+
+void completeParamPragmaError(int param) {
+    Outer(__extension__({ _Pragma(2) })); // expected-error {{_Pragma takes a parenthesized string literal}}
+    param;
+}
+
+// RUN: %clang_cc1 -fsyntax-only -verify -code-completion-at=%s:16:1 %s | FileCheck %s
diff --git a/test/CodeGen/64bit-swiftcall.c b/test/CodeGen/64bit-swiftcall.c
index c1f09817..06c3145 100644
--- a/test/CodeGen/64bit-swiftcall.c
+++ b/test/CodeGen/64bit-swiftcall.c
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s
 // RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s --check-prefix=ARM64
 
 // REQUIRES: aarch64-registered-target,x86-registered-target
 
@@ -60,6 +61,7 @@
 /********************************** LOWERING *********************************/
 /*****************************************************************************/
 
+typedef float float3 __attribute__((ext_vector_type(3)));
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef float float8 __attribute__((ext_vector_type(8)));
 typedef double double2 __attribute__((ext_vector_type(2)));
@@ -1005,3 +1007,10 @@
 TEST(union_het_vecint)
 // CHECK: define swiftcc void @return_union_het_vecint([[UNION:%.*]]* noalias sret
 // CHECK: define swiftcc void @take_union_het_vecint([[UNION]]*
+
+typedef struct {
+  float3 f3;
+} struct_v1f3;
+TEST(struct_v1f3)
+// ARM64-LABEL: define swiftcc { <2 x float>, float } @return_struct_v1f3()
+// ARM64-LABEL: define swiftcc void @take_struct_v1f3(<2 x float>, float)
diff --git a/test/CodeGen/PR32874.c b/test/CodeGen/PR32874.c
new file mode 100644
index 0000000..f8aa1c2
--- /dev/null
+++ b/test/CodeGen/PR32874.c
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -x c -S -emit-llvm -o - -triple x86_64-apple-darwin10 %s \
+// RUN:   -w -fsanitize=signed-integer-overflow,unsigned-integer-overflow,integer-divide-by-zero,float-divide-by-zero \
+// RUN:   | FileCheck %s
+
+// CHECK-LABEL: define void @foo
+// CHECK-NOT: !nosanitize
+void foo(const int *p) {
+  // __builtin_prefetch expects its optional arguments to be constant integers.
+  // Check that ubsan does not instrument any safe arithmetic performed in
+  // operands to __builtin_prefetch. (A clang frontend check should reject
+  // unsafe arithmetic in these operands.)
+
+  __builtin_prefetch(p, 0 + 1, 0 + 3);
+  __builtin_prefetch(p, 1 - 0, 3 - 0);
+  __builtin_prefetch(p, 1 * 1, 1 * 3);
+  __builtin_prefetch(p, 1 / 1, 3 / 1);
+  __builtin_prefetch(p, 3 % 2, 3 % 1);
+
+  __builtin_prefetch(p, 0U + 1U, 0U + 3U);
+  __builtin_prefetch(p, 1U - 0U, 3U - 0U);
+  __builtin_prefetch(p, 1U * 1U, 1U * 3U);
+  __builtin_prefetch(p, 1U / 1U, 3U / 1U);
+  __builtin_prefetch(p, 3U % 2U, 3U % 1U);
+}
+
+// CHECK-LABEL: define void @ub_constant_arithmetic
+void ub_constant_arithmetic() {
+  // Check that we still instrument unsafe arithmetic, even if it is known to
+  // be unsafe at compile time.
+
+  int INT_MIN = 0xffffffff;
+  int INT_MAX = 0x7fffffff;
+
+  // CHECK: call void @__ubsan_handle_add_overflow
+  // CHECK: call void @__ubsan_handle_add_overflow
+  INT_MAX + 1;
+  INT_MAX + -1;
+
+  // CHECK: call void @__ubsan_handle_negate_overflow
+  // CHECK: call void @__ubsan_handle_sub_overflow
+  -INT_MIN;
+  -INT_MAX - 2;
+
+  // CHECK: call void @__ubsan_handle_mul_overflow
+  // CHECK: call void @__ubsan_handle_mul_overflow
+  INT_MAX * INT_MAX;
+  INT_MIN * INT_MIN;
+
+  // CHECK: call void @__ubsan_handle_divrem_overflow
+  // CHECK: call void @__ubsan_handle_divrem_overflow
+  1 / 0;
+  INT_MIN / -1;
+
+  // CHECK: call void @__ubsan_handle_divrem_overflow
+  // CHECK: call void @__ubsan_handle_divrem_overflow
+  1 % 0;
+  INT_MIN % -1;
+
+  // CHECK: call void @__ubsan_handle_divrem_overflow
+  1.0 / 0.0;
+}
diff --git a/test/CodeGen/aarch64-args.cpp b/test/CodeGen/aarch64-args.cpp
new file mode 100644
index 0000000..4097736
--- /dev/null
+++ b/test/CodeGen/aarch64-args.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios7.0 -target-abi darwinpcs -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - -x c %s | FileCheck %s --check-prefix=CHECK-GNU-C
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK-GNU-CXX
+
+// Empty structs are ignored for PCS purposes on Darwin and in C mode elsewhere.
+// In C++ mode on ELF they consume a register slot though. Functions are
+// slightly bigger than minimal to make confirmation against actual GCC
+// behaviour easier.
+
+#if __cplusplus
+#define EXTERNC extern "C"
+#else
+#define EXTERNC
+#endif
+
+struct Empty {};
+
+// CHECK: define i32 @empty_arg(i32 %a)
+// CHECK-GNU-C: define i32 @empty_arg(i32 %a)
+// CHECK-GNU-CXX: define i32 @empty_arg(i8 %e.coerce, i32 %a)
+EXTERNC int empty_arg(struct Empty e, int a) {
+  return a;
+}
+
+// CHECK: define void @empty_ret()
+// CHECK-GNU-C: define void @empty_ret()
+// CHECK-GNU-CXX: define void @empty_ret()
+EXTERNC struct Empty empty_ret() {
+  struct Empty e;
+  return e;
+}
+
+// However, what counts as "empty" is a baroque mess. This is super-empty, it's
+// ignored even in C++ mode. It also has sizeof == 0, violating C++, but that's
+// legacy for you:
+
+struct SuperEmpty {
+  int arr[0];
+};
+
+// CHECK: define i32 @super_empty_arg(i32 %a)
+// CHECK-GNU-C: define i32 @super_empty_arg(i32 %a)
+// CHECK-GNU-CXX: define i32 @super_empty_arg(i32 %a)
+EXTERNC int super_empty_arg(struct SuperEmpty e, int a) {
+  return a;
+}
+
+// This is not empty. It has 0 size but consumes a register slot for GCC.
+
+struct SortOfEmpty {
+  struct SuperEmpty e;
+};
+
+// CHECK: define i32 @sort_of_empty_arg(i32 %a)
+// CHECK-GNU-C: define i32 @sort_of_empty_arg(i32 %a)
+// CHECK-GNU-CXX: define i32 @sort_of_empty_arg(i8 %e.coerce, i32 %a)
+EXTERNC int sort_of_empty_arg(struct Empty e, int a) {
+  return a;
+}
+
+// CHECK: define void @sort_of_empty_ret()
+// CHECK-GNU-C: define void @sort_of_empty_ret()
+// CHECK-GNU-CXX: define void @sort_of_empty_ret()
+EXTERNC struct SortOfEmpty sort_of_empty_ret() {
+  struct SortOfEmpty e;
+  return e;
+}
diff --git a/test/CodeGen/aarch64-neon-intrinsics.c b/test/CodeGen/aarch64-neon-intrinsics.c
index 2ffbcdc..54877e9 100644
--- a/test/CodeGen/aarch64-neon-intrinsics.c
+++ b/test/CodeGen/aarch64-neon-intrinsics.c
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \
-// RUN:     -fallow-half-arguments-and-returns -ffp-contract=fast -S -emit-llvm -o - %s \
+// RUN:     -fallow-half-arguments-and-returns -S -emit-llvm -o - %s \
 // RUN: | opt -S -mem2reg \
 // RUN: | FileCheck %s
 
diff --git a/test/CodeGen/arm-swiftcall.c b/test/CodeGen/arm-swiftcall.c
index 5a7e170..f5c3384 100644
--- a/test/CodeGen/arm-swiftcall.c
+++ b/test/CodeGen/arm-swiftcall.c
@@ -57,6 +57,7 @@
 /********************************** LOWERING *********************************/
 /*****************************************************************************/
 
+typedef float float3 __attribute__((ext_vector_type(3)));
 typedef float float4 __attribute__((ext_vector_type(4)));
 typedef float float8 __attribute__((ext_vector_type(8)));
 typedef double double2 __attribute__((ext_vector_type(2)));
@@ -1013,3 +1014,10 @@
 TEST(struct_vf81)
 // CHECK-LABEL: define swiftcc { <4 x float>, <4 x float> } @return_struct_vf81()
 // CHECK-LABEL: define swiftcc void @take_struct_vf81(<4 x float>, <4 x float>)
+
+typedef struct {
+  float3 f3;
+} struct_v1f3;
+TEST(struct_v1f3)
+// CHECK-LABEL: define swiftcc { <2 x float>, float } @return_struct_v1f3()
+// CHECK-LABEL: define swiftcc void @take_struct_v1f3(<2 x float>, float)
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
index d7a26f8..ce207c4 100644
--- a/test/CodeGen/catch-undef-behavior.c
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -1,6 +1,5 @@
 // RUN: %clang_cc1 -fsanitize=alignment,null,object-size,shift-base,shift-exponent,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize-recover=alignment,null,object-size,shift-base,shift-exponent,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-UBSAN
 // RUN: %clang_cc1 -fsanitize-trap=alignment,null,object-size,shift-base,shift-exponent,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize-recover=alignment,null,object-size,shift-base,shift-exponent,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize=alignment,null,object-size,shift-base,shift-exponent,return,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -fsanitize-recover=alignment,null,object-size,shift-base,shift-exponent,signed-integer-overflow,vla-bound,float-cast-overflow,integer-divide-by-zero,bool,returns-nonnull-attribute,nonnull-attribute -emit-llvm %s -o - -triple x86_64-linux-gnu | opt -instnamer -S | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-TRAP
-// RUN: %clang_cc1 -fsanitize=null -fsanitize-recover=null -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-NULL
 // RUN: %clang_cc1 -fsanitize=signed-integer-overflow -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-OVERFLOW
 
 // CHECK-UBSAN: @[[INT:.*]] = private unnamed_addr constant { i16, i16, [6 x i8] } { i16 0, i16 11, [6 x i8] c"'int'\00" }
@@ -30,25 +29,14 @@
 // CHECK-UBSAN: @[[LINE_1500:.*]] = {{.*}}, i32 1500, i32 10 {{.*}} @[[FP16]], {{.*}} }
 // CHECK-UBSAN: @[[LINE_1600:.*]] = {{.*}}, i32 1600, i32 10 {{.*}} @{{.*}} }
 
-// CHECK-NULL: @[[LINE_100:.*]] = private unnamed_addr global {{.*}}, i32 100, i32 5 {{.*}}
-
 // PR6805
 // CHECK-COMMON-LABEL: @foo
-// CHECK-NULL-LABEL: @foo
 void foo() {
   union { int i; } u;
-  // CHECK-COMMON:      %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null
 
-  // CHECK-COMMON:      %[[I8PTR:.*]] = bitcast i32* %[[PTR]] to i8*
+  // CHECK-COMMON:      %[[I8PTR:.*]] = bitcast i32* %[[PTR:.*]] to i8*
   // CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false)
-  // CHECK-COMMON-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4
-
-  // CHECK-COMMON:      %[[PTRTOINT:.*]] = ptrtoint {{.*}}* %[[PTR]] to i64
-  // CHECK-COMMON-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRTOINT]], 3
-  // CHECK-COMMON-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0
-
-  // CHECK-COMMON:       %[[CHECK01:.*]] = and i1 %[[CHECK0]], %[[CHECK1]]
-  // CHECK-COMMON-NEXT:  %[[OK:.*]] = and i1 %[[CHECK01]], %[[CHECK2]]
+  // CHECK-COMMON-NEXT: %[[OK:.*]] = icmp uge i64 %[[SIZE]], 4
 
   // CHECK-UBSAN: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
   // CHECK-TRAP:  br i1 %[[OK]], {{.*}}
@@ -58,11 +46,6 @@
 
   // CHECK-TRAP:      call void @llvm.trap() [[NR_NUW:#[0-9]+]]
   // CHECK-TRAP-NEXT: unreachable
-
-  // With -fsanitize=null, only perform the null check.
-  // CHECK-NULL: %[[NULL:.*]] = icmp ne {{.*}}, null
-  // CHECK-NULL: br i1 %[[NULL]]
-  // CHECK-NULL: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_100]] to i8*), i64 %{{.*}})
 #line 100
   u.i=1;
 }
diff --git a/test/CodeGen/compound-assign-overflow.c b/test/CodeGen/compound-assign-overflow.c
index f126bb0..92ae249 100644
--- a/test/CodeGen/compound-assign-overflow.c
+++ b/test/CodeGen/compound-assign-overflow.c
@@ -25,11 +25,9 @@
   // CHECK: @__ubsan_handle_add_overflow(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), {{.*}})
 }
 
-int8_t a, b;
-
 // CHECK: @compdiv
 void compdiv() {
 #line 300
-  a /= b;
+  x /= x;
   // CHECK: @__ubsan_handle_divrem_overflow(i8* bitcast ({{.*}} @[[LINE_300]] to i8*), {{.*}})
 }
diff --git a/test/CodeGen/debug-info-vla.c b/test/CodeGen/debug-info-vla.c
index 371d106..3b69773 100644
--- a/test/CodeGen/debug-info-vla.c
+++ b/test/CodeGen/debug-info-vla.c
@@ -4,8 +4,8 @@
 {
 // CHECK: dbg.declare
 // CHECK: dbg.declare({{.*}}, metadata ![[VAR:.*]], metadata ![[EXPR:.*]])
-// CHECK: ![[VAR]] = !DILocalVariable(name: "vla",{{.*}} line: [[@LINE+2]]
-// CHECK: ![[EXPR]] = !DIExpression(DW_OP_deref)
+// CHECK: ![[EXPR]] = !DIExpression()
+// CHECK: ![[VAR]] = !DILocalVariable(name: "vla",{{.*}} line: [[@LINE+1]]
   int vla[s];
   int i;
   for (i = 0; i < s; i++) {
diff --git a/test/CodeGen/ffp-contract-fast-option.cpp b/test/CodeGen/ffp-contract-fast-option.cpp
new file mode 100644
index 0000000..3db93de
--- /dev/null
+++ b/test/CodeGen/ffp-contract-fast-option.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -O3 -ffp-contract=fast -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+float fp_contract_1(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_1fff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  return a * b + c;
+}
+
+float fp_contract_2(float a, float b, float c) {
+  // CHECK-LABEL: fp_contract_2fff(
+  // CHECK: fmul contract float
+  // CHECK: fsub contract float
+  return a * b - c;
+}
+
+void fp_contract_3(float *a, float b, float c) {
+  // CHECK-LABEL: fp_contract_3Pfff(
+  // CHECK: fmul contract float
+  // CHECK: fadd contract float
+  a[0] += b * c;
+}
+
+void fp_contract_4(float *a, float b, float c) {
+  // CHECK-LABEL: fp_contract_4Pfff(
+  // CHECK: fmul contract float
+  // CHECK: fsub contract float
+  a[0] -= b * c;
+}
diff --git a/test/CodeGen/ffp-contract-option.c b/test/CodeGen/ffp-contract-option.c
index 61913b0..52b7507 100644
--- a/test/CodeGen/ffp-contract-option.c
+++ b/test/CodeGen/ffp-contract-option.c
@@ -1,8 +1,8 @@
-// RUN: %clang_cc1 -O3 -ffp-contract=fast -triple=powerpc-apple-darwin10 -S -o - %s | FileCheck %s
-// REQUIRES: powerpc-registered-target
+// RUN: %clang_cc1 -O3 -ffp-contract=fast -triple=aarch64-apple-darwin -S -o - %s | FileCheck %s
+// REQUIRES: aarch64-registered-target
 
 float fma_test1(float a, float b, float c) {
-// CHECK: fmadds
+// CHECK: fmadd
   float x = a * b;
   float y = x + c;
   return y;
diff --git a/test/CodeGen/fp-contract-fast-pragma.cpp b/test/CodeGen/fp-contract-fast-pragma.cpp
new file mode 100644
index 0000000..c2e52f0
--- /dev/null
+++ b/test/CodeGen/fp-contract-fast-pragma.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+// Is FP_CONTRACT honored in a simple case?
+float fp_contract_1(float a, float b, float c) {
+// CHECK: _Z13fp_contract_1fff
+// CHECK: %[[M:.+]] = fmul contract float %a, %b
+// CHECK-NEXT: fadd contract float %[[M]], %c
+#pragma clang fp contract(fast)
+  return a * b + c;
+}
+
+// Is FP_CONTRACT state cleared on exiting compound statements?
+float fp_contract_2(float a, float b, float c) {
+  // CHECK: _Z13fp_contract_2fff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  {
+#pragma clang fp contract(fast)
+  }
+  return a * b + c;
+}
+
+// Does FP_CONTRACT survive template instantiation?
+class Foo {};
+Foo operator+(Foo, Foo);
+
+template <typename T>
+T template_muladd(T a, T b, T c) {
+#pragma clang fp contract(fast)
+  return a * b + c;
+}
+
+float fp_contract_3(float a, float b, float c) {
+  // CHECK: _Z13fp_contract_3fff
+  // CHECK: %[[M:.+]] = fmul contract float %a, %b
+  // CHECK-NEXT: fadd contract float %[[M]], %c
+  return template_muladd<float>(a, b, c);
+}
+
+template <typename T>
+class fp_contract_4 {
+  float method(float a, float b, float c) {
+#pragma clang fp contract(fast)
+    return a * b + c;
+  }
+};
+
+template class fp_contract_4<int>;
+// CHECK: _ZN13fp_contract_4IiE6methodEfff
+// CHECK: %[[M:.+]] = fmul contract float %a, %b
+// CHECK-NEXT: fadd contract float %[[M]], %c
+
+// Check file-scoped FP_CONTRACT
+#pragma clang fp contract(fast)
+float fp_contract_5(float a, float b, float c) {
+  // CHECK: _Z13fp_contract_5fff
+  // CHECK: %[[M:.+]] = fmul contract float %a, %b
+  // CHECK-NEXT: fadd contract float %[[M]], %c
+  return a * b + c;
+}
+
+// Verify that we can handle multiple flags on the same pragma
+#pragma clang fp contract(fast) contract(off)
+float fp_contract_6(float a, float b, float c) {
+  // CHECK: _Z13fp_contract_6fff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  return a * b + c;
+}
diff --git a/test/CodeGen/fp-contract-on-asm.c b/test/CodeGen/fp-contract-on-asm.c
new file mode 100644
index 0000000..01a1bd1
--- /dev/null
+++ b/test/CodeGen/fp-contract-on-asm.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -O3 -triple=aarch64-apple-ios -S -o - %s | FileCheck %s
+// REQUIRES: aarch64-registered-target
+
+float fma_test1(float a, float b, float c) {
+#pragma STDC FP_CONTRACT ON
+// CHECK-LABEL: fma_test1:
+// CHECK: fmadd
+  float x = a * b + c;
+  return x;
+}
+
+float fma_test2(float a, float b, float c) {
+// CHECK-LABEL: fma_test2:
+// CHECK: fmul
+// CHECK: fadd
+  float x = a * b + c;
+  return x;
+}
diff --git a/test/CodeGen/fp-contract-on-pragma.cpp b/test/CodeGen/fp-contract-on-pragma.cpp
new file mode 100644
index 0000000..812a717
--- /dev/null
+++ b/test/CodeGen/fp-contract-on-pragma.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -O3 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s
+
+// Is FP_CONTRACT honored in a simple case?
+float fp_contract_1(float a, float b, float c) {
+// CHECK: _Z13fp_contract_1fff
+// CHECK: tail call float @llvm.fmuladd
+#pragma clang fp contract(on)
+  return a * b + c;
+}
+
+// Is FP_CONTRACT state cleared on exiting compound statements?
+float fp_contract_2(float a, float b, float c) {
+  // CHECK: _Z13fp_contract_2fff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  {
+#pragma clang fp contract(on)
+  }
+  return a * b + c;
+}
+
+// Does FP_CONTRACT survive template instantiation?
+class Foo {};
+Foo operator+(Foo, Foo);
+
+template <typename T>
+T template_muladd(T a, T b, T c) {
+#pragma clang fp contract(on)
+  return a * b + c;
+}
+
+float fp_contract_3(float a, float b, float c) {
+  // CHECK: _Z13fp_contract_3fff
+  // CHECK: tail call float @llvm.fmuladd
+  return template_muladd<float>(a, b, c);
+}
+
+template <typename T>
+class fp_contract_4 {
+  float method(float a, float b, float c) {
+#pragma clang fp contract(on)
+    return a * b + c;
+  }
+};
+
+template class fp_contract_4<int>;
+// CHECK: _ZN13fp_contract_4IiE6methodEfff
+// CHECK: tail call float @llvm.fmuladd
+
+// Check file-scoped FP_CONTRACT
+#pragma clang fp contract(on)
+float fp_contract_5(float a, float b, float c) {
+  // CHECK: _Z13fp_contract_5fff
+  // CHECK: tail call float @llvm.fmuladd
+  return a * b + c;
+}
+
+#pragma clang fp contract(off)
+float fp_contract_6(float a, float b, float c) {
+  // CHECK: _Z13fp_contract_6fff
+  // CHECK: %[[M:.+]] = fmul float %a, %b
+  // CHECK-NEXT: fadd float %[[M]], %c
+  return a * b + c;
+}
+
+// If the multiply has multiple uses, don't produce fmuladd.
+// This used to assert (PR25719):
+// https://llvm.org/bugs/show_bug.cgi?id=25719
+
+float fp_contract_7(float a, float b, float c) {
+// CHECK: _Z13fp_contract_7fff
+// CHECK:  %[[M:.+]] = fmul float %b, 2.000000e+00
+// CHECK-NEXT: fsub float %[[M]], %c
+#pragma clang fp contract(on)
+  return (a = 2 * b) - c;
+}
diff --git a/test/CodeGen/lifetime2.c b/test/CodeGen/lifetime2.c
index 4374b3c..55c6d91 100644
--- a/test/CodeGen/lifetime2.c
+++ b/test/CodeGen/lifetime2.c
@@ -1,7 +1,7 @@
-// RUN: %clang -S -emit-llvm -o - -O2 %s | FileCheck %s -check-prefixes=CHECK,O2
-// RUN: %clang -S -emit-llvm -o - -O2 -Xclang -disable-lifetime-markers %s \
+// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-llvm-passes %s | FileCheck %s -check-prefixes=CHECK,O2
+// RUN: %clang_cc1 -S -emit-llvm -o - -O2 -disable-lifetime-markers %s \
 // RUN:       | FileCheck %s -check-prefixes=CHECK,O0
-// RUN: %clang -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
+// RUN: %clang_cc1 -S -emit-llvm -o - -O0 %s | FileCheck %s -check-prefixes=CHECK,O0
 
 extern int bar(char *A, int n);
 
@@ -25,13 +25,11 @@
   char x;
 l1:
   bar(&x, 1);
-  // O2: @llvm.lifetime.start(i64 5
-  // O2: @llvm.lifetime.end(i64 5
   char y[5];
   bar(y, 5);
   goto l1;
   // Infinite loop
-  // O2-NOT: @llvm.lifetime.end(i64 1
+  // O2-NOT: @llvm.lifetime.end(
 }
 
 // CHECK-LABEL: @goto_bypass
@@ -91,3 +89,27 @@
 L:
   bar(&x, 1);
 }
+
+// O2-LABEL: @jump_backward_over_declaration(
+// O2: %[[p:.*]] = alloca i32*
+// O2: %[[v0:.*]] = bitcast i32** %[[p]] to i8*
+// O2: call void @llvm.lifetime.start(i64 {{.*}}, i8* %[[v0]])
+// O2-NOT: call void @llvm.lifetime.start(
+
+extern void foo2(int p);
+
+int jump_backward_over_declaration(int a) {
+  int *p = 0;
+label1:
+  if (p) {
+    foo2(*p);
+    return 0;
+  }
+
+  int i = 999;
+  if (a != 2) {
+    p = &i;
+    goto label1;
+  }
+  return -1;
+}
diff --git a/test/CodeGen/sanitize-recover.c b/test/CodeGen/sanitize-recover.c
index dd8734e..cb2d09d 100644
--- a/test/CodeGen/sanitize-recover.c
+++ b/test/CodeGen/sanitize-recover.c
@@ -7,33 +7,22 @@
 void test() {
   extern volatile unsigned x, y, z;
 
-  // RECOVER: uadd.with.overflow.i32
-  // RECOVER: ubsan_handle_add_overflow(
+  // RECOVER: uadd.with.overflow.i32{{.*}}, !nosanitize
+  // RECOVER: ubsan_handle_add_overflow({{.*}}, !nosanitize
   // RECOVER-NOT: unreachable
-  // ABORT: uadd.with.overflow.i32
-  // ABORT: ubsan_handle_add_overflow_abort(
-  // ABORT: unreachable
+  // ABORT: uadd.with.overflow.i32{{.*}}, !nosanitize
+  // ABORT: ubsan_handle_add_overflow_abort({{.*}}, !nosanitize
+  // ABORT: unreachable{{.*}}, !nosanitize
   x = y + z;
 }
 
 void foo() {
   union { int i; } u;
   u.i=1;
-  // PARTIAL:      %[[CHECK0:.*]] = icmp ne {{.*}}* %[[PTR:.*]], null
-
   // PARTIAL:      %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false)
-  // PARTIAL-NEXT: %[[CHECK1:.*]] = icmp uge i64 %[[SIZE]], 4
+  // PARTIAL-NEXT: %[[CHECK0:.*]] = icmp uge i64 %[[SIZE]], 4
 
-  // PARTIAL:      %[[MISALIGN:.*]] = and i64 {{.*}}, 3
-  // PARTIAL-NEXT: %[[CHECK2:.*]] = icmp eq i64 %[[MISALIGN]], 0
+  // PARTIAL:      br i1 %[[CHECK0]], {{.*}} !nosanitize
 
-  // PARTIAL:      %[[CHECK02:.*]] = and i1 %[[CHECK0]], %[[CHECK2]]
-  // PARTIAL-NEXT: %[[CHECK012:.*]] = and i1 %[[CHECK02]], %[[CHECK1]]
-
-  // PARTIAL:      br i1 %[[CHECK012]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize
-
-  // PARTIAL:      br i1 %[[CHECK02]], {{.*}}
-  // PARTIAL:      call void @__ubsan_handle_type_mismatch_v1_abort(
-  // PARTIAL-NEXT: unreachable
   // PARTIAL:      call void @__ubsan_handle_type_mismatch_v1(
 }
diff --git a/test/CodeGen/sanitize-thread-no-checking-at-run-time.m b/test/CodeGen/sanitize-thread-no-checking-at-run-time.m
index 098b7cf..3d862c0 100644
--- a/test/CodeGen/sanitize-thread-no-checking-at-run-time.m
+++ b/test/CodeGen/sanitize-thread-no-checking-at-run-time.m
@@ -1,5 +1,7 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefix=TSAN %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -fblocks -emit-llvm -o - %s | FileCheck -check-prefix=WITHOUT %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -x objective-c++ -fblocks -emit-llvm -o - %s -fsanitize=thread | FileCheck -check-prefix=TSAN %s
+
+// WITHOUT-NOT: "sanitize_thread_no_checking_at_run_time"
 
 __attribute__((objc_root_class))
 @interface NSObject
@@ -26,9 +28,14 @@
 }
 @end
 
-// WITHOUT-NOT: "sanitize_thread_no_checking_at_run_time"
-
 // TSAN: initialize{{.*}}) [[ATTR:#[0-9]+]]
 // TSAN: dealloc{{.*}}) [[ATTR:#[0-9]+]]
 // TSAN: cxx_destruct{{.*}}) [[ATTR:#[0-9]+]]
+
+void test2(id x) {
+  extern void test2_helper(id (^)(void));
+  test2_helper(^{ return x; });
+// TSAN: define internal void @__destroy_helper_block_(i8*) [[ATTR:#[0-9]+]]
+}
+
 // TSAN: attributes [[ATTR]] = { noinline nounwind {{.*}} "sanitize_thread_no_checking_at_run_time" {{.*}} }
diff --git a/test/CodeGen/ubsan-null.c b/test/CodeGen/ubsan-null.c
new file mode 100644
index 0000000..2b7cd3e
--- /dev/null
+++ b/test/CodeGen/ubsan-null.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsanitize=null -emit-llvm %s -o - | FileCheck %s
+
+struct A {
+  int a[2];
+  int b;
+};
+
+// CHECK-LABEL: @f1
+int *f1() {
+// CHECK-NOT: __ubsan_handle_type_mismatch
+// CHECK: ret
+// CHECK-SAME: getelementptr inbounds (%struct.A, %struct.A* null, i32 0, i32 1)
+  return &((struct A *)0)->b;
+}
diff --git a/test/CodeGen/ubsan-promoted-arith.cpp b/test/CodeGen/ubsan-promoted-arith.cpp
new file mode 100644
index 0000000..5a2898b
--- /dev/null
+++ b/test/CodeGen/ubsan-promoted-arith.cpp
@@ -0,0 +1,131 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=signed-integer-overflow,unsigned-integer-overflow | FileCheck %s
+
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+typedef int int4 __attribute__((ext_vector_type(4)));
+
+enum E1 : int {
+  a
+};
+
+enum E2 : char {
+  b
+};
+
+// CHECK-LABEL: define signext i8 @_Z4add1
+// CHECK-NOT: sadd.with.overflow
+char add1(char c) { return c + c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4add2
+// CHECK-NOT: uadd.with.overflow
+uchar add2(uchar uc) { return uc + uc; }
+
+// CHECK-LABEL: define i32 @_Z4add3
+// CHECK: sadd.with.overflow
+int add3(E1 e) { return e + a; }
+
+// CHECK-LABEL: define signext i8 @_Z4add4
+// CHECK-NOT: sadd.with.overflow
+char add4(E2 e) { return e + b; }
+
+// CHECK-LABEL: define signext i8 @_Z4sub1
+// CHECK-NOT: ssub.with.overflow
+char sub1(char c) { return c - c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4sub2
+// CHECK-NOT: usub.with.overflow
+uchar sub2(uchar uc) { return uc - uc; }
+
+// CHECK-LABEL: define signext i8 @_Z4sub3
+// CHECK-NOT: ssub.with.overflow
+char sub3(char c) { return -c; }
+
+// Note: -INT_MIN can overflow.
+//
+// CHECK-LABEL: define i32 @_Z4sub4
+// CHECK: ssub.with.overflow
+int sub4(int i) { return -i; }
+
+// CHECK-LABEL: define signext i8 @_Z4mul1
+// CHECK-NOT: smul.with.overflow
+char mul1(char c) { return c * c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4mul2
+// CHECK-NOT: smul.with.overflow
+uchar mul2(uchar uc) { return uc * uc; }
+
+// Note: USHRT_MAX * USHRT_MAX can overflow.
+//
+// CHECK-LABEL: define zeroext i16 @_Z4mul3
+// CHECK: smul.with.overflow
+ushort mul3(ushort us) { return us * us; }
+
+// CHECK-LABEL: define i32 @_Z4mul4
+// CHECK: smul.with.overflow
+int mul4(int i, char c) { return i * c; }
+
+// CHECK-LABEL: define i32 @_Z4mul5
+// CHECK: smul.with.overflow
+int mul5(int i, char c) { return c * i; }
+
+// CHECK-LABEL: define signext i16 @_Z4mul6
+// CHECK-NOT: smul.with.overflow
+short mul6(short s) { return s * s; }
+
+// CHECK-LABEL: define signext i8 @_Z4div1
+// CHECK-NOT: ubsan_handle_divrem_overflow
+char div1(char c) { return c / c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4div2
+// CHECK-NOT: ubsan_handle_divrem_overflow
+uchar div2(uchar uc) { return uc / uc; }
+
+// CHECK-LABEL: define signext i8 @_Z4div3
+// CHECK-NOT: ubsan_handle_divrem_overflow
+char div3(char c, int i) { return c / i; }
+
+// CHECK-LABEL: define signext i8 @_Z4div4
+// CHECK: ubsan_handle_divrem_overflow
+char div4(int i, char c) { return i / c; }
+
+// Note: INT_MIN / -1 can overflow.
+//
+// CHECK-LABEL: define signext i8 @_Z4div5
+// CHECK: ubsan_handle_divrem_overflow
+char div5(int i, char c) { return i / c; }
+
+// CHECK-LABEL: define signext i8 @_Z4rem1
+// CHECK-NOT: ubsan_handle_divrem_overflow
+char rem1(char c) { return c % c; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4rem2
+// CHECK-NOT: ubsan_handle_divrem_overflow
+uchar rem2(uchar uc) { return uc % uc; }
+
+// CHECK-LABEL: define signext i8 @_Z4rem3
+// CHECK: ubsan_handle_divrem_overflow
+char rem3(int i, char c) { return i % c; }
+
+// CHECK-LABEL: define signext i8 @_Z4rem4
+// CHECK-NOT: ubsan_handle_divrem_overflow
+char rem4(char c, int i) { return c % i; }
+
+// CHECK-LABEL: define signext i8 @_Z4inc1
+// CHECK-NOT: sadd.with.overflow
+char inc1(char c) { return c++ + (char)0; }
+
+// CHECK-LABEL: define zeroext i8 @_Z4inc2
+// CHECK-NOT: uadd.with.overflow
+uchar inc2(uchar uc) { return uc++ + (uchar)0; }
+
+// CHECK-LABEL: define void @_Z4inc3
+// CHECK-NOT: sadd.with.overflow
+void inc3(char c) { c++; }
+
+// CHECK-LABEL: define void @_Z4inc4
+// CHECK-NOT: uadd.with.overflow
+void inc4(uchar uc) { uc++; }
+
+// CHECK-LABEL: define <4 x i32> @_Z4vremDv4_iS_
+// CHECK-NOT: ubsan_handle_divrem_overflow
+int4 vrem(int4 a, int4 b) { return a % b; }
diff --git a/test/CodeGen/ubsan-shift.c b/test/CodeGen/ubsan-shift.c
new file mode 100644
index 0000000..90c15d8
--- /dev/null
+++ b/test/CodeGen/ubsan-shift.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fsanitize=shift-exponent,shift-base -emit-llvm %s -o - | FileCheck %s
+
+// CHECK-LABEL: define i32 @f1
+int f1(int c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+  return 1 << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f2
+int f2(long c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 63, !nosanitize
+// CHECK: icmp ule i64 %{{.*}}, 31, !nosanitize
+  return 1 << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f3
+unsigned f3(unsigned c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+// CHECK: icmp ule i32 %{{.*}}, 31, !nosanitize
+  return 1U << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f4
+unsigned f4(unsigned long c, int shamt) {
+// CHECK: icmp ule i32 %{{.*}}, 63, !nosanitize
+// CHECK: icmp ule i64 %{{.*}}, 31, !nosanitize
+  return 1U << (c << shamt);
+}
+
+// CHECK-LABEL: define i32 @f5
+int f5(int c, long long shamt) {
+// CHECK: icmp ule i64 %{{[0-9]+}}, 31, !nosanitize
+//
+// CHECK: sub nuw nsw i32 31, %sh_prom, !nosanitize
+// CHECK: lshr i32 %{{.*}}, %shl.zeros, !nosanitize
+  return c << shamt;
+}
+
+// CHECK-LABEL: define i32 @f6
+int f6(int c, int shamt) {
+// CHECK: icmp ule i32 %[[WIDTH:.*]], 31, !nosanitize
+//
+// CHECK: sub nuw nsw i32 31, %[[WIDTH]], !nosanitize
+// CHECK: lshr i32 %{{.*}}, %shl.zeros, !nosanitize
+  return c << shamt;
+}
diff --git a/test/CodeGen/unsigned-promotion.c b/test/CodeGen/unsigned-promotion.c
index 4e7a442..4b13f68 100644
--- a/test/CodeGen/unsigned-promotion.c
+++ b/test/CodeGen/unsigned-promotion.c
@@ -7,53 +7,6 @@
 // RUN:   -fsanitize=unsigned-integer-overflow | FileCheck %s --check-prefix=CHECKU
 
 unsigned short si, sj, sk;
-unsigned char ci, cj, ck;
-
-extern void opaqueshort(unsigned short);
-extern void opaquechar(unsigned char);
-
-// CHECKS-LABEL:   define void @testshortadd()
-// CHECKU-LABEL: define void @testshortadd()
-void testshortadd() {
-  // CHECKS:        load i16, i16* @sj
-  // CHECKS:        load i16, i16* @sk
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_add_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i16, i16* @sj
-  // CHECKU:      [[T2:%.*]] = zext i16 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i16, i16* @sk
-  // CHECKU:      [[T4:%.*]] = zext i16 [[T3]]
-  // CHECKU-NOT:  llvm.sadd
-  // CHECKU-NOT:  llvm.uadd
-  // CHECKU:      [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
-
-  si = sj + sk;
-}
-
-// CHECKS-LABEL:   define void @testshortsub()
-// CHECKU-LABEL: define void @testshortsub()
-void testshortsub() {
-
-  // CHECKS:        load i16, i16* @sj
-  // CHECKS:        load i16, i16* @sk
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_sub_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i16, i16* @sj
-  // CHECKU:      [[T2:%.*]] = zext i16 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i16, i16* @sk
-  // CHECKU:      [[T4:%.*]] = zext i16 [[T3]]
-  // CHECKU-NOT:  llvm.ssub
-  // CHECKU-NOT:  llvm.usub
-  // CHECKU:      [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
-
-  si = sj - sk;
-}
 
 // CHECKS-LABEL:   define void @testshortmul()
 // CHECKU-LABEL: define void @testshortmul()
@@ -75,69 +28,3 @@
   // CHECKU:      [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
   si = sj * sk;
 }
-
-// CHECKS-LABEL:   define void @testcharadd()
-// CHECKU-LABEL: define void @testcharadd()
-void testcharadd() {
-
-  // CHECKS:        load i8, i8* @cj
-  // CHECKS:        load i8, i8* @ck
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_add_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i8, i8* @cj
-  // CHECKU:      [[T2:%.*]] = zext i8 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i8, i8* @ck
-  // CHECKU:      [[T4:%.*]] = zext i8 [[T3]]
-  // CHECKU-NOT:  llvm.sadd
-  // CHECKU-NOT:  llvm.uadd
-  // CHECKU:      [[T5:%.*]] = add nsw i32 [[T2]], [[T4]]
-
-  ci = cj + ck;
-}
-
-// CHECKS-LABEL:   define void @testcharsub()
-// CHECKU-LABEL: define void @testcharsub()
-void testcharsub() {
-
-  // CHECKS:        load i8, i8* @cj
-  // CHECKS:        load i8, i8* @ck
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_sub_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i8, i8* @cj
-  // CHECKU:      [[T2:%.*]] = zext i8 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i8, i8* @ck
-  // CHECKU:      [[T4:%.*]] = zext i8 [[T3]]
-  // CHECKU-NOT:  llvm.ssub
-  // CHECKU-NOT:  llvm.usub
-  // CHECKU:      [[T5:%.*]] = sub nsw i32 [[T2]], [[T4]]
-
-  ci = cj - ck;
-}
-
-// CHECKS-LABEL:   define void @testcharmul()
-// CHECKU-LABEL: define void @testcharmul()
-void testcharmul() {
-
-  // CHECKS:        load i8, i8* @cj
-  // CHECKS:        load i8, i8* @ck
-  // CHECKS:        [[T1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[T2:%.*]], i32 [[T3:%.*]])
-  // CHECKS-NEXT:   [[T4:%.*]] = extractvalue { i32, i1 } [[T1]], 0
-  // CHECKS-NEXT:   [[T5:%.*]] = extractvalue { i32, i1 } [[T1]], 1
-  // CHECKS:        call void @__ubsan_handle_mul_overflow
-  //
-  // CHECKU:      [[T1:%.*]] = load i8, i8* @cj
-  // CHECKU:      [[T2:%.*]] = zext i8 [[T1]]
-  // CHECKU:      [[T3:%.*]] = load i8, i8* @ck
-  // CHECKU:      [[T4:%.*]] = zext i8 [[T3]]
-  // CHECKU-NOT:  llvm.smul
-  // CHECKU-NOT:  llvm.umul
-  // CHECKU:      [[T5:%.*]] = mul nsw i32 [[T2]], [[T4]]
-
-  ci = cj * ck;
-}
diff --git a/test/CodeGen/vector.c b/test/CodeGen/vector.c
index ebaea84..2e36dcc 100644
--- a/test/CodeGen/vector.c
+++ b/test/CodeGen/vector.c
@@ -60,23 +60,3 @@
   extern __typeof(_mm_extract_epi16(_mm_setzero_si128(), 3)) check_result_int;
   extern __typeof(_mm_extract_epi32(_mm_setzero_si128(), 3)) check_result_int;
 }
-
-// Test some logic around our lax vector comparison rules with integers.
-
-typedef int vec_int1 __attribute__((vector_size(4)));
-vec_int1 lax_vector_compare1(int x, vec_int1 y) {
-  y = x == y;
-  return y;
-}
-
-// CHECK: define i32 @lax_vector_compare1(i32 {{.*}}, i32 {{.*}})
-// CHECK: icmp eq <1 x i32>
-
-typedef int vec_int2 __attribute__((vector_size(8)));
-vec_int2 lax_vector_compare2(long long x, vec_int2 y) {
-  y = x == y;
-  return y;
-}
-
-// CHECK: define void @lax_vector_compare2(<2 x i32>* {{.*sret.*}}, i64 {{.*}}, i64 {{.*}})
-// CHECK: icmp eq <2 x i32>
diff --git a/test/CodeGenCUDA/fp-contract.cu b/test/CodeGenCUDA/fp-contract.cu
index 070ebae..96de5c4 100644
--- a/test/CodeGenCUDA/fp-contract.cu
+++ b/test/CodeGenCUDA/fp-contract.cu
@@ -10,10 +10,10 @@
 // RUN:   -ffp-contract=fast -disable-llvm-passes -o - %s \
 // RUN:   | FileCheck -check-prefix ENABLED %s
 
-// Explicit -ffp-contract=on -- fusing by front-end (disabled).
+// Explicit -ffp-contract=on -- fusing by front-end.
 // RUN: %clang_cc1 -fcuda-is-device -triple nvptx-nvidia-cuda -S \
 // RUN:   -ffp-contract=on -disable-llvm-passes -o - %s \
-// RUN:   | FileCheck -check-prefix DISABLED %s
+// RUN:   | FileCheck -check-prefix ENABLED %s
 
 // Explicit -ffp-contract=off should disable instruction fusing.
 // RUN: %clang_cc1 -fcuda-is-device -triple nvptx-nvidia-cuda -S \
diff --git a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
new file mode 100644
index 0000000..e3708e2
--- /dev/null
+++ b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -debug-info-kind=standalone -std=c++11 -triple x86_64-darwin -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+  A(int, ...);
+};
+struct B : A {
+  using A::A;
+};
+
+A::A(int i, ...) {}
+// CHECK: define void @{{.*}}foo
+// CHECK-NOT ret void
+// CHECK: call void @llvm.dbg.declare
+// CHECK-NOT ret void
+// CHECK: call void @llvm.dbg.declare(metadata %{{.*}}** %{{[^,]+}},
+// CHECK-SAME: metadata ![[THIS:[0-9]+]], metadata !{{[0-9]+}}), !dbg ![[LOC:[0-9]+]]
+// CHECK: ret void, !dbg ![[NOINL:[0-9]+]]
+// CHECK: ![[FOO:.*]] = distinct !DISubprogram(name: "foo"
+// CHECK-DAG: ![[A:.*]] = distinct !DISubprogram(name: "A", linkageName: "_ZN1BCI11AEiz"
+void foo() {
+// CHECK-DAG: ![[LOC]] = !DILocation(line: 0, scope: ![[A]], inlinedAt: ![[INL:[0-9]+]])
+// CHECK-DAG: ![[INL]] = !DILocation(line: [[@LINE+1]], scope: ![[FOO]])
+  B b(0);
+// CHECK: ![[NOINL]] = !DILocation(line: [[@LINE+1]], scope: !{{[0-9]+}})
+}
diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp
index c75c407..95857e3 100644
--- a/test/CodeGenCXX/debug-info-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-namespace.cpp
@@ -53,24 +53,34 @@
 int var_i;
 }
 }
-void B::func_fwd() {}
+namespace {
+int anonymous;
+}
+void B::func_fwd() {
+  anonymous = 0;
+}
+
+namespace C {
+  void c();
+}
+void C::c() {}
 
 // This should work even if 'i' and 'func' were declarations & not definitions,
 // but it doesn't yet.
 
 // CHECK: [[I:![0-9]+]] = distinct !DIGlobalVariable(name: "i",{{.*}} scope: [[NS:![0-9]+]],
-// CHECK: [[NS]] = !DINamespace(name: "B", scope: [[CTXT:![0-9]+]], file: [[FOOCPP:![0-9]+]], line: 1)
-// CHECK: [[FOOCPP]] = !DIFile(filename: "foo.cpp"
-// CHECK: [[CTXT]] = !DINamespace(name: "A", scope: null, file: [[FILE:![0-9]+]], line: 5)
-// CHECK: [[FILE]] = !DIFile(filename: "{{.*}}debug-info-namespace.cpp",
+// CHECK: [[NS]] = !DINamespace(name: "B", scope: [[CTXT:![0-9]+]])
+// CHECK: [[CTXT]] = !DINamespace(name: "A", scope: null)
+// CHECK: [[FOOCPP:.*]] = !DIFile(filename: "foo.cpp"
 // CHECK: [[VAR_FWD:![0-9]+]] = distinct !DIGlobalVariable(name: "var_fwd",{{.*}} scope: [[NS]],
 // CHECK-SAME:                                             line: 44
 // CHECK-SAME:                                             isDefinition: true
 // CHECK: distinct !DIGlobalVariable(name: "var_i",{{.*}} scope: [[INLINE:![0-9]+]],
-// CHECK: [[INLINE]] = !DINamespace(name: "I", scope: [[CTXT]], file: [[FOOCPP]], line: 46, exportSymbols: true)
+// CHECK: [[INLINE]] = !DINamespace(name: "I", scope: [[CTXT]], exportSymbols: true)
+// CHECK: !DINamespace(scope: null)
 // CHECK: [[CU:![0-9]+]] = distinct !DICompileUnit(
 // CHECK-SAME:                            imports: [[MODULES:![0-9]*]]
-// CHECK: [[MODULES]] = !{[[M1:![0-9]+]], [[M2:![0-9]+]], [[M3:![0-9]+]], [[M4:![0-9]+]], [[M5:![0-9]+]], [[M6:![0-9]+]], [[M7:![0-9]+]], [[M8:![0-9]+]], [[M9:![0-9]+]], [[M10:![0-9]+]], [[M11:![0-9]+]], [[M12:![0-9]+]], [[M13:![0-9]+]], [[M14:![0-9]+]], [[M15:![0-9]+]], [[M16:![0-9]+]], [[M17:![0-9]+]]}
+// CHECK: [[MODULES]] = !{[[M1:![0-9]+]], [[M2:![0-9]+]], [[M3:![0-9]+]], [[M4:![0-9]+]], [[M5:![0-9]+]], [[M6:![0-9]+]], [[M7:![0-9]+]], [[M8:![0-9]+]], [[M9:![0-9]+]], [[M10:![0-9]+]], [[M11:![0-9]+]], [[M12:![0-9]+]], [[M13:![0-9]+]], [[M14:![0-9]+]], [[M15:![0-9]+]], [[M16:![0-9]+]], [[M17:![0-9]+]]
 // CHECK: [[M1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CTXT]], entity: [[NS]], line: 15)
 
 // CHECK: [[M2]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[CTXT]],
@@ -106,8 +116,10 @@
 // CHECK-SAME:                          scope: [[NS]], file: [[FOOCPP]], line: 9
 // CHECK: [[M15]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_FWD:![0-9]+]]
 // CHECK: [[M16]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_FWD:![0-9]+]]
-// CHECK: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 50,{{.*}} isDefinition: true
+// CHECK: [[FUNC_FWD]] = distinct !DISubprogram(name: "func_fwd",{{.*}} line: 53,{{.*}} isDefinition: true
 // CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]]
+// CHECK: distinct !DISubprogram(name: "c",{{.*}}, scope: ![[C:[0-9]+]],{{.*}}, line: 60,{{.*}} isDefinition: true
+// CHECK: ![[C]] = !DINamespace(name: "C",
 
 // CHECK-GMLT: [[CU:![0-9]+]] = distinct !DICompileUnit(
 // CHECK-GMLT-SAME:                            emissionKind: LineTablesOnly,
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 9575a51..2b86150 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -21,6 +21,7 @@
 
 // CHECK: ![[INCTYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "incomplete"
 // CHECK-SAME:                                   DIFlagFwdDecl
+// CHECK: ![[EXPR]] = !DIExpression()
 
 template<typename T> struct Identity {
   typedef T Type;
@@ -117,7 +118,6 @@
 // For some reason function arguments ended up down here
 // CHECK: ![[F]] = !DILocalVariable(name: "f", arg: 1, scope: ![[FUNC]]
 // CHECK-SAME:                      type: ![[FOO]]
-// CHECK: ![[EXPR]] = !DIExpression(DW_OP_deref)
 foo func(foo f) {
   return f; // reference 'f' for now because otherwise we hit another bug
 }
diff --git a/test/CodeGenCXX/explicit-instantiation.cpp b/test/CodeGenCXX/explicit-instantiation.cpp
index fb57118..85857fb 100644
--- a/test/CodeGenCXX/explicit-instantiation.cpp
+++ b/test/CodeGenCXX/explicit-instantiation.cpp
@@ -5,6 +5,9 @@
 // This check logically is attached to 'template int S<int>::i;' below.
 // CHECK: @_ZN1SIiE1iE = weak_odr global i32
 
+// This check is logically attached to 'template int ExportedStaticLocal::f<int>()' below.
+// CHECK-OPT: @_ZZN19ExportedStaticLocal1fIiEEvvE1i = linkonce_odr global
+
 template<typename T, typename U, typename Result>
 struct plus {
   Result operator()(const T& t, const U& u) const;
@@ -153,3 +156,17 @@
 template <typename T> void S<T>::g() {}
 template <typename T> int S<T>::i;
 template <typename T> void S<T>::S2::h() {}
+
+namespace ExportedStaticLocal {
+void sink(int&);
+template <typename T>
+inline void f() {
+  static int i;
+  sink(i);
+}
+// See the check line at the top of the file.
+extern template void f<int>();
+void use() {
+  f<int>();
+}
+}
diff --git a/test/CodeGenCXX/linetable-virtual-variadic.cpp b/test/CodeGenCXX/linetable-virtual-variadic.cpp
index 6f96641..cd746cd 100644
--- a/test/CodeGenCXX/linetable-virtual-variadic.cpp
+++ b/test/CodeGenCXX/linetable-virtual-variadic.cpp
@@ -12,8 +12,10 @@
 
 // CHECK: define void @_ZN7Derived16VariadicFunctionEz({{.*}} !dbg ![[SP:[0-9]+]]
 // CHECK: ret void, !dbg ![[LOC:[0-9]+]]
-// CHECK-LABEL: define void @_ZT{{.+}}N7Derived16VariadicFunctionEz(
-// CHECK: ret void, !dbg ![[LOC:[0-9]+]]
+// CHECK: define void @_ZT{{.+}}N7Derived16VariadicFunctionEz({{.*}} !dbg ![[SP_I:[0-9]+]]
+// CHECK: ret void, !dbg ![[LOC_I:[0-9]+]]
 //
 // CHECK: ![[SP]] = distinct !DISubprogram(name: "VariadicFunction"
 // CHECK: ![[LOC]] = !DILocation({{.*}}scope: ![[SP]])
+// CHECK: ![[SP_I]] = distinct !DISubprogram(name: "VariadicFunction"
+// CHECK: ![[LOC_I]] = !DILocation({{.*}}scope: ![[SP_I]])
diff --git a/test/CodeGenCXX/ubsan-bitfields.cpp b/test/CodeGenCXX/ubsan-bitfields.cpp
new file mode 100644
index 0000000..5595db0
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-bitfields.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=bool,enum | FileCheck %s
+
+enum E {
+  a = 1,
+  b = 2,
+  c = 3
+};
+
+struct S {
+  E e1 : 10;
+};
+
+// CHECK-LABEL: define i32 @_Z4loadP1S
+E load(S *s) {
+  // CHECK: [[LOAD:%.*]] = load i16, i16* {{.*}}
+  // CHECK: [[CLEAR:%.*]] = and i16 [[LOAD]], 1023
+  // CHECK: [[CAST:%.*]] = zext i16 [[CLEAR]] to i32
+  // CHECK: icmp ule i32 [[CAST]], 3, !nosanitize
+  // CHECK: call void @__ubsan_handle_load_invalid_value
+  return s->e1;
+}
+
+struct Bool {
+  bool b1 : 1;
+  bool b2 : 7;
+  bool b3 : 16;
+};
+
+// CHECK-LABEL: define zeroext i1 @_Z13load_cpp_boolP4Bool
+bool load_cpp_bool(Bool *b) {
+  // CHECK-NOT: call void @__ubsan_handle_load_invalid_value
+  // CHECK-NOT: !nosanitize
+  return b->b1 || b->b2 || b->b3;
+}
diff --git a/test/CodeGenCXX/ubsan-global-alignment.cpp b/test/CodeGenCXX/ubsan-global-alignment.cpp
new file mode 100644
index 0000000..67fcfd4
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-global-alignment.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s
+
+struct S {
+  int I;
+};
+
+extern S g_S;
+extern S array_S[];
+
+// CHECK-LABEL: define i32 @_Z18load_extern_global
+int load_extern_global() {
+  // FIXME: The IR builder constant-folds the alignment check away to 'true'
+  // here, so we never call the diagnostic. This is PR32630.
+  // CHECK-NOT: ptrtoint i32* {{.*}} to i32, !nosanitize
+  // CHECK: [[I:%.*]] = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @g_S, i32 0, i32 0), align 4
+  // CHECK-NEXT: ret i32 [[I]]
+  return g_S.I;
+}
+
+// CHECK-LABEL: define i32 @_Z22load_from_extern_array
+int load_from_extern_array(int I) {
+  // CHECK: [[I:%.*]] = getelementptr inbounds %struct.S, %struct.S* {{.*}}, i32 0, i32 0
+  // CHECK-NEXT: [[PTRTOINT:%.*]] = ptrtoint i32* [[I]] to i64, !nosanitize
+  // CHECK-NEXT: [[AND:%.*]] = and i64 [[PTRTOINT]], 3, !nosanitize
+  // CHECK-NEXT: [[ICMP:%.*]] = icmp eq i64 [[AND]], 0, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]]
+  // CHECK: call void @__ubsan_handle_type_mismatch
+  return array_S[I].I;
+}
diff --git a/test/CodeGenCXX/ubsan-nullability-assign.cpp b/test/CodeGenCXX/ubsan-nullability-assign.cpp
new file mode 100644
index 0000000..3f85c88
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-nullability-assign.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=nullability-assign | FileCheck %s
+
+struct S1 {
+  int *_Nonnull p;
+};
+
+struct S2 {
+  S1 s1;
+};
+
+union U1 {
+  S1 s1;
+  S2 s2;
+};
+
+// CHECK-LABEL: define void @{{.*}}f1
+void f1(int *p) {
+  U1 u;
+
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}} !nosanitize
+  // CHECK: store
+  u.s1.p = p;
+
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}} !nosanitize
+  // CHECK: store
+  u.s2.s1.p = p;
+
+  // CHECK-NOT: __ubsan_handle_type_mismatch
+  // CHECK-NOT: store
+  // CHECK: ret void
+}
diff --git a/test/CodeGenCXX/ubsan-suppress-checks.cpp b/test/CodeGenCXX/ubsan-suppress-checks.cpp
new file mode 100644
index 0000000..ae7c94b
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-suppress-checks.cpp
@@ -0,0 +1,232 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s --check-prefixes=CHECK,ALIGN
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s --check-prefixes=CHECK,NULL
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment,null -DCHECK_LAMBDA | FileCheck %s --check-prefixes=LAMBDA
+
+// CHECK-LABEL: define void @_Z22load_non_null_pointersv
+void load_non_null_pointers() {
+  int var;
+  var = *&var;
+
+  int arr[1];
+  arr[0] = arr[0];
+
+  char c = "foo"[0];
+
+  // CHECK-NOT: and i64 {{.*}}, !nosanitize
+  // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize
+  // CHECK: ret void
+}
+
+struct A {
+  int foo;
+
+  // CHECK-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv
+  void do_nothing() {
+    // ALIGN: %[[THISINT1:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[THISINT1]], 3, !nosanitize
+    // NULL: icmp ne %struct.A* %[[THIS1:[a-z0-9]+]], null, !nosanitize
+    // NULL: ptrtoint %struct.A* %[[THIS1]] to i64, !nosanitize
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    // CHECK: ret void
+  }
+
+#ifdef CHECK_LAMBDA
+  // LAMBDA-LABEL: define linkonce_odr void @_ZN1A22do_nothing_with_lambdaEv
+  void do_nothing_with_lambda() {
+    // LAMBDA: icmp ne %struct.A* %[[THIS2:[a-z0-9]+]], null, !nosanitize
+    // LAMBDA: %[[THISINT2:[0-9]+]] = ptrtoint %struct.A* %[[THIS2]] to i64, !nosanitize
+    // LAMBDA: and i64 %[[THISINT2]], 3, !nosanitize
+    // LAMBDA: call void @__ubsan_handle_type_mismatch
+
+    auto f = [&] {
+      foo = 0;
+    };
+    f();
+
+    // LAMBDA-NOT: call void @__ubsan_handle_type_mismatch
+    // LAMBDA: ret void
+  }
+
+// Check the IR for the lambda:
+//
+// LAMBDA-LABEL: define linkonce_odr void @_ZZN1A22do_nothing_with_lambdaEvENKUlvE_clEv
+// LAMBDA: call void @__ubsan_handle_type_mismatch
+// LAMBDA-NOT: call void @__ubsan_handle_type_mismatch
+// LAMBDA: ret void
+#endif
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1A11load_memberEv
+  int load_member() {
+    // ALIGN: %[[THISINT3:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[THISINT3]], 3, !nosanitize
+    // NULL: icmp ne %struct.A* %[[THIS3:[a-z0-9]+]], null, !nosanitize
+    // NULL: ptrtoint %struct.A* %[[THIS3]] to i64, !nosanitize
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return foo;
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1A11call_methodEv
+  int call_method() {
+    // ALIGN: %[[THISINT4:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[THISINT4]], 3, !nosanitize
+    // NULL: icmp ne %struct.A* %[[THIS4:[a-z0-9]+]], null, !nosanitize
+    // NULL: ptrtoint %struct.A* %[[THIS4]] to i64, !nosanitize
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return load_member();
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_1Ev
+  void assign_member_1() {
+    // ALIGN: %[[THISINT5:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[THISINT5]], 3, !nosanitize
+    // NULL: icmp ne %struct.A* %[[THIS5:[a-z0-9]+]], null, !nosanitize
+    // NULL: ptrtoint %struct.A* %[[THIS5]] to i64, !nosanitize
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    foo = 0;
+    // CHECK: ret void
+  }
+
+  // CHECK-LABEL: define linkonce_odr void @_ZN1A15assign_member_2Ev
+  void assign_member_2() {
+    // ALIGN: %[[THISINT6:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[THISINT6]], 3, !nosanitize
+    // NULL: icmp ne %struct.A* %[[THIS6:[a-z0-9]+]], null, !nosanitize
+    // NULL: ptrtoint %struct.A* %[[THIS6]] to i64, !nosanitize
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    (__extension__ (this))->foo = 0;
+    // CHECK: ret void
+  }
+
+  // CHECK-LABEL: define linkonce_odr void @_ZNK1A15assign_member_3Ev
+  void assign_member_3() const {
+    // ALIGN: %[[THISINT7:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[THISINT7]], 3, !nosanitize
+    // NULL: icmp ne %struct.A* %[[THIS7:[a-z0-9]+]], null, !nosanitize
+    // NULL: ptrtoint %struct.A* %[[THIS7]] to i64, !nosanitize
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    const_cast<A *>(this)->foo = 0;
+    // CHECK: ret void
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1A22call_through_referenceERS_
+  static int call_through_reference(A &a) {
+    // ALIGN: %[[OBJINT:[0-9]+]] = ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[OBJINT]], 3, !nosanitize
+    // ALIGN: call void @__ubsan_handle_type_mismatch
+    // NULL-NOT: call void @__ubsan_handle_type_mismatch
+    return a.load_member();
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1A20call_through_pointerEPS_
+  static int call_through_pointer(A *a) {
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    return a->load_member();
+    // CHECK: ret i32
+  }
+};
+
+struct B {
+  operator A*() const { return nullptr; }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEPS_
+  static int load_member(B *bp) {
+    // Check &b before converting it to an A*.
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    //
+    // Check the result of the conversion before using it.
+    // NULL: call void @__ubsan_handle_type_mismatch
+    //
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return static_cast<A *>(*bp)->load_member();
+    // CHECK: ret i32
+  }
+};
+
+struct Base {
+  int foo;
+
+  virtual int load_member_1() = 0;
+};
+
+struct Derived : public Base {
+  int bar;
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_2Ev
+  int load_member_2() {
+    // ALIGN: %[[THISINT8:[0-9]+]] = ptrtoint %struct.Derived* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[THISINT8]], 7, !nosanitize
+    // ALIGN: call void @__ubsan_handle_type_mismatch
+    // NULL: icmp ne %struct.Derived* %[[THIS8:[a-z0-9]+]], null, !nosanitize
+    // NULL: ptrtoint %struct.Derived* %[[THIS8]] to i64, !nosanitize
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    //
+    // Check the result of the cast before using it.
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    //
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return dynamic_cast<Base *>(this)->load_member_1();
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_3Ev
+  int load_member_3() {
+    // ALIGN: %[[THISINT9:[0-9]+]] = ptrtoint %struct.Derived* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[THISINT9]], 7, !nosanitize
+    // ALIGN: call void @__ubsan_handle_type_mismatch
+    // ALIGN: call void @__ubsan_handle_type_mismatch
+    // NULL: icmp ne %struct.Derived* %[[THIS9:[a-z0-9]+]], null, !nosanitize
+    // NULL: ptrtoint %struct.Derived* %[[THIS9]] to i64, !nosanitize
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return reinterpret_cast<Derived *>(static_cast<Base *>(this))->foo;
+    // CHECK: ret i32
+  }
+
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN7Derived13load_member_1Ev
+  int load_member_1() override {
+    // ALIGN: %[[THISINT10:[0-9]+]] = ptrtoint %struct.Derived* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %[[THISINT10]], 7, !nosanitize
+    // ALIGN: call void @__ubsan_handle_type_mismatch
+    // NULL: icmp ne %struct.Derived* %[[THIS10:[a-z0-9]+]], null, !nosanitize
+    // NULL: ptrtoint %struct.Derived* %[[THIS10]] to i64, !nosanitize
+    // CHECK: call void @__ubsan_handle_type_mismatch
+    // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+    return foo + bar;
+    // CHECK: ret i32
+  }
+};
+
+void force_irgen() {
+  A *a;
+  a->do_nothing();
+#ifdef CHECK_LAMBDA
+  a->do_nothing_with_lambda();
+#endif
+  a->load_member();
+  a->call_method();
+  a->assign_member_1();
+  a->assign_member_2();
+  a->assign_member_3();
+  A::call_through_reference(*a);
+  A::call_through_pointer(a);
+
+  B::load_member(nullptr);
+
+  Base *b = new Derived;
+  b->load_member_1();
+
+  Derived *d;
+  d->load_member_2();
+  d->load_member_3();
+
+  load_non_null_pointers();
+}
diff --git a/test/CodeGenCXX/ubsan-type-checks.cpp b/test/CodeGenCXX/ubsan-type-checks.cpp
new file mode 100644
index 0000000..786d049
--- /dev/null
+++ b/test/CodeGenCXX/ubsan-type-checks.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment | FileCheck %s -check-prefixes=ALIGN,COMMON
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s -check-prefixes=NULL,COMMON
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=object-size | FileCheck %s -check-prefixes=OBJSIZE,COMMON
+
+struct A {
+  // COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv
+  void do_nothing() {
+    // ALIGN-NOT: ptrtoint %struct.A* %{{.*}} to i64, !nosanitize
+ 
+    // NULL: icmp ne %struct.A* %{{.*}}, null, !nosanitize
+ 
+    // OBJSIZE-NOT: call i64 @llvm.objectsize
+  }
+};
+
+struct B {
+  int x;
+
+  // COMMON-LABEL: define linkonce_odr void @_ZN1B10do_nothingEv
+  void do_nothing() {
+    // ALIGN: ptrtoint %struct.B* %{{.*}} to i64, !nosanitize
+    // ALIGN: and i64 %{{.*}}, 3, !nosanitize
+
+    // NULL: icmp ne %struct.B* %{{.*}}, null, !nosanitize
+
+    // OBJSIZE-NOT: call i64 @llvm.objectsize
+  }
+};
+
+void force_irgen() {
+  A a;
+  a.do_nothing();
+
+  B b;
+  b.do_nothing();
+}
diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m
index f67136b..2913132 100644
--- a/test/CodeGenObjC/arc-blocks.m
+++ b/test/CodeGenObjC/arc-blocks.m
@@ -532,8 +532,6 @@
   // CHECK-NEXT: [[T0:%.*]] = load void ()*, void ()** [[B]]
   // CHECK-NEXT: [[T1:%.*]] = bitcast void ()* [[T0]] to i8*
   // CHECK-NEXT: call void @objc_release(i8* [[T1]])
-  // CHECK-NEXT: [[BPTR2:%.*]] = bitcast void ()** [[B]] to i8*
-  // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[BPTR2]])
 
   // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]]
   // CHECK-NEXT: br i1 [[T0]]
@@ -541,7 +539,9 @@
   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
   // CHECK-NEXT: br label
 
-  // CHECK:      [[T0:%.*]] = load i8*, i8** [[X]]
+  // CHECK:      [[BPTR2:%.*]] = bitcast void ()** [[B]] to i8*
+  // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[BPTR2]])
+  // CHECK-NEXT:      [[T0:%.*]] = load i8*, i8** [[X]]
   // CHECK-NEXT: call void @objc_release(i8* [[T0]])
   // CHECK-NEXT: ret void
 }
diff --git a/test/CodeGenObjC/availability-cf-link-guard.m b/test/CodeGenObjC/availability-cf-link-guard.m
new file mode 100644
index 0000000..918d13f
--- /dev/null
+++ b/test/CodeGenObjC/availability-cf-link-guard.m
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11 -emit-llvm -o - %s | FileCheck --check-prefixes=CHECK,CHECK_LINK_OPT %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11 -emit-llvm -o - -D USE_BUILTIN %s | FileCheck --check-prefixes=CHECK,CHECK_LINK_OPT %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11 -emit-llvm -o - -D DEF_CF %s | FileCheck --check-prefixes=CHECK_CF,CHECK_LINK_OPT %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.12 -emit-llvm -o - %s | FileCheck --check-prefix=CHECK_NO_GUARD %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux -emit-llvm -o - %s | FileCheck --check-prefix=CHECK_NO_GUARD %s
+
+#ifdef DEF_CF
+struct CFBundle;
+typedef struct CFBundle *CFBundleRef;
+unsigned CFBundleGetVersionNumber(CFBundleRef bundle);
+// CHECK_CF: declare i32 @CFBundleGetVersionNumber(%struct.CFBundle*)
+// CHECK_CF: @__clang_at_available_requires_core_foundation_framework
+// CHECK_CF-NEXT: call {{.*}}@CFBundleGetVersionNumber
+#endif
+
+void use_at_available() {
+#ifdef DEF_CF
+  CFBundleGetVersionNumber(0);
+#endif
+#ifdef USE_BUILTIN
+  if (__builtin_available(macos 10.12, *))
+    ;
+#else
+  if (@available(macos 10.12, *))
+    ;
+#endif
+}
+
+// CHECK: @llvm.compiler.used{{.*}}@__clang_at_available_requires_core_foundation_framework
+
+// CHECK: declare i32 @CFBundleGetVersionNumber(i8*)
+
+// CHECK-LABEL: linkonce hidden void @__clang_at_available_requires_core_foundation_framework
+// CHECK: call i32 @CFBundleGetVersionNumber(i8* null)
+// CHECK-NEXT: unreachable
+
+// CHECK_NO_GUARD-NOT: __clang_at_available_requires_core_foundation_framework
+// CHECK_NO_GUARD-NOT: CFBundleGetVersionNumber
+
+// CHECK_LINK_OPT: !"Linker Options", ![[OPTS:[0-9]+]]
+// CHECK_LINK_OPT: ![[OPTS]] = !{![[FRAMEWORK:[0-9]+]]
+// CHECK_LINK_OPT: ![[FRAMEWORK]] = !{!"-framework", !"CoreFoundation"}
+
+// CHECK_NO_GUARD-NOT: "Linker Options"
+// CHECK_NO_GUARD-NOT: CoreFoundation
diff --git a/test/CodeGenObjC/availability-check.m b/test/CodeGenObjC/availability-check.m
new file mode 100644
index 0000000..71c5ff7
--- /dev/null
+++ b/test/CodeGenObjC/availability-check.m
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11 -emit-llvm -o - %s | FileCheck %s
+
+void use_at_available() {
+  // CHECK: call i32 @__isOSVersionAtLeast(i32 10, i32 12, i32 0)
+  // CHECK-NEXT: icmp ne
+  if (__builtin_available(macos 10.12, *))
+    ;
+
+  // CHECK: call i32 @__isOSVersionAtLeast(i32 10, i32 12, i32 0)
+  // CHECK-NEXT: icmp ne
+  if (@available(macos 10.12, *))
+    ;
+
+  // CHECK: call i32 @__isOSVersionAtLeast(i32 10, i32 12, i32 42)
+  // CHECK-NEXT: icmp ne
+  if (__builtin_available(ios 10, macos 10.12.42, *))
+    ;
+
+  // CHECK-NOT: call i32 @__isOSVersionAtLeast
+  // CHECK: br i1 true
+  if (__builtin_available(ios 10, *))
+    ;
+
+  // This check should be folded: our deployment target is 10.11.
+  // CHECK-NOT: call i32 @__isOSVersionAtLeast
+  // CHECK: br i1 true
+  if (__builtin_available(macos 10.11, *))
+    ;
+}
+
+// CHECK: declare i32 @__isOSVersionAtLeast(i32, i32, i32)
diff --git a/test/CodeGenObjC/empty-collection-literals.m b/test/CodeGenObjC/empty-collection-literals.m
new file mode 100644
index 0000000..4b1d7f6
--- /dev/null
+++ b/test/CodeGenObjC/empty-collection-literals.m
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx10.10.0 -fobjc-runtime=macosx-10.10.0 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-WITHOUT-EMPTY-COLLECTIONS %s
+// RUN: %clang_cc1 -I %S/Inputs -triple x86_64-apple-macosx10.11.0 -fobjc-runtime=macosx-10.11.0 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-WITH-EMPTY-COLLECTIONS %s
+
+// RUN: %clang_cc1 -I %S/Inputs -triple arm64-apple-ios8.0 -fobjc-runtime=ios-8.0 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-WITHOUT-EMPTY-COLLECTIONS %s
+// RUN: %clang_cc1 -I %S/Inputs -triple arm64-apple-ios9.0 -fobjc-runtime=ios-9.0 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-WITH-EMPTY-COLLECTIONS %s
+
+// RUN: %clang_cc1 -I %S/Inputs -triple armv7k-apple-watchos2.0 -fobjc-runtime=watchos-1.0 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-WITHOUT-EMPTY-COLLECTIONS %s
+// RUN: %clang_cc1 -I %S/Inputs -triple armv7k-apple-watchos2.0 -fobjc-runtime=watchos-2.0 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-WITH-EMPTY-COLLECTIONS %s
+
+// RUN: %clang_cc1 -I %S/Inputs -triple arm64-apple-tvos8.0 -fobjc-runtime=ios-8.0 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-WITHOUT-EMPTY-COLLECTIONS %s
+// RUN: %clang_cc1 -I %S/Inputs -triple arm64-apple-tvos9.0 -fobjc-runtime=ios-9.0 -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=CHECK-WITH-EMPTY-COLLECTIONS %s
+
+#include "literal-support.h"
+
+void test_empty_array() {
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS-LABEL: define void @test_empty_array
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*objc_msgSend}}
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*objc_retainAutoreleasedReturnValue}}
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS: ret void
+
+  // CHECK-WITH-EMPTY-COLLECTIONS-LABEL: define void @test_empty_array
+  // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITH-EMPTY-COLLECTIONS: load {{.*}} @__NSArray0__
+  // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITH-EMPTY-COLLECTIONS: {{call.*objc_retain\(}}
+  // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITH-EMPTY-COLLECTIONS: call void @objc_storeStrong
+  // CHECK-WITH-EMPTY-COLLECTIONS-NEXT: ret void
+  NSArray *arr = @[];
+}
+
+void test_empty_dictionary() {
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS-LABEL: define void @test_empty_dictionary
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*objc_msgSend}}
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS: {{call.*objc_retainAutoreleasedReturnValue}}
+  // CHECK-WITHOUT-EMPTY-COLLECTIONS: ret void
+
+  // CHECK-WITH-EMPTY-COLLECTIONS-LABEL: define void @test_empty_dictionary
+  // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITH-EMPTY-COLLECTIONS: load {{.*}} @__NSDictionary0__{{.*}}!invariant.load
+  // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITH-EMPTY-COLLECTIONS: {{call.*objc_retain\(}}
+  // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void
+  // CHECK-WITH-EMPTY-COLLECTIONS: call void @objc_storeStrong
+  // CHECK-WITH-EMPTY-COLLECTIONS-NEXT: ret void
+  NSDictionary *dict = @{};
+}
diff --git a/test/CodeGenObjC/ubsan-bool.m b/test/CodeGenObjC/ubsan-bool.m
index 6d6c083..b30562c 100644
--- a/test/CodeGenObjC/ubsan-bool.m
+++ b/test/CodeGenObjC/ubsan-bool.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,OBJC
-// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,OBJC
+// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC
+// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - -w | FileCheck %s -check-prefixes=SHARED,OBJC
 // RUN: %clang_cc1 -x c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=bool %s -o - | FileCheck %s -check-prefixes=SHARED,C
 
 typedef signed char BOOL;
@@ -10,4 +10,57 @@
   // C-NOT: call void @__ubsan_handle_load_invalid_value
   BOOL a = 2;
   return a + 1;
+  // SHARED: ret i8
 }
+
+struct S1 {
+  BOOL b1 : 1;
+};
+
+// SHARED-LABEL: f2
+BOOL f2(struct S1 *s) {
+  // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}}
+  // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7
+  // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7
+  // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize
+  // OBJC: call void @__ubsan_handle_load_invalid_value
+
+  // C-NOT: call void @__ubsan_handle_load_invalid_value
+  return s->b1;
+  // SHARED: ret i8
+}
+
+#ifdef __OBJC__
+@interface I1 {
+@public
+  BOOL b1 : 1;
+}
+@property (nonatomic) BOOL b1;
+@end
+@implementation I1
+@synthesize b1;
+@end
+
+// Check the synthesized getter.
+// OBJC-LABEL: define internal signext i8 @"\01-[I1 b1]"
+// OBJC: [[IVAR:%.*]] = load i64, i64* @"OBJC_IVAR_$_I1.b1"
+// OBJC: [[ADDR:%.*]] = getelementptr inbounds i8, i8* {{.*}}, i64 [[IVAR]]
+// OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}}
+// OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7
+// OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7
+// OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize
+// OBJC: call void @__ubsan_handle_load_invalid_value
+
+// Also check direct accesses to the ivar.
+// OBJC-LABEL: f3
+BOOL f3(I1 *i) {
+  // OBJC: [[LOAD:%.*]] = load i8, i8* {{.*}}
+  // OBJC: [[SHL:%.*]] = shl i8 [[LOAD]], 7
+  // OBJC: [[ASHR:%.*]] = ashr i8 [[SHL]], 7
+  // OBJC: icmp ule i8 [[ASHR]], 1, !nosanitize
+  // OBJC: call void @__ubsan_handle_load_invalid_value
+
+  return i->b1;
+  // OBJC: ret i8
+}
+#endif /* __OBJC__ */
diff --git a/test/CodeGenObjC/ubsan-nonnull-and-nullability.m b/test/CodeGenObjC/ubsan-nonnull-and-nullability.m
new file mode 100644
index 0000000..b927f55
--- /dev/null
+++ b/test/CodeGenObjC/ubsan-nonnull-and-nullability.m
@@ -0,0 +1,31 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-return,returns-nonnull-attribute,nullability-arg,nonnull-attribute %s -o - -w | FileCheck %s
+
+// If both the annotation and the attribute are present, prefer the attribute,
+// since it actually affects IRGen.
+
+// CHECK-LABEL: define nonnull i32* @f1
+__attribute__((returns_nonnull)) int *_Nonnull f1(int *_Nonnull p) {
+  // CHECK: entry:
+  // CHECK-NEXT: [[ADDR:%.*]] = alloca i32*
+  // CHECK-NEXT: store i32* [[P:%.*]], i32** [[ADDR]]
+  // CHECK-NEXT: [[ARG:%.*]] = load i32*, i32** [[ADDR]]
+  // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* [[ARG]], null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], label %[[CONT:.+]], label %[[HANDLE:[^,]+]]
+  // CHECK: [[HANDLE]]:
+  // CHECK-NEXT:   call void @__ubsan_handle_nonnull_return_abort
+  // CHECK-NEXT:   unreachable, !nosanitize
+  // CHECK: [[CONT]]:
+  // CHECK-NEXT:   ret i32*
+  return p;
+}
+
+// CHECK-LABEL: define void @f2
+void f2(int *_Nonnull __attribute__((nonnull)) p) {}
+
+// CHECK-LABEL: define void @call_f2
+void call_f2() {
+  // CHECK: call void @__ubsan_handle_nonnull_arg_abort
+  // CHECK-NOT: call void @__ubsan_handle_nonnull_arg_abort
+  f2((void *)0);
+}
diff --git a/test/CodeGenObjC/ubsan-nonnull.m b/test/CodeGenObjC/ubsan-nonnull.m
new file mode 100644
index 0000000..cc0850c
--- /dev/null
+++ b/test/CodeGenObjC/ubsan-nonnull.m
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nonnull-attribute %s -o - -w | FileCheck %s
+
+@interface A
+
+-(void) one_arg: (__attribute__((nonnull)) int *) arg1;
+
+-(void) varargs: (__attribute__((nonnull)) int *) arg1, ...;
+
++(void) clsmethod: (__attribute__((nonnull)) int *) arg1;
+
+@end
+
+@implementation A
+
+// CHECK-LABEL: define internal void @"\01-[A one_arg:]"
+// CHECK-SAME: i32* nonnull
+-(void) one_arg: (__attribute__((nonnull)) int *) arg1 {}
+
+// CHECK-LABEL: define internal void @"\01-[A varargs:]"
+// CHECK-SAME: i32* nonnull
+-(void) varargs: (__attribute__((nonnull)) int *) arg1, ... {}
+
+// CHECK-LABEL: define internal void @"\01+[A clsmethod:]"
+// CHECK-SAME: i32* nonnull
++(void) clsmethod: (__attribute__((nonnull)) int *) arg1 {}
+
+@end
+
+// CHECK-LABEL: define void @call_A
+void call_A(A *a, int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
+  // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
+  // CHECK: call void {{.*}} @objc_msgSend {{.*}} ({{.*}}, i32* [[P1]])
+  [a one_arg: p];
+
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], null, !nosanitize
+  // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
+  // CHECK: call void {{.*}} @objc_msgSend {{.*}} ({{.*}}, i32* [[P2]], {{.*}})
+  [a varargs: p, p];
+
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P3:%.*]], null, !nosanitize
+  // CHECK: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nonnull_arg{{.*}} !nosanitize
+  // CHECK: call void {{.*}} @objc_msgSend {{.*}} ({{.*}}, i32* [[P3]])
+  [A clsmethod: p];
+}
diff --git a/test/CodeGenObjC/ubsan-nullability.m b/test/CodeGenObjC/ubsan-nullability.m
new file mode 100644
index 0000000..7f53ea6
--- /dev/null
+++ b/test/CodeGenObjC/ubsan-nullability.m
@@ -0,0 +1,186 @@
+// REQUIRES: asserts
+// RUN: %clang_cc1 -x objective-c -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
+// RUN: %clang_cc1 -x objective-c++ -emit-llvm -triple x86_64-apple-macosx10.10.0 -fsanitize=nullability-arg,nullability-assign,nullability-return -w %s -o - | FileCheck %s
+
+// CHECK: [[NONNULL_RV_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 109, i32 1 {{.*}} i32 100, i32 6
+// CHECK: [[NONNULL_ARG_LOC:@.*]] = private unnamed_addr global {{.*}} i32 204, i32 15 {{.*}} i32 190, i32 23
+// CHECK: [[NONNULL_ASSIGN1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 305, i32 9
+// CHECK: [[NONNULL_ASSIGN2_LOC:@.*]] = private unnamed_addr global {{.*}} i32 405, i32 10
+// CHECK: [[NONNULL_ASSIGN3_LOC:@.*]] = private unnamed_addr global {{.*}} i32 506, i32 10
+// CHECK: [[NONNULL_INIT1_LOC:@.*]] = private unnamed_addr global {{.*}} i32 604, i32 25
+// CHECK: [[NONNULL_INIT2_LOC1:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 26
+// CHECK: [[NONNULL_INIT2_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 707, i32 29
+// CHECK: [[NONNULL_RV_LOC2:@.*]] = private unnamed_addr global {{.*}} i32 817, i32 1 {{.*}} i32 800, i32 6
+
+#define NULL ((void *)0)
+#define INULL ((int *)NULL)
+#define INNULL ((int *_Nonnull)NULL)
+
+// CHECK-LABEL: define i32* @{{.*}}nonnull_retval1
+#line 100
+int *_Nonnull nonnull_retval1(int *p) {
+  // CHECK: br i1 true, label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
+  // CHECK: [[NULL]]:
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC1]]
+  return p;
+  // CHECK: [[NONULL]]:
+  // CHECK-NEXT: ret i32*
+}
+
+#line 190
+void nonnull_arg(int *_Nonnull p) {}
+
+// CHECK-LABEL: define void @{{.*}}call_func_with_nonnull_arg
+#line 200
+void call_func_with_nonnull_arg(int *_Nonnull p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nullability_arg{{.*}}[[NONNULL_ARG_LOC]]
+  nonnull_arg(p);
+}
+
+// CHECK-LABEL: define void @{{.*}}nonnull_assign1
+#line 300
+void nonnull_assign1(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN1_LOC]]
+  int *_Nonnull local;
+  local = p;
+}
+
+// CHECK-LABEL: define void @{{.*}}nonnull_assign2
+#line 400
+void nonnull_assign2(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN2_LOC]]
+  int *_Nonnull arr[1];
+  arr[0] = p;
+}
+
+struct S1 {
+  int *_Nonnull mptr;
+};
+
+// CHECK-LABEL: define void @{{.*}}nonnull_assign3
+#line 500
+void nonnull_assign3(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_ASSIGN3_LOC]]
+  // CHECK-NOT: call void @__ubsan_handle_type_mismatch
+  struct S1 s;
+  s.mptr = p;
+}
+
+// CHECK-LABEL: define void @{{.*}}nonnull_init1
+#line 600
+void nonnull_init1(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT1_LOC]]
+  int *_Nonnull local = p;
+}
+
+// CHECK-LABEL: define void @{{.*}}nonnull_init2
+#line 700
+void nonnull_init2(int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC1]]
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* %{{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_type_mismatch{{.*}}[[NONNULL_INIT2_LOC2]]
+  int *_Nonnull arr[] = {p, p};
+}
+
+// CHECK-LABEL: define i32* @{{.*}}nonnull_retval2
+#line 800
+int *_Nonnull nonnull_retval2(int *_Nonnull arg1,  //< Test this.
+                              int *_Nonnull arg2,  //< Test this.
+                              int *_Nullable arg3, //< Don't test the rest.
+                              int *arg4,
+                              int arg5, ...) {
+  // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
+  // CHECK-NEXT: [[DO_RV_CHECK_1:%.*]] = and i1 true, [[ARG1CMP]], !nosanitize
+  // CHECK: [[ARG2CMP:%.*]] = icmp ne i32* %arg2, null, !nosanitize
+  // CHECK-NEXT: [[DO_RV_CHECK_2:%.*]] = and i1 [[DO_RV_CHECK_1]], [[ARG2CMP]]
+  // CHECK: br i1 [[DO_RV_CHECK_2]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
+  // CHECK: [[NULL]]:
+  // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nullability_return{{.*}}[[NONNULL_RV_LOC2]]
+  return arg1;
+  // CHECK: [[NONULL]]:
+  // CHECK-NEXT: ret i32*
+}
+
+@interface A
++(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1;
+-(int *_Nonnull) objc_method: (int *_Nonnull) arg1;
+@end
+
+@implementation A
+
+// CHECK-LABEL: define internal i32* @"\01+[A objc_clsmethod:]"
++(int *_Nonnull) objc_clsmethod: (int *_Nonnull) arg1 {
+  // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
+  // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
+  // CHECK: br i1 [[DO_RV_CHECK]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
+  // CHECK: [[NULL]]:
+  // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
+  return arg1;
+  // CHECK: [[NONULL]]:
+  // CHECK-NEXT: ret i32*
+}
+
+// CHECK-LABEL: define internal i32* @"\01-[A objc_method:]"
+-(int *_Nonnull) objc_method: (int *_Nonnull) arg1 {
+  // CHECK: [[ARG1CMP:%.*]] = icmp ne i32* %arg1, null, !nosanitize
+  // CHECK-NEXT: [[DO_RV_CHECK:%.*]] = and i1 true, [[ARG1CMP]]
+  // CHECK: br i1 [[DO_RV_CHECK]], label %[[NULL:.*]], label %[[NONULL:.*]], !nosanitize
+  // CHECK: [[NULL]]:
+  // CHECK-NEXT: [[ICMP:%.*]] = icmp ne i32* {{.*}}, null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nullability_return{{.*}}
+  return arg1;
+  // CHECK: [[NONULL]]:
+  // CHECK-NEXT: ret i32*
+}
+@end
+
+// CHECK-LABEL: define void @{{.*}}call_A
+void call_A(A *a, int *p) {
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P1:%.*]], null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
+  // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P1]])
+  [a objc_method: p];
+
+  // CHECK: [[ICMP:%.*]] = icmp ne i32* [[P2:%.*]], null, !nosanitize
+  // CHECK-NEXT: br i1 [[ICMP]], {{.*}}, !nosanitize
+  // CHECK: call void @__ubsan_handle_nullability_arg{{.*}} !nosanitize
+  // CHECK: call i32* {{.*}} @objc_msgSend to i32* {{.*}}({{.*}}, i32* [[P2]])
+  [A objc_clsmethod: p];
+}
+
+void dont_crash(int *_Nonnull p, ...) {}
+
+int main() {
+  nonnull_retval1(INULL);
+  nonnull_retval2(INNULL, INNULL, INULL, (int *_Nullable)NULL, 0, 0, 0, 0);
+  call_func_with_nonnull_arg(INNULL);
+  nonnull_assign1(INULL);
+  nonnull_assign2(INULL);
+  nonnull_assign3(INULL);
+  nonnull_init1(INULL);
+  nonnull_init2(INULL);
+  call_A((A *)NULL, INULL);
+  dont_crash(INNULL, NULL);
+  return 0;
+}
diff --git a/test/CodeGenObjCXX/arc-references.mm b/test/CodeGenObjCXX/arc-references.mm
index c62df4e..791c275 100644
--- a/test/CodeGenObjCXX/arc-references.mm
+++ b/test/CodeGenObjCXX/arc-references.mm
@@ -21,7 +21,7 @@
   // CHECK: call void @_Z6calleev
   callee();
   // CHECK: call void @objc_release
-  // CHECK-NEXT: ret
+  // CHECK: ret
 }
 
 // No lifetime extension when we're binding a reference to an lvalue.
@@ -44,9 +44,9 @@
   const __weak id &ref = strong_id();
   // CHECK-NEXT: call void @_Z6calleev()
   callee();
+  // CHECK-NEXT: call void @objc_destroyWeak
   // CHECK-NEXT: [[PTR:%.*]] = bitcast i8*** [[REF]] to i8*
   // CHECK-NEXT: call void @llvm.lifetime.end(i64 8, i8* [[PTR]])
-  // CHECK-NEXT: call void @objc_destroyWeak
   // CHECK-NEXT: ret void
 }
 
diff --git a/test/CodeGenObjCXX/lambda-expressions.mm b/test/CodeGenObjCXX/lambda-expressions.mm
index 7ac7a21..c8247e2 100644
--- a/test/CodeGenObjCXX/lambda-expressions.mm
+++ b/test/CodeGenObjCXX/lambda-expressions.mm
@@ -71,6 +71,10 @@
 // ARC:   %[[CAPTURE1:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %[[BLOCK]], i32 0, i32 5
 // ARC:   store i32 %{{.*}}, i32* %[[CAPTURE1]]
 
+// ARC-LABEL: define internal void @"_ZZ10-[Foo foo]ENK3$_4clEv"(
+// ARC-NOT: @objc_storeStrong(
+// ARC: ret void
+
 // ARC: define internal void @"___ZZN13LambdaCapture4foo1ERiENK3$_3clEv_block_invoke"
 // ARC:   %[[CAPTURE2:.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, i32 }>* %{{.*}}, i32 0, i32 5
 // ARC:   store i32 %{{.*}}, i32* %[[CAPTURE2]]
@@ -124,6 +128,15 @@
   };
 }
 
+@interface NSObject @end
+@interface Foo : NSObject @end
+@implementation Foo
+- (void)foo {
+  [&] {
+    ^{ (void)self; }();
+  }();
+}
+@end
 
 // ARC: attributes [[NUW]] = { noinline nounwind{{.*}} }
 // MRC: attributes [[NUW]] = { noinline nounwind{{.*}} }
diff --git a/test/CodeGenObjCXX/lambda-to-block.mm b/test/CodeGenObjCXX/lambda-to-block.mm
new file mode 100644
index 0000000..a8d0718
--- /dev/null
+++ b/test/CodeGenObjCXX/lambda-to-block.mm
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -x objective-c++ -fblocks -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -std=c++1z -emit-llvm -o - %s | FileCheck %s
+
+// rdar://31385153
+// Shouldn't crash!
+
+void takesBlock(void (^)(void));
+
+struct Copyable {
+  Copyable(const Copyable &x);
+};
+
+void hasLambda(Copyable x) {
+  takesBlock([x] () { });
+}
+// CHECK-LABEL: define internal void @__copy_helper_block_
+// CHECK: call void @"_ZZ9hasLambda8CopyableEN3$_0C1ERKS0_"
+// CHECK-LABEL: define internal void @"_ZZ9hasLambda8CopyableEN3$_0C2ERKS0_"
+// CHECK: call void @_ZN8CopyableC1ERKS_
diff --git a/test/CodeGenObjCXX/objc-weak.mm b/test/CodeGenObjCXX/objc-weak.mm
new file mode 100644
index 0000000..68c2d46
--- /dev/null
+++ b/test/CodeGenObjCXX/objc-weak.mm
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fblocks -fobjc-weak -fobjc-runtime-has-weak -std=c++11 -o - %s | FileCheck %s
+
+struct A { __weak id x; };
+
+id test0() {
+  A a;
+  A b = a;
+  A c(static_cast<A&&>(b));
+  a = c;
+  c = static_cast<A&&>(a);
+  return c.x;
+}
+
+// Copy Assignment Operator
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.A* @_ZN1AaSERKS_(
+// CHECK:       [[THISADDR:%this.*]] = alloca [[A:.*]]*
+// CHECK:       [[OBJECTADDR:%.*]] = alloca [[A:.*]]*
+// CHECK:       [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]]
+// CHECK:       [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]]
+// CHECK:       [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0
+// CHECK-NEXT:  [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[T0]])
+// CHECK-NEXT:  [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0
+// CHECK-NEXT:  [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]])
+
+// Move Assignment Operator
+// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.A* @_ZN1AaSEOS_(
+// CHECK:       [[THISADDR:%this.*]] = alloca [[A:.*]]*
+// CHECK:       [[OBJECTADDR:%.*]] = alloca [[A:.*]]*
+// CHECK:       [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]]
+// CHECK:       [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]]
+// CHECK:       [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0
+// CHECK-NEXT:  [[T1:%.*]] = call i8* @objc_loadWeak(i8** [[T0]])
+// CHECK-NEXT:  [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0
+// CHECK-NEXT:  [[T3:%.*]] = call i8* @objc_storeWeak(i8** [[T2]], i8* [[T1]])
+
+// Default Constructor
+// CHECK-LABEL: define linkonce_odr void @_ZN1AC2Ev(
+// CHECK:       [[THISADDR:%this.*]] = alloca [[A:.*]]*
+// CHECK:       [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]]
+// CHECK:       [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0
+// CHECK-NEXT:  store i8* null, i8** [[T0]]
+
+// Copy Constructor
+// CHECK-LABEL: define linkonce_odr void @_ZN1AC2ERKS_(
+// CHECK:       [[THISADDR:%this.*]] = alloca [[A:.*]]*
+// CHECK:       [[OBJECTADDR:%.*]] = alloca [[A:.*]]*
+// CHECK:       [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]]
+// CHECK:       [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0
+// CHECK-NEXT:  [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]]
+// CHECK-NEXT:  [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0
+// CHECK-NEXT:  call void @objc_copyWeak(i8** [[T0]], i8** [[T1]])
+
+// Move Constructor
+// CHECK-LABEL: define linkonce_odr void @_ZN1AC2EOS_(
+// CHECK:       [[THISADDR:%this.*]] = alloca [[A:.*]]*
+// CHECK:       [[OBJECTADDR:%.*]] = alloca [[A:.*]]*
+// CHECK:       [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]]
+// CHECK:       [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0
+// CHECK-NEXT:  [[OBJECT:%.*]] = load [[A]]*, [[A]]** [[OBJECTADDR]]
+// CHECK-NEXT:  [[T1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OBJECT]], i32 0, i32 0
+// CHECK-NEXT:  call void @objc_moveWeak(i8** [[T0]], i8** [[T1]])
+
+// Destructor
+// CHECK-LABEL: define linkonce_odr void @_ZN1AD2Ev(
+// CHECK:       [[THISADDR:%this.*]] = alloca [[A:.*]]*
+// CHECK:       [[THIS:%this.*]] = load [[A]]*, [[A]]** [[THISADDR]]
+// CHECK-NEXT:  [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 0
+// CHECK-NEXT:  call void @objc_destroyWeak(i8** [[T0]])
+
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl b/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
new file mode 100644
index 0000000..c0b3009
--- /dev/null
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
@@ -0,0 +1,125 @@
+// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa -mcpu=fiji -o - %s | FileCheck %s
+
+// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_NONE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}})
+// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_LOCAL:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 2)
+// CHECK-DAG: ![[DWARF_ADDRESS_SPACE_PRIVATE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !{{[0-9]+}}, size: {{[0-9]+}}, dwarfAddressSpace: 1)
+
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+global int *FileVar0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+constant int *FileVar1;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: false, isDefinition: true)
+local int *FileVar2;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: false, isDefinition: true)
+private int *FileVar3;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+int *FileVar4;
+
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+global int *global FileVar5;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+constant int *global FileVar6;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: false, isDefinition: true)
+local int *global FileVar7;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: false, isDefinition: true)
+private int *global FileVar8;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+int *global FileVar9;
+
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+global int *constant FileVar10 = 0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+constant int *constant FileVar11 = 0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: false, isDefinition: true)
+local int *constant FileVar12 = 0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: false, isDefinition: true)
+private int *constant FileVar13 = 0;
+// CHECK-DAG: distinct !DIGlobalVariable(name: "FileVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: false, isDefinition: true)
+int *constant FileVar14 = 0;
+
+kernel void kernel1(
+    // CHECK-DAG: !DILocalVariable(name: "KernelArg0", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+    global int *KernelArg0,
+    // CHECK-DAG: !DILocalVariable(name: "KernelArg1", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+    constant int *KernelArg1,
+    // CHECK-DAG: !DILocalVariable(name: "KernelArg2", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
+    local int *KernelArg2) {
+  private int *Tmp0;
+  int *Tmp1;
+
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  global int *FuncVar0 = KernelArg0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  constant int *FuncVar1 = KernelArg1;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
+  local int *FuncVar2 = KernelArg2;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]])
+  private int *FuncVar3 = Tmp0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  int *FuncVar4 = Tmp1;
+
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  global int *constant FuncVar5 = KernelArg0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  constant int *constant FuncVar6 = KernelArg1;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
+  local int *constant FuncVar7 = KernelArg2;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]])
+  private int *constant FuncVar8 = Tmp0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  int *constant FuncVar9 = Tmp1;
+
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+  global int *local FuncVar10; FuncVar10 = KernelArg0;
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+  constant int *local FuncVar11; FuncVar11 = KernelArg1;
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: true, isDefinition: true)
+  local int *local FuncVar12; FuncVar12 = KernelArg2;
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: true, isDefinition: true)
+  private int *local FuncVar13; FuncVar13 = Tmp0;
+  // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+  int *local FuncVar14; FuncVar14 = Tmp1;
+
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar15", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  global int *private FuncVar15 = KernelArg0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar16", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  constant int *private FuncVar16 = KernelArg1;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar17", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
+  local int *private FuncVar17 = KernelArg2;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar18", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]])
+  private int *private FuncVar18 = Tmp0;
+  // CHECK-DAG: !DILocalVariable(name: "FuncVar19", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
+  int *private FuncVar19 = Tmp1;
+}
+
+struct FileStruct0 {
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}})
+  global int *StructMem0;
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}, offset: {{[0-9]+}})
+  constant int *StructMem1;
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_LOCAL]], size: {{[0-9]+}}, offset: {{[0-9]+}})
+  local int *StructMem2;
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_PRIVATE]], size: {{[0-9]+}}, offset: {{[0-9]+}})
+  private int *StructMem3;
+  // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "StructMem4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}}, offset: {{[0-9]+}})
+  int *StructMem4;
+};
+
+struct FileStruct1 {
+  union {
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}})
+    global int *UnionMem0;
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}})
+    constant int *UnionMem1;
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_LOCAL]], size: {{[0-9]+}})
+    local int *UnionMem2;
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_PRIVATE]], size: {{[0-9]+}})
+    private int *UnionMem3;
+    // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "UnionMem4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, baseType: ![[DWARF_ADDRESS_SPACE_NONE]], size: {{[0-9]+}})
+    int *UnionMem4;
+  };
+  long StructMem0;
+};
+
+kernel void kernel2(global struct FileStruct0 *Kernel2Arg0,
+                    global struct FileStruct1 *Kernel2Arg1) {}
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
new file mode 100644
index 0000000..a962d3c
--- /dev/null
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
@@ -0,0 +1,130 @@
+// RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa -mcpu=fiji -o - %s | FileCheck %s
+
+// CHECK-DAG: ![[LOCAL:[0-9]+]] = !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef)
+// CHECK-DAG: ![[PRIVATE:[0-9]+]] = !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)
+
+// CHECK-DAG: ![[FILEVAR0:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR0]])
+global int *FileVar0;
+// CHECK-DAG: ![[FILEVAR1:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR1]])
+constant int *FileVar1;
+// CHECK-DAG: ![[FILEVAR2:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR2]])
+local int *FileVar2;
+// CHECK-DAG: ![[FILEVAR3:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR3]])
+private int *FileVar3;
+// CHECK-DAG: ![[FILEVAR4:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR4]])
+int *FileVar4;
+
+// CHECK-DAG: ![[FILEVAR5:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR5]])
+global int *global FileVar5;
+// CHECK-DAG: ![[FILEVAR6:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR6]])
+constant int *global FileVar6;
+// CHECK-DAG: ![[FILEVAR7:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR7]])
+local int *global FileVar7;
+// CHECK-DAG: ![[FILEVAR8:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR8]])
+private int *global FileVar8;
+// CHECK-DAG: ![[FILEVAR9:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR9]])
+int *global FileVar9;
+
+// CHECK-DAG: ![[FILEVAR10:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR10]])
+global int *constant FileVar10 = 0;
+// CHECK-DAG: ![[FILEVAR11:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR11]])
+constant int *constant FileVar11 = 0;
+// CHECK-DAG: ![[FILEVAR12:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR12]])
+local int *constant FileVar12 = 0;
+// CHECK-DAG: ![[FILEVAR13:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR13]])
+private int *constant FileVar13 = 0;
+// CHECK-DAG: ![[FILEVAR14:[0-9]+]] = distinct !DIGlobalVariable(name: "FileVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: false, isDefinition: true)
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR14]])
+int *constant FileVar14 = 0;
+
+kernel void kernel1(
+    // CHECK-DAG: ![[KERNELARG0:[0-9]+]] = !DILocalVariable(name: "KernelArg0", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+    // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[KERNELARG0]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+    global int *KernelArg0,
+    // CHECK-DAG: ![[KERNELARG1:[0-9]+]] = !DILocalVariable(name: "KernelArg1", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+    // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[KERNELARG1]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+    constant int *KernelArg1,
+    // CHECK-DAG: ![[KERNELARG2:[0-9]+]] = !DILocalVariable(name: "KernelArg2", arg: {{[0-9]+}}, scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+    // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[KERNELARG2]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+    local int *KernelArg2) {
+  private int *Tmp0;
+  int *Tmp1;
+
+  // CHECK-DAG: ![[FUNCVAR0:[0-9]+]] = !DILocalVariable(name: "FuncVar0", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR0]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  global int *FuncVar0 = KernelArg0;
+  // CHECK-DAG: ![[FUNCVAR1:[0-9]+]] = !DILocalVariable(name: "FuncVar1", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR1]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  constant int *FuncVar1 = KernelArg1;
+  // CHECK-DAG: ![[FUNCVAR2:[0-9]+]] = !DILocalVariable(name: "FuncVar2", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR2]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  local int *FuncVar2 = KernelArg2;
+  // CHECK-DAG: ![[FUNCVAR3:[0-9]+]] = !DILocalVariable(name: "FuncVar3", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR3]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  private int *FuncVar3 = Tmp0;
+  // CHECK-DAG: ![[FUNCVAR4:[0-9]+]] = !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR4]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  int *FuncVar4 = Tmp1;
+
+  // CHECK-DAG: ![[FUNCVAR5:[0-9]+]] = !DILocalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR5]], metadata ![[NONE:[0-9]+]]), !dbg !{{[0-9]+}}
+  global int *constant FuncVar5 = KernelArg0;
+  // CHECK-DAG: ![[FUNCVAR6:[0-9]+]] = !DILocalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR6]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
+  constant int *constant FuncVar6 = KernelArg1;
+  // CHECK-DAG: ![[FUNCVAR7:[0-9]+]] = !DILocalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR7]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
+  local int *constant FuncVar7 = KernelArg2;
+  // CHECK-DAG: ![[FUNCVAR8:[0-9]+]] = !DILocalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR8]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
+  private int *constant FuncVar8 = Tmp0;
+  // CHECK-DAG: ![[FUNCVAR9:[0-9]+]] = !DILocalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR9]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
+  int *constant FuncVar9 = Tmp1;
+
+  // CHECK-DAG: ![[FUNCVAR10:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: ![[LOCAL]])
+  global int *local FuncVar10; FuncVar10 = KernelArg0;
+  // CHECK-DAG: ![[FUNCVAR11:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar11", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR11]], expr: ![[LOCAL]])
+  constant int *local FuncVar11; FuncVar11 = KernelArg1;
+  // CHECK-DAG: ![[FUNCVAR12:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar12", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR12]], expr: ![[LOCAL]])
+  local int *local FuncVar12; FuncVar12 = KernelArg2;
+  // CHECK-DAG: ![[FUNCVAR13:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar13", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR13]], expr: ![[LOCAL]])
+  private int *local FuncVar13; FuncVar13 = Tmp0;
+  // CHECK-DAG: ![[FUNCVAR14:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar14", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR14]], expr: ![[LOCAL]])
+  int *local FuncVar14; FuncVar14 = Tmp1;
+
+  // CHECK-DAG: ![[FUNCVAR15:[0-9]+]] = !DILocalVariable(name: "FuncVar15", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR15]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  global int *private FuncVar15 = KernelArg0;
+  // CHECK-DAG: ![[FUNCVAR16:[0-9]+]] = !DILocalVariable(name: "FuncVar16", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR16]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  constant int *private FuncVar16 = KernelArg1;
+  // CHECK-DAG: ![[FUNCVAR17:[0-9]+]] = !DILocalVariable(name: "FuncVar17", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR17]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  local int *private FuncVar17 = KernelArg2;
+  // CHECK-DAG: ![[FUNCVAR18:[0-9]+]] = !DILocalVariable(name: "FuncVar18", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR18]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  private int *private FuncVar18 = Tmp0;
+  // CHECK-DAG: ![[FUNCVAR19:[0-9]+]] = !DILocalVariable(name: "FuncVar19", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR19]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
+  int *private FuncVar19 = Tmp1;
+}
diff --git a/test/CoverageMapping/empty-destructor.cpp b/test/CoverageMapping/empty-destructor.cpp
new file mode 100644
index 0000000..cfc29a7
--- /dev/null
+++ b/test/CoverageMapping/empty-destructor.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple i686-windows -emit-llvm-only -fcoverage-mapping -dump-coverage-mapping -fprofile-instrument=clang %s | FileCheck %s
+
+struct A {
+  virtual ~A();
+};
+
+// CHECK: ?PR32761@@YAXXZ:
+// CHECK-NEXT: File 0, [[@LINE+1]]:16 -> [[@LINE+3]]:2 = #0
+void PR32761() {
+  A a;
+}
diff --git a/test/CoverageMapping/implicit-def-in-macro.m b/test/CoverageMapping/implicit-def-in-macro.m
index 902fc8b..71184fc 100644
--- a/test/CoverageMapping/implicit-def-in-macro.m
+++ b/test/CoverageMapping/implicit-def-in-macro.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -triple x86_64-apple-darwin -fobjc-runtime=macosx-10.10.0 -fblocks -fobjc-arc %s | FileCheck %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -triple x86_64-apple-darwin -fobjc-runtime=macosx-10.10.0 -fblocks -fobjc-arc -w %s | FileCheck %s
 
 @interface Foo
 @end
diff --git a/test/CoverageMapping/macro-expressions.cpp b/test/CoverageMapping/macro-expressions.cpp
index 3852fc6..3eba869 100644
--- a/test/CoverageMapping/macro-expressions.cpp
+++ b/test/CoverageMapping/macro-expressions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name macro-expressions.cpp %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name macro-expressions.cpp -w %s | FileCheck %s
 
 #define EXPR(x) (x)
 #define NEXPR(x) (!x)
diff --git a/test/CoverageMapping/objc.m b/test/CoverageMapping/objc.m
index 89da5da..55c7545 100644
--- a/test/CoverageMapping/objc.m
+++ b/test/CoverageMapping/objc.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name objc.m -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 %s | FileCheck %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name objc.m -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -w %s | FileCheck %s
 
 @interface A
 - (void)bork:(int)msg;
diff --git a/test/CoverageMapping/unused_names.c b/test/CoverageMapping/unused_names.c
index a03d18b..49fa119 100644
--- a/test/CoverageMapping/unused_names.c
+++ b/test/CoverageMapping/unused_names.c
@@ -2,14 +2,15 @@
 // RUN: FileCheck -input-file %t %s
 // RUN: FileCheck -check-prefix=SYSHEADER -input-file %t %s
 
-// Since foo is never emitted, there should not be a profile name for it.
-
-// CHECK-DAG: @__profn_bar = {{.*}} [3 x i8] c"bar"
-// CHECK-DAG: @__profn_baz = {{.*}} [3 x i8] c"baz"
-// CHECK-DAG: @__profn_unused_names.c_qux = {{.*}} [18 x i8] c"unused_names.c:qux"
+// CHECK-DAG: @__profc_bar
 // CHECK-DAG: @__llvm_prf_nm = private constant {{.*}}, section "{{.*}}__llvm_prf_names"
 
-// SYSHEADER-NOT: @__profn_foo =
+// These are never instantiated, so we shouldn't get counters for them.
+//
+// CHECK-NOT: @__profc_baz
+// CHECK-NOT: @__profc_unused_names.c_qux
+
+// SYSHEADER-NOT: @__profc_foo =
 
 
 #ifdef IS_SYSHEADER
diff --git a/test/Driver/clang_f_opts.c b/test/Driver/clang_f_opts.c
index 210e169..b41521a 100644
--- a/test/Driver/clang_f_opts.c
+++ b/test/Driver/clang_f_opts.c
@@ -482,3 +482,8 @@
 // RUN: %clang -### -S -fno-strict-return %s 2>&1 | FileCheck -check-prefix=CHECK-NO-STRICT-RETURN %s
 // CHECK-STRICT-RETURN-NOT: "-fno-strict-return"
 // CHECK-NO-STRICT-RETURN: "-fno-strict-return"
+
+// RUN: %clang -### -S -fallow-editor-placeholders %s 2>&1 | FileCheck -check-prefix=CHECK-ALLOW-PLACEHOLDERS %s
+// RUN: %clang -### -S -fno-allow-editor-placeholders %s 2>&1 | FileCheck -check-prefix=CHECK-NO-ALLOW-PLACEHOLDERS %s
+// CHECK-ALLOW-PLACEHOLDERS: -fallow-editor-placeholders
+// CHECK-NO-ALLOW-PLACEHOLDERS-NOT: -fallow-editor-placeholders
diff --git a/test/Driver/crash-report-crashfile.m b/test/Driver/crash-report-crashfile.m
index 71f6e7a..fbfb532 100644
--- a/test/Driver/crash-report-crashfile.m
+++ b/test/Driver/crash-report-crashfile.m
@@ -3,15 +3,32 @@
 // RUN: mkdir -p %t/i %t/m %t
 
 // RUN: not env FORCE_CLANG_DIAGNOSTICS_CRASH= TMPDIR=%t TEMP=%t TMP=%t \
-// RUN: %clang -fsyntax-only %s -I %S/Inputs/module -isysroot %/t/i/    \
-// RUN: -fmodules -fmodules-cache-path=%t/m/ -DFOO=BAR 2>&1 | FileCheck %s
+// RUN: %clang -fsyntax-only %s \
+// RUN:   -I %S/Inputs/module -isysroot %/t/i/ \
+// RUN:   -fmodules -fmodules-cache-path=%t/m/ -DFOO=BAR 2>&1 | \
+// RUN:   FileCheck -check-prefix=CRASH_ENV %s
+
+// RUN: not env TMPDIR=%t TEMP=%t TMP=%t \
+// RUN: %clang -gen-reproducer -fsyntax-only %s \
+// RUN:   -I %S/Inputs/module -isysroot %/t/i/ \
+// RUN:   -fmodules -fmodules-cache-path=%t/m/ -DFOO=BAR 2>&1 | \
+// RUN:   FileCheck -check-prefix=CRASH_FLAG %s
 
 @import simple;
 const int x = MODULE_MACRO;
 
-// CHECK: Preprocessed source(s) and associated run script(s) are located at:
-// CHECK-NEXT: note: diagnostic msg: {{.*}}.m
-// CHECK-NEXT: note: diagnostic msg: {{.*}}.cache
-// CHECK-NEXT: note: diagnostic msg: {{.*}}.sh
-// CHECK-NEXT: note: diagnostic msg: Crash backtrace is located in
-// CHECK-NEXT: note: diagnostic msg: {{.*}}Library/Logs/DiagnosticReports{{.*}}
+// CRASH_ENV: failing because environment variable 'FORCE_CLANG_DIAGNOSTICS_CRASH' is set
+// CRASH_ENV: Preprocessed source(s) and associated run script(s) are located at:
+// CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}.m
+// CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}.cache
+// CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}.sh
+// CRASH_ENV-NEXT: note: diagnostic msg: Crash backtrace is located in
+// CRASH_ENV-NEXT: note: diagnostic msg: {{.*}}Library/Logs/DiagnosticReports{{.*}}
+
+// CRASH_FLAG: failing because '-gen-reproducer' is used
+// CRASH_FLAG: Preprocessed source(s) and associated run script(s) are located at:
+// CRASH_FLAG-NEXT: note: diagnostic msg: {{.*}}.m
+// CRASH_FLAG-NEXT: note: diagnostic msg: {{.*}}.cache
+// CRASH_FLAG-NEXT: note: diagnostic msg: {{.*}}.sh
+// CRASH_FLAG-NEXT: note: diagnostic msg: Crash backtrace is located in
+// CRASH_FLAG-NEXT: note: diagnostic msg: {{.*}}Library/Logs/DiagnosticReports{{.*}}
diff --git a/test/Driver/darwin-simulator-macro.c b/test/Driver/darwin-simulator-macro.c
new file mode 100644
index 0000000..6971e93
--- /dev/null
+++ b/test/Driver/darwin-simulator-macro.c
@@ -0,0 +1,12 @@
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mios-simulator-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -miphonesimulator-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mtvos-simulator-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mappletvsimulator-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mwatchos-simulator-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mwatchsimulator-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=SIM %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mios-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=DEV %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mtvos-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=DEV %s
+// RUN: %clang -target x86_64-apple-darwin10 -arch x86_64 -mwatchos-version-min=6.0.0 -E -dM %s | FileCheck -check-prefix=DEV %s
+
+// SIM: #define __APPLE_EMBEDDED_SIMULATOR__ 1
+// DEV-NOT: __APPLE_EMBEDDED_SIMULATOR__
diff --git a/test/Driver/darwin-version.c b/test/Driver/darwin-version.c
index 009f848..8f08bb9 100644
--- a/test/Driver/darwin-version.c
+++ b/test/Driver/darwin-version.c
@@ -29,9 +29,13 @@
 // RUN:   FileCheck --check-prefix=CHECK-VERSION-OSX10 %s
 // RUN: %clang -target x86_64-apple-macosx -mmacosx-version-min=10.10 -c %s -### 2>&1 | \
 // RUN:   FileCheck --check-prefix=CHECK-VERSION-OSX10 %s
+// RUN: %clang -target x86_64-apple-macosx -mmacos-version-min=10.10 -c %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=CHECK-VERSION-OSX10 %s
 // CHECK-VERSION-OSX10: "x86_64-apple-macosx10.10.0"
 // RUN: %clang -target x86_64-apple-macosx -mmacosx-version-min= -c %s -### 2>&1 | \
 // RUN:   FileCheck --check-prefix=CHECK-VERSION-MISSING %s
+// RUN: %clang -target x86_64-apple-macosx -mmacos-version-min= -c %s -### 2>&1 | \
+// RUN:   FileCheck --check-prefix=CHECK-VERSION-MISSING %s
 // CHECK-VERSION-MISSING: invalid version number
 // RUN: %clang -target armv7k-apple-darwin -mwatchos-version-min=2.0 -c %s -### 2>&1 | \
 // RUN:   FileCheck --check-prefix=CHECK-VERSION-WATCHOS20 %s
diff --git a/test/Driver/embed-bitcode.c b/test/Driver/embed-bitcode.c
index 36314e6..fa86c2c3 100644
--- a/test/Driver/embed-bitcode.c
+++ b/test/Driver/embed-bitcode.c
@@ -34,6 +34,13 @@
 // CHECK-LTO-NOT: warning: argument unused during compilation: '-fembed-bitcode'
 // CHECK-LTO-NOT: -cc1
 // CHECK-LTO-NOT: -fembed-bitcode=all
+// RUN: touch %t.o
+// RUN: %clang  -target armv7-apple-darwin -miphoneos-version-min=6.0 %t.o -fembed-bitcode  -fembed-bitcode-marker -mlinker-version=277  2>&1 -### | FileCheck %s -check-prefix=CHECK-LTO-MARKER-277
+// RUN: %clang  -target armv7-apple-darwin -miphoneos-version-min=6.0 %t.o -fembed-bitcode  -fembed-bitcode-marker -mlinker-version=278  2>&1 -### | FileCheck %s -check-prefix=CHECK-LTO-MARKER-278
+// CHECK-LTO-MARKER-277-NOT: bitcode_process_mode
+// CHECK-LTO-MARKER-278: bitcode_process_mode
+
+
 
 // RUN: %clang -c %s -fembed-bitcode-marker -fintegrated-as 2>&1 -### | FileCheck %s -check-prefix=CHECK-MARKER
 // CHECK-MARKER: -cc1
diff --git a/test/Driver/frame-pointer-elim.c b/test/Driver/frame-pointer-elim.c
index e1d816e..e39499a 100644
--- a/test/Driver/frame-pointer-elim.c
+++ b/test/Driver/frame-pointer-elim.c
@@ -49,9 +49,9 @@
 
 // RUN: %clang -### -target armv7s-apple-ios8.0 -momit-leaf-frame-pointer %s 2>&1 | \
 // RUN:   FileCheck --check-prefix=WARN-OMIT-LEAF-7S %s
-// WARN-OMIT-LEAF-7S: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
+// WARN-OMIT-LEAF-7S-NOT: warning: optimization flag '-momit-leaf-frame-pointer' is not supported for target 'armv7s'
 // WARN-OMIT-LEAF-7S: "-mdisable-fp-elim"
-// WARN-OMIT-LEAF-7S-NOT: "-momit-leaf-frame-pointer"
+// WARN-OMIT-LEAF-7S: "-momit-leaf-frame-pointer"
 
 // On the PS4, we default to omitting the frame pointer on leaf functions
 // (OMIT_LEAF check line is above)
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index 25aea01..1b1bae0 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -30,7 +30,7 @@
 // RUN: %clang -target x86_64-pc-win32 -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-COVERAGE-WIN64
 // CHECK-COVERAGE-WIN64: "--dependent-lib={{[^"]*}}ubsan_standalone-x86_64.lib"
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER -implicit-check-not="-fsanitize-address-use-after-scope"
 // CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent),?){5}"}}
 
 // RUN: %clang -fsanitize=bounds -### -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix=CHECK-BOUNDS
@@ -121,7 +121,7 @@
 // CHECK-USE-AFTER-SCOPE-BOTH-OFF-NOT: -cc1{{.*}}address-use-after-scope
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-WITHOUT-USE-AFTER-SCOPE
-// CHECK-ASAN-WITHOUT-USE-AFTER-SCOPE-NOT: -cc1{{.*}}address-use-after-scope
+// CHECK-ASAN-WITHOUT-USE-AFTER-SCOPE: -cc1{{.*}}address-use-after-scope
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-TRACK-ORIGINS
 // CHECK-ONLY-TRACK-ORIGINS: warning: argument unused during compilation: '-fsanitize-memory-track-origins'
diff --git a/test/Driver/mglobal-merge.c b/test/Driver/mglobal-merge.c
index ad76736..271011e 100644
--- a/test/Driver/mglobal-merge.c
+++ b/test/Driver/mglobal-merge.c
@@ -11,7 +11,7 @@
 // RUN: FileCheck --check-prefix=CHECK-NONE < %t %s
 
 // CHECK-NGM-ARM: "-backend-option" "-arm-global-merge=false"
-// CHECK-NGM-AARCH64: "-backend-option" "-aarch64-global-merge=false"
+// CHECK-NGM-AARCH64: "-backend-option" "-aarch64-enable-global-merge=false"
 
 // RUN: %clang -target armv7-unknown-unknown -### -fsyntax-only %s 2> %t \
 // RUN:   -mglobal-merge
@@ -26,7 +26,7 @@
 // RUN: FileCheck --check-prefix=CHECK-NONE < %t %s
 
 // CHECK-GM-ARM: "-backend-option" "-arm-global-merge=true"
-// CHECK-GM-AARCH64: "-backend-option" "-aarch64-global-merge=true"
+// CHECK-GM-AARCH64: "-backend-option" "-aarch64-enable-global-merge=true"
 
 // RUN: %clang -target armv7-unknown-unknown -### -fsyntax-only %s 2> %t
 // RUN: FileCheck --check-prefix=CHECK-NONE < %t %s
diff --git a/test/FixIt/fixit-availability.c b/test/FixIt/fixit-availability.c
new file mode 100644
index 0000000..038dee0
--- /dev/null
+++ b/test/FixIt/fixit-availability.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunguarded-availability -fdiagnostics-parseable-fixits -triple x86_64-apple-darwin9 %s 2>&1 | FileCheck %s
+
+__attribute__((availability(macos, introduced=10.12)))
+int function(void);
+
+void use() {
+  function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (__builtin_available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+}
diff --git a/test/FixIt/fixit-availability.mm b/test/FixIt/fixit-availability.mm
new file mode 100644
index 0000000..d044a73
--- /dev/null
+++ b/test/FixIt/fixit-availability.mm
@@ -0,0 +1,111 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunguarded-availability -fdiagnostics-parseable-fixits -triple x86_64-apple-darwin9 %s 2>&1 | FileCheck %s
+
+__attribute__((availability(macos, introduced=10.12)))
+int function(void);
+
+void anotherFunction(int function);
+
+int use() {
+  function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+  int y = function(), x = 0;
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:29-[[@LINE-2]]:29}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+  x += function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:19-[[@LINE-2]]:19}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+  if (1) {
+    x = function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:20-[[@LINE-2]]:20}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+  }
+  anotherFunction(function());
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:31-[[@LINE-2]]:31}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+  if (function()) {
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+1]]:4-[[@LINE+1]]:4}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+  }
+  while (function())
+    // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+    // CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+1]]:6-[[@LINE+1]]:6}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+    ;
+  do
+    function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
+  while (1);
+  for (int i = 0; i < 10; ++i)
+    function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
+  switch (x) {
+  case 0:
+    function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
+  case 2:
+    anotherFunction(1);
+    function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
+    break;
+  default:
+    function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n    } else {\n        // Fallback on earlier versions\n    }"
+    break;
+  }
+  return function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:21-[[@LINE-2]]:21}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+}
+
+#define MYFUNCTION function
+
+#define MACRO_ARGUMENT(X) X
+#define MACRO_ARGUMENT_SEMI(X) X;
+#define MACRO_ARGUMENT_2(X) if (1) X;
+
+#define INNER_MACRO if (1) MACRO_ARGUMENT(function()); else ;
+
+void useInMacros() {
+  MYFUNCTION();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+
+  MACRO_ARGUMENT_SEMI(function())
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:34-[[@LINE-2]]:34}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+  MACRO_ARGUMENT(function());
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:30-[[@LINE-2]]:30}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+  MACRO_ARGUMENT_2(function());
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:32-[[@LINE-2]]:32}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+
+  INNER_MACRO
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+}
+
+void wrapDeclStmtUses() {
+  int x = 0, y = function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n      "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+13]]:22-[[@LINE+13]]:22}:"\n  } else {\n      // Fallback on earlier versions\n  }"
+  {
+    int z = function();
+    if (z) {
+
+    }
+// CHECK: fix-it:{{.*}}:{[[@LINE-4]]:5-[[@LINE-4]]:5}:"if (@available(macOS 10.12, *)) {\n        "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:6-[[@LINE-2]]:6}:"\n    } else {\n        // Fallback on earlier versions\n    }"
+  }
+  if (y)
+    int z = function();
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n        "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:24-[[@LINE-2]]:24}:"\n    } else {\n        // Fallback on earlier versions\n    }"
+  anotherFunction(y);
+  anotherFunction(x);
+}
diff --git a/test/FixIt/fixit-pragma-attribute.c b/test/FixIt/fixit-pragma-attribute.c
new file mode 100644
index 0000000..f166eb2
--- /dev/null
+++ b/test/FixIt/fixit-pragma-attribute.c
@@ -0,0 +1,6 @@
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// Verify that the suggested attribute subject match rules don't include the
+// rules that are not applicable in the current language mode.
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:60-[[@LINE-1]]:60}:", apply_to = any(record(unless(is_union)), variable, function)"
diff --git a/test/FixIt/fixit-pragma-attribute.cpp b/test/FixIt/fixit-pragma-attribute.cpp
new file mode 100644
index 0000000..8e3f6d9
--- /dev/null
+++ b/test/FixIt/fixit-pragma-attribute.cpp
@@ -0,0 +1,83 @@
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -Wno-pragma-clang-attribute %s 2>&1 | FileCheck %s
+
+#pragma clang attribute push (annotate)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:31-[[@LINE-1]]:31}:"__attribute__(("
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:39-[[@LINE-2]]:39}:"))"
+#pragma clang attribute push (annotate(("test")))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:31-[[@LINE-1]]:31}:"__attribute__(("
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:49-[[@LINE-2]]:49}:"))"
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( enum, function, function, namespace, function ))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:97-[[@LINE-1]]:107}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:118-[[@LINE-2]]:127}:""
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(is_global), function, variable(is_global), variable(is_global) ))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:112-[[@LINE-1]]:133}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:133-[[@LINE-2]]:153}:""
+
+#pragma clang attribute push (__attribute__((annotate("subRuleContradictions"))), apply_to = any(variable, variable(is_parameter), function(is_member), variable(is_global)))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:108-[[@LINE-1]]:132}:""
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:153-[[@LINE-2]]:172}:""
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((annotate("subRuleContradictions2"))), apply_to = any(function(is_member),function))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:99-[[@LINE-1]]:119}:""
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((annotate("negatedSubRuleContradictions1"))), apply_to = any(variable(is_parameter), variable(unless(is_parameter))))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:130-[[@LINE-1]]:160}:""
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((annotate("negatedSubRuleContradictions2"))), apply_to = any(variable(unless(is_parameter)), variable(is_thread_local), function, variable(is_global)))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:106-[[@LINE-1]]:137}:""
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(enum, variable))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:77-[[@LINE-1]]:82}:""
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:60-[[@LINE-1]]:60}:", apply_to = any(record(unless(is_union)), variable, function, namespace)"
+#pragma clang attribute push (__attribute__((abi_tag("a"))) apply_to=function)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:60-[[@LINE-1]]:60}:", "
+#pragma clang attribute push (__attribute__((abi_tag("a"))) = function)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:60-[[@LINE-1]]:60}:", apply_to"
+#pragma clang attribute push (__attribute__((abi_tag("a"))) any(function))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:60-[[@LINE-1]]:60}:", apply_to = "
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))) 22)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:60-[[@LINE-1]]:63}:", apply_to = any(record(unless(is_union)), variable, function, namespace)"
+#pragma clang attribute push (__attribute__((abi_tag("a"))) function)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:60-[[@LINE-1]]:69}:", apply_to = any(record(unless(is_union)), variable, function, namespace)"
+#pragma clang attribute push (__attribute__((abi_tag("a"))) (function))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:60-[[@LINE-1]]:71}:", apply_to = any(record(unless(is_union)), variable, function, namespace)"
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), )
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:61-[[@LINE-1]]:62}:"apply_to = any(record(unless(is_union)), variable, function, namespace)"
+#pragma clang attribute push (__attribute__((abi_tag("a"))), = function)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:61-[[@LINE-1]]:61}:"apply_to"
+#pragma clang attribute push (__attribute__((abi_tag("a"))), any(function))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:61-[[@LINE-1]]:61}:"apply_to = "
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), 22)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:61-[[@LINE-1]]:64}:"apply_to = any(record(unless(is_union)), variable, function, namespace)"
+#pragma clang attribute push (__attribute__((abi_tag("a"))), 1, 2)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:61-[[@LINE-1]]:66}:"apply_to = any(record(unless(is_union)), variable, function, namespace)"
+#pragma clang attribute push (__attribute__((abi_tag("a"))), function)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:61-[[@LINE-1]]:70}:"apply_to = any(record(unless(is_union)), variable, function, namespace)"
+#pragma clang attribute push (__attribute__((abi_tag("a"))), (function))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:61-[[@LINE-1]]:72}:"apply_to = any(record(unless(is_union)), variable, function, namespace)"
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to)
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:70-[[@LINE-1]]:70}:" = any(record(unless(is_union)), variable, function, namespace)"
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to any(function))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:70-[[@LINE-1]]:70}:" = "
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to 41 (22))
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:70-[[@LINE-1]]:78}:" = any(record(unless(is_union)), variable, function, namespace)"
+
+// Don't give fix-it to attributes without a strict subject set
+#pragma clang attribute push (__attribute__((annotate("a"))))
+// CHECK-NO: [[@LINE-1]]:61
diff --git a/test/FixIt/fixit.cpp b/test/FixIt/fixit.cpp
index c43aac9..0b7fc62 100644
--- a/test/FixIt/fixit.cpp
+++ b/test/FixIt/fixit.cpp
@@ -409,3 +409,14 @@
 // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:26-[[@LINE-1]]:26}:"{}"
 int use_czi = czi.a;
 
+namespace dotPointerDestructor {
+
+struct Bar {
+  ~Bar();
+};
+
+void bar(Bar *o) {
+  o.~Bar(); // expected-error {{member reference type 'dotPointerDestructor::Bar *' is a pointer; did you mean to use '->'}}
+}  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:5}:"->"
+
+}
diff --git a/test/FixIt/no-fixit.cpp b/test/FixIt/no-fixit.cpp
index 7e8e1fb..2dad28d 100644
--- a/test/FixIt/no-fixit.cpp
+++ b/test/FixIt/no-fixit.cpp
@@ -11,3 +11,15 @@
     (void)&i;
   }
 } x;
+
+namespace dotPointerDestructor {
+
+struct Bar {
+  ~Bar() = delete;
+};
+
+void bar(Bar *o) {
+  o.~Bar(); // no fixit
+}
+
+}
diff --git a/test/Frontend/iframework.c b/test/Frontend/iframework.c
index 6f801f2..2354553 100644
--- a/test/Frontend/iframework.c
+++ b/test/Frontend/iframework.c
@@ -1,4 +1,5 @@
 // RUN: %clang -fsyntax-only -iframework %S/Inputs %s -Xclang -verify
+// RUN: %clang -fsyntax-only -isysroot %S -iframeworkwithsysroot /Inputs %s -Xclang -verify
 // expected-no-diagnostics
 
 #include <TestFramework/TestFramework.h>
diff --git a/test/Frontend/objc-bool-is-bool.m b/test/Frontend/objc-bool-is-bool.m
index 464fe2e..ee4fb58 100644
--- a/test/Frontend/objc-bool-is-bool.m
+++ b/test/Frontend/objc-bool-is-bool.m
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -E -dM -triple=armv7k-apple-watchos %s | FileCheck --check-prefix=BOOL %s
 // RUN: %clang_cc1 -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
-// RUN: %clang_cc1 -x c -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=NONE %s
+// RUN: %clang_cc1 -x c -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
+// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
+// RUN: %clang_cc1 -x c++ -fsyntax-only -E -dM -triple=x86_64-apple-darwin16 %s | FileCheck --check-prefix=CHAR %s
 
 // rdar://21170440
 
@@ -9,5 +11,3 @@
 
 // CHAR: #define __OBJC_BOOL_IS_BOOL 0
 // CHAR-NOT: #define __OBJC_BOOL_IS_BOOL 1
-
-// NONE-NOT: __OBJC_BOOL_IS_BOOL
diff --git a/test/Headers/Inputs/usr/include/math.h b/test/Headers/Inputs/usr/include/math.h
new file mode 100644
index 0000000..4171d4f
--- /dev/null
+++ b/test/Headers/Inputs/usr/include/math.h
@@ -0,0 +1 @@
+// math.h
diff --git a/test/Headers/Inputs/usr/include/tgmath.h b/test/Headers/Inputs/usr/include/tgmath.h
new file mode 100644
index 0000000..897962d
--- /dev/null
+++ b/test/Headers/Inputs/usr/include/tgmath.h
@@ -0,0 +1,4 @@
+#ifndef SYS_TGMATH_H
+#define SYS_TGMATH_H
+
+#endif /* SYS_TGMATH_H */
diff --git a/test/Headers/tgmath-darwin.c b/test/Headers/tgmath-darwin.c
new file mode 100644
index 0000000..916605a
--- /dev/null
+++ b/test/Headers/tgmath-darwin.c
@@ -0,0 +1,12 @@
+// REQUIRES: system-darwin
+// RUN: %clang -target x86_64-apple-darwin10 -fsyntax-only -std=c11 -isysroot %S/Inputs %s
+#include <tgmath.h>
+
+// Test the #include_next of tgmath.h works on Darwin.
+#ifndef SYS_TGMATH_H
+  #error "SYS_TGMATH_H not defined"
+#endif
+
+#ifndef __CLANG_TGMATH_H
+  #error "__CLANG_TGMATH_H not defined"
+#endif
diff --git a/test/Index/Core/Inputs/sys/system-head.h b/test/Index/Core/Inputs/sys/system-head.h
new file mode 100644
index 0000000..df0e39e
--- /dev/null
+++ b/test/Index/Core/Inputs/sys/system-head.h
@@ -0,0 +1,36 @@
+// CHECK: [[@LINE+1]]:12 | class/ObjC | Base | [[Base_USR:.*]] | {{.*}} | Decl | rel: 0
+@interface Base
+@end
+
+// CHECK: [[@LINE+1]]:11 | protocol/ObjC | Prot1 | [[Prot1_USR:.*]] | {{.*}} | Decl | rel: 0
+@protocol Prot1
+@end
+
+// CHECK: [[@LINE+3]]:11 | protocol/ObjC | Prot2 | [[Prot2_USR:.*]] | {{.*}} | Decl | rel: 0
+// CHECK: [[@LINE+2]]:17 | protocol/ObjC | Prot1 | [[Prot1_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | Prot2 | [[Prot2_USR]]
+@protocol Prot2<Prot1>
+@end
+
+// CHECK: [[@LINE+7]]:12 | class/ObjC | Sub | [[Sub_USR:.*]] | {{.*}} | Decl | rel: 0
+// CHECK: [[@LINE+6]]:18 | class/ObjC | Base | [[Base_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | Sub | [[Sub_USR]]
+// CHECK: [[@LINE+4]]:23 | protocol/ObjC | Prot2 | [[Prot2_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | Sub | [[Sub_USR]]
+// CHECK: [[@LINE+2]]:30 | protocol/ObjC | Prot1 | [[Prot1_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | Sub | [[Sub_USR]]
+@interface Sub : Base<Prot2, Prot1>
+// CHECK-NOT: [[@LINE+1]]:3 | class/ObjC | Sub |
+-(Sub*)getit;
+@end
+
+// CHECK: [[@LINE+1]]:7 | class/C++ | Cls | [[Cls_USR:.*]] | {{.*}} | Def | rel: 0
+class Cls {};
+
+// CHECK: [[@LINE+3]]:7 | class/C++ | SubCls1 | [[SubCls1_USR:.*]] | {{.*}} | Def | rel: 0
+// CHECK: [[@LINE+2]]:24 | class/C++ | Cls | [[Cls_USR]] | {{.*}} | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | SubCls1 | [[SubCls1_USR]]
+class SubCls1 : public Cls {
+  // CHECK-NOT: [[@LINE+1]]:3 | class/C++ | SubCls1 |
+  SubCls1 *f;
+};
diff --git a/test/Index/Core/external-source-symbol-attr.m b/test/Index/Core/external-source-symbol-attr.m
new file mode 100644
index 0000000..cdc5296
--- /dev/null
+++ b/test/Index/Core/external-source-symbol-attr.m
@@ -0,0 +1,104 @@
+// RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s
+
+#define EXT_DECL(mod_name) __attribute__((external_source_symbol(language="Swift", defined_in=mod_name)))
+#define GEN_DECL(mod_name) __attribute__((external_source_symbol(language="Swift", defined_in=mod_name, generated_declaration)))
+#define PUSH_GEN_DECL(mod_name) push(GEN_DECL(mod_name), apply_to=any(enum, objc_interface, objc_category, objc_protocol))
+
+// Forward declarations should not affect module namespacing below
+@class I1;
+@class I2;
+
+// This should not be indexed.
+GEN_DECL("some_module")
+@interface I1
+// CHECK-NOT: [[@LINE-1]]:12 |
+-(void)method;
+// CHECK-NOT: [[@LINE-1]]:8 |
+@end
+
+EXT_DECL("some_module")
+@interface I2
+// CHECK: [[@LINE-1]]:12 | class/Swift | I2 | c:@M@some_module@objc(cs)I2 | {{.*}} | Decl | rel: 0
+-(void)method;
+// CHECK: [[@LINE-1]]:8 | instance-method/Swift | method | c:@M@some_module@objc(cs)I2(im)method | -[I2 method] | Decl,Dyn,RelChild | rel: 1
+@end
+
+void test1(I1 *o) {
+// CHECK: [[@LINE-1]]:12 | class/Swift | I1 | c:@M@some_module@objc(cs)I1 |
+  [o method];
+  // CHECK: [[@LINE-1]]:6 | instance-method/Swift | method | c:@M@some_module@objc(cs)I1(im)method |
+}
+
+EXT_DECL("some_module")
+@protocol ExtProt
+// CHECK: [[@LINE-1]]:11 | protocol/Swift | ExtProt | c:@M@some_module@objc(pl)ExtProt |
+@end
+
+@interface I1(cat)
+// CHECK: [[@LINE-1]]:15 | extension/ObjC | cat | c:@M@some_module@objc(cy)I1@cat |
+-(void)cat_method;
+// CHECK: [[@LINE-1]]:8 | instance-method/ObjC | cat_method | c:@M@some_module@objc(cs)I1(im)cat_method
+@end
+
+EXT_DECL("cat_module")
+@interface I1(cat2)
+// CHECK: [[@LINE-1]]:15 | extension/Swift | cat2 | c:@CM@cat_module@some_module@objc(cy)I1@cat2 |
+-(void)cat_method2;
+// CHECK: [[@LINE-1]]:8 | instance-method/Swift | cat_method2 | c:@CM@cat_module@some_module@objc(cs)I1(im)cat_method2
+@end
+
+#define NS_ENUM(_name, _type) enum _name:_type _name; enum _name : _type
+
+#pragma clang attribute PUSH_GEN_DECL("modname")
+
+@interface I3
+// CHECK-NOT: [[@LINE-1]]:12 |
+-(void)meth;
+// CHECK-NOT: [[@LINE-1]]:8 |
+@end
+
+@interface I3(cat)
+// CHECK-NOT: [[@LINE-1]]:12 |
+// CHECK-NOT: [[@LINE-2]]:15 |
+-(void)meth2;
+// CHECK-NOT: [[@LINE-1]]:8 |
+@end
+
+@protocol ExtProt2
+// CHECK-NOT: [[@LINE-1]]:11 |
+-(void)meth;
+// CHECK-NOT: [[@LINE-1]]:8 |
+@end
+
+typedef NS_ENUM(SomeEnum, int) {
+// CHECK-NOT: [[@LINE-1]]:17 |
+  SomeEnumFirst = 0,
+  // CHECK-NOT: [[@LINE-1]]:3 |
+};
+
+#pragma clang attribute pop
+
+void test2(I3 *i3, id<ExtProt2> prot2, SomeEnum some) {
+  // CHECK: [[@LINE-1]]:12 | class/Swift | I3 | c:@M@modname@objc(cs)I3 |
+  // CHECK: [[@LINE-2]]:23 | protocol/Swift | ExtProt2 | c:@M@modname@objc(pl)ExtProt2 |
+  // CHECK: [[@LINE-3]]:40 | enum/Swift | SomeEnum | c:@M@modname@E@SomeEnum |
+  [i3 meth];
+  // CHECK: [[@LINE-1]]:7 | instance-method/Swift | meth | c:@M@modname@objc(cs)I3(im)meth |
+  [i3 meth2];
+  // CHECK: [[@LINE-1]]:7 | instance-method/Swift | meth2 | c:@CM@modname@objc(cs)I3(im)meth2 |
+  [prot2 meth];
+  // CHECK: [[@LINE-1]]:10 | instance-method/Swift | meth | c:@M@modname@objc(pl)ExtProt2(im)meth |
+  some = SomeEnumFirst;
+  // CHECK: [[@LINE-1]]:10 | enumerator/Swift | SomeEnumFirst | c:@M@modname@E@SomeEnum@SomeEnumFirst |
+}
+
+#pragma clang attribute PUSH_GEN_DECL("other_mod_for_cat")
+@interface I3(cat_other_mod)
+-(void)meth_other_mod;
+@end
+#pragma clang attribute pop
+
+void test3(I3 *i3) {
+  [i3 meth_other_mod];
+  // CHECK: [[@LINE-1]]:7 | instance-method/Swift | meth_other_mod | c:@CM@other_mod_for_cat@modname@objc(cs)I3(im)meth_other_mod |
+}
diff --git a/test/Index/Core/index-dependent-source.cpp b/test/Index/Core/index-dependent-source.cpp
new file mode 100644
index 0000000..59c6286
--- /dev/null
+++ b/test/Index/Core/index-dependent-source.cpp
@@ -0,0 +1,160 @@
+// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
+
+int invalid;
+
+class Base {
+  void baseFunction();
+
+  int baseField;
+
+  static void staticBaseFunction();
+};
+
+template<typename T>
+class BaseTemplate {
+public:
+  T baseTemplateFunction();
+
+  T baseTemplateField;
+
+  static T baseTemplateVariable;
+};
+
+template<typename T, typename S>
+class TemplateClass: public Base , public BaseTemplate<T> {
+public:
+  ~TemplateClass();
+
+  T function() { }
+
+  static void staticFunction() { }
+
+  T field;
+
+  static T variable;
+
+  struct Struct { };
+
+  enum Enum { EnumValue };
+
+  using TypeAlias = S;
+  typedef T Typedef;
+
+  void overload1(const T &);
+  void overload1(const S &);
+};
+
+template<typename T, typename S>
+void indexSimpleDependentDeclarations(const TemplateClass<T, S> &object) {
+  // Valid instance members:
+  object.function();
+// CHECK: [[@LINE-1]]:10 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+  object.field;
+// CHECK: [[@LINE-1]]:10 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+  object.baseFunction();
+// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseFunction | c:@S@Base@F@baseFunction# | __ZN4Base12baseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1
+  object.baseField;
+// CHECK: [[@LINE-1]]:10 | field/C++ | baseField | c:@S@Base@FI@baseField | <no-cgname> | Ref,RelCont | rel: 1
+  object.baseTemplateFunction();
+// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+  object.baseTemplateField;
+// CHECK: [[@LINE-1]]:10 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField | <no-cgname> | Ref,RelCont | rel: 1
+
+  // Invalid instance members:
+  object.variable;
+// CHECK-NOT: [[@LINE-1]]:10
+  object.staticFunction();
+// CHECK-NOT: [[@LINE-1]]:10
+  object.Struct;
+// CHECK-NOT: [[@LINE-1]]:10
+  object.EnumValue;
+// CHECK-NOT: [[@LINE-1]]:10
+
+  // Valid static members:
+  TemplateClass<T, S>::staticFunction();
+// CHECK: [[@LINE-1]]:24 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+  TemplateClass<T, S>::variable;
+// CHECK: [[@LINE-1]]:24 | static-property/C++ | variable | c:@ST>2#T#T@TemplateClass@variable | __ZN13TemplateClass8variableE | Ref,RelCont | rel: 1
+  TemplateClass<T, S>::staticBaseFunction();
+// CHECK: [[@LINE-1]]:24 | static-method/C++ | staticBaseFunction | c:@S@Base@F@staticBaseFunction#S | __ZN4Base18staticBaseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1
+  TemplateClass<T, S>::baseTemplateVariable;
+// CHECK: [[@LINE-1]]:24 | static-property/C++ | baseTemplateVariable | c:@ST>1#T@BaseTemplate@baseTemplateVariable | __ZN12BaseTemplate20baseTemplateVariableE | Ref,RelCont | rel: 1
+  TemplateClass<T, S>::EnumValue;
+// CHECK: [[@LINE-1]]:24 | enumerator/C | EnumValue | c:@ST>2#T#T@TemplateClass@E@Enum@EnumValue | <no-cgname> | Ref,RelCont | rel: 1
+  TemplateClass<T, S>::Struct();
+// CHECK: [[@LINE-1]]:24 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+
+  // Invalid static members:
+  TemplateClass<T, S>::field;
+// CHECK-NOT: [[@LINE-1]]:24
+  TemplateClass<T, S>::function();
+// CHECK-NOT: [[@LINE-1]]:24
+
+  // Valid type names:
+  typename TemplateClass<T, S>::Struct Val;
+// CHECK: [[@LINE-1]]:33 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,RelCont | rel: 1
+  typename TemplateClass<T, S>::Enum EnumVal;
+// CHECK: [[@LINE-1]]:33 | enum/C | Enum | c:@ST>2#T#T@TemplateClass@E@Enum | <no-cgname> | Ref,RelCont | rel: 1
+  typename TemplateClass<T, S>::TypeAlias Val2;
+// CHECK: [[@LINE-1]]:33 | type-alias/C++ | TypeAlias | c:@ST>2#T#T@TemplateClass@TypeAlias | <no-cgname> | Ref,RelCont | rel: 1
+  typename TemplateClass<T, S>::Typedef Val3;
+// CHECK: [[@LINE-1]]:33 | type-alias/C | Typedef | c:{{.*}}index-dependent-source.cpp@ST>2#T#T@TemplateClass@T@Typedef | <no-cgname> | Ref,RelCont | rel: 1
+
+  // Invalid type names:
+  typename TemplateClass<T, S>::field Val4;
+// CHECK-NOT: [[@LINE-1]]:33
+  typename TemplateClass<T, S>::staticFunction Val5;
+// CHECK-NOT: [[@LINE-1]]:33
+
+
+  object.invalid;
+// CHECK-NOT: [[@LINE-1]]:10
+  TemplateClass<T, S>::invalid;
+// CHECK-NOT: [[@LINE-1]]:24
+}
+
+template<typename T, typename S, typename Y>
+void indexDependentOverloads(const TemplateClass<T, S> &object) {
+  object.overload1(T());
+// CHECK-NOT: [[@LINE-1]]
+  object.overload1(S());
+// CHECK-NOT: [[@LINE-1]]
+  object.overload1(Y());
+// CHECK-NOT: [[@LINE-1]]
+}
+
+template<typename T> struct UndefinedTemplateClass;
+
+template<typename T>
+void undefinedTemplateLookup(UndefinedTemplateClass<T> &x) {
+// Shouldn't crash!
+  x.lookup;
+  typename UndefinedTemplateClass<T>::Type y;
+}
+
+template<typename T>
+struct UserOfUndefinedTemplateClass: UndefinedTemplateClass<T> { };
+
+template<typename T>
+void undefinedTemplateLookup2(UserOfUndefinedTemplateClass<T> &x) {
+// Shouldn't crash!
+  x.lookup;
+  typename UserOfUndefinedTemplateClass<T>::Type y;
+}
+
+template<typename T> struct Dropper;
+
+template<typename T> struct Trait;
+
+template<typename T>
+struct Recurse : Trait<typename Dropper<T>::Type> { };
+
+template<typename T>
+struct Trait : Recurse<T> {
+};
+
+template<typename T>
+void infiniteTraitRecursion(Trait<T> &t) {
+// Shouldn't crash!
+  t.lookup;
+}
diff --git a/test/Index/Core/index-instantiated-source.cpp b/test/Index/Core/index-instantiated-source.cpp
new file mode 100644
index 0000000..7a810fb
--- /dev/null
+++ b/test/Index/Core/index-instantiated-source.cpp
@@ -0,0 +1,88 @@
+// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
+// References to declarations in instantiations should be canonicalized:
+
+template<typename T>
+class BaseTemplate {
+public:
+  T baseTemplateFunction();
+// CHECK: [[@LINE-1]]:5 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction#
+
+  T baseTemplateField;
+// CHECK: [[@LINE-1]]:5 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField
+
+  struct NestedBaseType { };
+// CHECK: [[@LINE-1]]:10 | struct/C | NestedBaseType | c:@ST>1#T@BaseTemplate@S@NestedBaseType |
+};
+
+template<typename T, typename S>
+class TemplateClass: public BaseTemplate<T> {
+public:
+  T function() { return T(); }
+// CHECK: [[@LINE-1]]:5 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function#
+
+  static void staticFunction() { }
+// CHECK: [[@LINE-1]]:15 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S
+
+  T field;
+// CHECK: [[@LINE-1]]:5 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field
+
+  struct NestedType {
+// CHECK: [[@LINE-1]]:10 | struct/C++ | NestedType | c:@ST>2#T#T@TemplateClass@S@NestedType |
+
+    T nestedField;
+// CHECK: [[@LINE-1]]:7 | field/C++ | nestedField | c:@ST>2#T#T@TemplateClass@S@NestedType@FI@nestedField |
+
+    class SubNestedType {
+// CHECK: [[@LINE-1]]:11 | class/C++ | SubNestedType | c:@ST>2#T#T@TemplateClass@S@NestedType@S@SubNestedType |
+    public:
+      SubNestedType(int);
+    };
+    using TypeAlias = T;
+// CHECK: [[@LINE-1]]:11 | type-alias/C++ | TypeAlias | c:@ST>2#T#T@TemplateClass@S@NestedType@TypeAlias |
+
+    typedef int Typedef;
+// CHECK: [[@LINE-1]]:17 | type-alias/C | Typedef | c:{{.*}}index-instantiated-source.cpp@ST>2#T#T@TemplateClass@S@NestedType@T@Typedef |
+
+    enum Enum {
+// CHECK: [[@LINE-1]]:10 | enum/C | Enum | c:@ST>2#T#T@TemplateClass@S@NestedType@E@Enum |
+      EnumCase
+// CHECK: [[@LINE-1]]:7 | enumerator/C | EnumCase | c:@ST>2#T#T@TemplateClass@S@NestedType@E@Enum@EnumCase |
+    };
+  };
+};
+
+void canonicalizeInstaniationReferences(TemplateClass<int, float> &object) {
+  (void)object.function();
+// CHECK: [[@LINE-1]]:16 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function# | <no-cgname>
+  (void)object.field;
+// CHECK: [[@LINE-1]]:16 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+  (void)object.baseTemplateFunction();
+// CHECK: [[@LINE-1]]:16 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction# | <no-cgname>
+  (void)object.baseTemplateField;
+// CHECK: [[@LINE-1]]:16 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField | <no-cgname> | Ref,RelCont | rel: 1
+
+  TemplateClass<int, float>::staticFunction();
+// CHECK: [[@LINE-1]]:30 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | <no-cgname
+
+  TemplateClass<int, float>::NestedBaseType nestedBaseType;
+// CHECK: [[@LINE-1]]:30 | struct/C | NestedBaseType | c:@ST>1#T@BaseTemplate@S@NestedBaseType |
+  TemplateClass<int, float>::NestedType nestedSubType;
+// CHECK: [[@LINE-1]]:30 | struct/C++ | NestedType | c:@ST>2#T#T@TemplateClass@S@NestedType |
+  (void)nestedSubType.nestedField;
+// CHECK: [[@LINE-1]]:23 | field/C++ | nestedField | c:@ST>2#T#T@TemplateClass@S@NestedType@FI@nestedField |
+
+  typedef TemplateClass<int, float> TT;
+  TT::NestedType::SubNestedType subNestedType(0);
+// CHECK: [[@LINE-1]]:7 | struct/C++ | NestedType | c:@ST>2#T#T@TemplateClass@S@NestedType |
+// CHECK: [[@LINE-2]]:19 | class/C++ | SubNestedType | c:@ST>2#T#T@TemplateClass@S@NestedType@S@SubNestedType |
+
+  TT::NestedType::TypeAlias nestedTypeAlias;
+// CHECK: [[@LINE-1]]:19 | type-alias/C++ | TypeAlias | c:@ST>2#T#T@TemplateClass@S@NestedType@TypeAlias |
+  TT::NestedType::Typedef nestedTypedef;
+// CHECK: [[@LINE-1]]:19 | type-alias/C | Typedef | c:{{.*}}index-instantiated-source.cpp@ST>2#T#T@TemplateClass@S@NestedType@T@Typedef |
+
+  TT::NestedType::Enum nestedEnum;
+// CHECK: [[@LINE-1]]:19 | enum/C | Enum | c:@ST>2#T#T@TemplateClass@S@NestedType@E@Enum |
+  (void)TT::NestedType::Enum::EnumCase;
+// CHECK: [[@LINE-1]]:31 | enumerator/C | EnumCase | c:@ST>2#T#T@TemplateClass@S@NestedType@E@Enum@EnumCase |
+}
diff --git a/test/Index/Core/index-pch.c b/test/Index/Core/index-pch.c
new file mode 100644
index 0000000..773cfc5
--- /dev/null
+++ b/test/Index/Core/index-pch.c
@@ -0,0 +1,13 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+// RUN: %clang_cc1 -emit-pch %s -o %t.pch
+// RUN: c-index-test core -print-source-symbols -module-file %t.pch | FileCheck %s
+
+// CHECK: [[@LINE+1]]:6 | function/C | test1 | [[TEST1_USR:.*]] | [[TEST1_CG:.*]] | Decl | rel: 0
+void test1();
+
+// CHECK: [[@LINE+1]]:20 | function/C | test2 | [[TEST2_USR:.*]] | {{.*}} | Def | rel: 0
+static inline void test2() {
+  // CHECK: [[@LINE+2]]:3 | function/C | test1 | [[TEST1_USR]] | [[TEST1_CG]] | Ref,Call,RelCall,RelCont | rel: 1
+  // CHECK-NEXT: RelCall,RelCont | test2 | [[TEST2_USR]]
+  test1();
+}
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index 68eafec..022638c 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -1,16 +1,46 @@
 // RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
 
-// CHECK: [[@LINE+1]]:7 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Def | rel: 0
-class Cls {
-  // CHECK: [[@LINE+2]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:7 | class/C++ | Cls | [[Cls_USR:.*]] | <no-cgname> | Def | rel: 0
+class Cls { public:
+  // CHECK: [[@LINE+3]]:3 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Decl,RelChild | rel: 1
   // CHECK-NEXT: RelChild | Cls | c:@S@Cls
+  // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
   Cls(int x);
-  // CHECK: [[@LINE+1]]:3 | constructor/cxx-copy-ctor/C++ | Cls | c:@S@Cls@F@Cls#&1$@S@Cls# | __ZN3ClsC1ERKS_ | Decl,RelChild | rel: 1
+  // CHECK: [[@LINE+2]]:3 | constructor/cxx-copy-ctor/C++ | Cls | c:@S@Cls@F@Cls#&1$@S@Cls# | __ZN3ClsC1ERKS_ | Decl,RelChild | rel: 1
+  // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
   Cls(const Cls &);
-  // CHECK: [[@LINE+1]]:3 | constructor/cxx-move-ctor/C++ | Cls | c:@S@Cls@F@Cls#&&$@S@Cls# | __ZN3ClsC1EOS_ | Decl,RelChild | rel: 1
+  // CHECK: [[@LINE+2]]:3 | constructor/cxx-move-ctor/C++ | Cls | c:@S@Cls@F@Cls#&&$@S@Cls# | __ZN3ClsC1EOS_ | Decl,RelChild | rel: 1
+  // CHECK: [[@LINE+1]]:3 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
   Cls(Cls &&);
+
+  // CHECK: [[@LINE+2]]:3 | destructor/C++ | ~Cls | c:@S@Cls@F@~Cls# | __ZN3ClsD1Ev | Decl,RelChild | rel: 1
+  // CHECK: [[@LINE+1]]:4 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+  ~Cls();
 };
 
+// CHECK: [[@LINE+3]]:7 | class/C++ | SubCls1 | [[SubCls1_USR:.*]] | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+2]]:24 | class/C++ | Cls | [[Cls_USR]] | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | SubCls1 | [[SubCls1_USR]]
+class SubCls1 : public Cls {};
+// CHECK: [[@LINE+1]]:13 | type-alias/C | ClsAlias | [[ClsAlias_USR:.*]] | <no-cgname> | Def | rel: 0
+typedef Cls ClsAlias;
+// CHECK: [[@LINE+5]]:7 | class/C++ | SubCls2 | [[SubCls2_USR:.*]] | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+4]]:24 | type-alias/C | ClsAlias | [[ClsAlias_USR]] | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | SubCls2 | [[SubCls2_USR]]
+// CHECK: [[@LINE+2]]:24 | class/C++ | Cls | [[Cls_USR]] | <no-cgname> | Ref,Impl,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | SubCls2 | [[SubCls2_USR]]
+class SubCls2 : public ClsAlias {};
+
+Cls::Cls(int x) {}
+// CHECK: [[@LINE-1]]:6 | constructor/C++ | Cls | c:@S@Cls@F@Cls#I# | __ZN3ClsC1Ei | Def,RelChild | rel: 1
+// CHECK: [[@LINE-2]]:1 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:6 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+
+Cls::~/*a comment*/Cls() {}
+// CHECK: [[@LINE-1]]:6 | destructor/C++ | ~Cls | c:@S@Cls@F@~Cls# | __ZN3ClsD1Ev | Def,RelChild | rel: 1
+// CHECK: [[@LINE-2]]:1 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:20 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+
 template <typename TemplArg>
 class TemplCls {
 // CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Def | rel: 0
@@ -20,9 +50,25 @@
   // CHECK-NEXT: RelChild | TemplCls | c:@ST>1#T@TemplCls
 };
 
+template<>
+class TemplCls<double> {
+// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | TemplCls | c:@S@TemplCls>#d | <no-cgname> | Def,RelSpecialization | rel: 1
+// CHECK: RelSpecialization | TemplCls | c:@ST>1#T@TemplCls
+};
+
 TemplCls<int> gtv(0);
 // CHECK: [[@LINE-1]]:1 | class(Gen)/C++ | TemplCls | c:@ST>1#T@TemplCls | <no-cgname> | Ref,RelCont | rel: 1
 
+template<class T>
+class Wrapper {};
+template<class T, class P>
+class Wrapper<T(P)> {};
+
+// CHECK: [[@LINE+1]]:6 | function/C | test1 | [[TEST1_USR:.*]] | [[TEST1_CG:.*]] | Decl | rel: 0
+void test1(Wrapper<void(int)> f);
+// CHECK: [[@LINE+1]]:6 | function/C | test1 | [[TEST1_USR]] | [[TEST1_CG]] | Def | rel: 0
+void test1(Wrapper<void(int)> f) {}
+
 template <typename T>
 class BT {
   struct KLR {
@@ -51,3 +97,339 @@
 // CHECK: [[@LINE+2]]:5 | variable/C | gvf | c:@gvf | _gvf | Def | rel: 0
 // CHECK: [[@LINE+1]]:11 | variable(Gen)/C++ | tmplVar | c:index-source.cpp@VT>1#T@tmplVar | __ZL7tmplVar | Ref,Read,RelCont | rel: 1
 int gvf = tmplVar<float>;
+
+template<typename A, typename B>
+class PartialSpecilizationClass { };
+// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass | <no-cgname> | Def | rel: 0
+
+template<typename B>
+class PartialSpecilizationClass<int, B *> { };
+// CHECK: [[@LINE-1]]:7 | class(Gen,TPS)/C++ | PartialSpecilizationClass | c:@SP>1#T@PartialSpecilizationClass>#I#*t0.0 | <no-cgname> | Def,RelSpecialization | rel: 1
+// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass
+
+template<>
+class PartialSpecilizationClass<int, int> { };
+// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#I#I | <no-cgname> | Def,RelSpecialization | rel: 1
+// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass
+
+template<typename T, typename S>
+class PseudoOverridesInSpecializations {
+  void function() { }
+  void function(int) { }
+
+  static void staticFunction() { }
+
+  int field;
+  static int variable;
+
+  typedef T TypeDef;
+  using TypeAlias = T;
+
+  enum anEnum { };
+
+  struct Struct { };
+  union Union { };
+
+  using TypealiasOrRecord = void;
+
+  template<typename U> struct InnerTemplate { };
+  template<typename U> struct InnerTemplate <U*> { };
+};
+
+template<>
+class PseudoOverridesInSpecializations<double, int> {
+  void function() { }
+// CHECK: [[@LINE-1]]:8 | instance-method/C++ | function | c:@S@PseudoOverridesInSpecializations>#d#I@F@function# | __ZN32PseudoOverridesInSpecializationsIdiE8functionEv | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | function | c:@ST>2#T#T@PseudoOverridesInSpecializations@F@function#
+
+  void staticFunction() { }
+// CHECK: [[@LINE-1]]:8 | instance-method/C++ | staticFunction | c:@S@PseudoOverridesInSpecializations>#d#I@F@staticFunction# | __ZN32PseudoOverridesInSpecializationsIdiE14staticFunctionEv | Def,RelChild | rel: 1
+// CHECK-NOT: RelSpecialization
+
+  int notOverridingField = 0;
+
+// CHECK-LABEL: checLabelBreak
+  int checLabelBreak = 0;
+
+  int field = 0;
+// CHECK: [[@LINE-1]]:7 | field/C++ | field | c:@S@PseudoOverridesInSpecializations>#d#I@FI@field | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | field | c:@ST>2#T#T@PseudoOverridesInSpecializations@FI@field
+
+  static double variable;
+// CHECK: [[@LINE-1]]:17 | static-property/C++ | variable | c:@S@PseudoOverridesInSpecializations>#d#I@variable | __ZN32PseudoOverridesInSpecializationsIdiE8variableE | Decl,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | variable | c:@ST>2#T#T@PseudoOverridesInSpecializations@variable
+
+  typedef double TypeDef;
+// CHECK: [[@LINE-1]]:18 | type-alias/C | TypeDef | c:index-source.cpp@S@PseudoOverridesInSpecializations>#d#I@T@TypeDef | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | TypeDef | c:index-source.cpp@ST>2#T#T@PseudoOverridesInSpecializations@T@TypeDef
+
+  using TypeAlias = int;
+// CHECK: [[@LINE-1]]:9 | type-alias/C++ | TypeAlias | c:@S@PseudoOverridesInSpecializations>#d#I@TypeAlias | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | TypeAlias | c:@ST>2#T#T@PseudoOverridesInSpecializations@TypeAlias
+
+  enum anEnum { };
+// CHECK: [[@LINE-1]]:8 | enum/C | anEnum | c:@S@PseudoOverridesInSpecializations>#d#I@E@anEnum | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | anEnum | c:@ST>2#T#T@PseudoOverridesInSpecializations@E@anEnum
+  class Struct { };
+// CHECK: [[@LINE-1]]:9 | class/C++ | Struct | c:@S@PseudoOverridesInSpecializations>#d#I@S@Struct | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | Struct | c:@ST>2#T#T@PseudoOverridesInSpecializations@S@Struct
+  union Union { };
+// CHECK: [[@LINE-1]]:9 | union/C | Union | c:@S@PseudoOverridesInSpecializations>#d#I@U@Union | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | Union | c:@ST>2#T#T@PseudoOverridesInSpecializations@U@Union
+
+  struct TypealiasOrRecord { };
+// CHECK: [[@LINE-1]]:10 | struct/C | TypealiasOrRecord | c:@S@PseudoOverridesInSpecializations>#d#I@S@TypealiasOrRecord | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | TypealiasOrRecord | c:@ST>2#T#T@PseudoOverridesInSpecializations@TypealiasOrRecord
+
+  template<typename U> struct InnerTemplate { };
+// CHECK: [[@LINE-1]]:31 | struct(Gen)/C++ | InnerTemplate | c:@S@PseudoOverridesInSpecializations>#d#I@ST>1#T@InnerTemplate | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | InnerTemplate | c:@ST>2#T#T@PseudoOverridesInSpecializations@ST>1#T@InnerTemplate
+  template<typename U> struct InnerTemplate <U*> { };
+};
+
+template<typename S>
+class PseudoOverridesInSpecializations<float, S> {
+  typedef float TypealiasOrRecord;
+// CHECK: [[@LINE-1]]:17 | type-alias/C | TypealiasOrRecord | c:index-source.cpp@SP>1#T@PseudoOverridesInSpecializations>#f#t0.0@T@TypealiasOrRecord | <no-cgname> | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | TypealiasOrRecord | c:@ST>2#T#T@PseudoOverridesInSpecializations@TypealiasOrRecord
+};
+
+template<typename T, typename U>
+class ConflictingPseudoOverridesInSpecialization {
+  void foo(T x);
+  void foo(U x);
+};
+
+template<typename T>
+class ConflictingPseudoOverridesInSpecialization<int, T> {
+  void foo(T x);
+// CHECK: [[@LINE-1]]:8 | instance-method/C++ | foo | c:@SP>1#T@ConflictingPseudoOverridesInSpecialization>#I#t0.0@F@foo#S0_# | <no-cgname> | Decl,RelChild,RelSpecialization | rel: 3
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | foo | c:@ST>2#T#T@ConflictingPseudoOverridesInSpecialization@F@foo#t0.0#
+// CHECK-NEXT: RelSpecialization | foo | c:@ST>2#T#T@ConflictingPseudoOverridesInSpecialization@F@foo#t0.1#
+};
+
+template<typename T, typename U, int x>
+void functionSpecialization();
+
+template<typename T, typename U, int x>
+void functionSpecialization() { }
+// CHECK: [[@LINE-1]]:6 | function/C | functionSpecialization | c:@FT@>3#T#T#NIfunctionSpecialization#v# | <no-cgname> | Def | rel: 0
+
+template<>
+void functionSpecialization<int, int, 0>();
+// CHECK: [[@LINE-1]]:6 | function(Gen,TS)/C++ | functionSpecialization | c:@F@functionSpecialization<#I#I#VI0># | __Z22functionSpecializationIiiLi0EEvv | Decl,RelSpecialization | rel: 1
+// CHECK-NEXT: RelSpecialization | functionSpecialization | c:@FT@>3#T#T#NIfunctionSpecialization#v#
+
+template<>
+void functionSpecialization<int, int, 0>() { }
+// CHECK: [[@LINE-1]]:6 | function(Gen,TS)/C++ | functionSpecialization | c:@F@functionSpecialization<#I#I#VI0># | __Z22functionSpecializationIiiLi0EEvv | Def,RelSpecialization | rel: 1
+// CHECK-NEXT: RelSpecialization | functionSpecialization | c:@FT@>3#T#T#NIfunctionSpecialization#v#
+
+struct ContainsSpecializedMemberFunction {
+  template<typename T>
+  void memberSpecialization();
+};
+
+template<typename T>
+void ContainsSpecializedMemberFunction::memberSpecialization() {
+// CHECK: [[@LINE-1]]:41 | instance-method/C++ | memberSpecialization | c:@S@ContainsSpecializedMemberFunction@FT@>1#TmemberSpecialization#v# | <no-cgname> | Def,RelChild | rel: 1
+// CHECK-NEXT: RelChild
+}
+
+template<>
+void ContainsSpecializedMemberFunction::memberSpecialization<int>() {
+// CHECK: [[@LINE-1]]:41 | instance-method(Gen,TS)/C++ | memberSpecialization | c:@S@ContainsSpecializedMemberFunction@F@memberSpecialization<#I># | __ZN33ContainsSpecializedMemberFunction20memberSpecializationIiEEvv | Def,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
+// CHECK-NEXT: RelSpecialization | memberSpecialization | c:@S@ContainsSpecializedMemberFunction@FT@>1#TmemberSpecialization#v#
+}
+
+template<typename T>
+class SpecializationDecl;
+// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+
+template<typename T>
+class SpecializationDecl { };
+// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Def | rel: 0
+
+template<>
+class SpecializationDecl<int>;
+// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+
+template<>
+class SpecializationDecl<int> { };
+// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#I | <no-cgname> | Def,RelSpecialization | rel: 1
+// CHECK-NEXT: RelSpecialization | SpecializationDecl | c:@ST>1#T@SpecializationDecl
+// CHECK-NEXT: [[@LINE-3]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+
+template<typename T>
+class PartialSpecilizationClass<Cls, T>;
+// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass | <no-cgname> | Ref | rel: 0
+// CHECK-NEXT: [[@LINE-2]]:33 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
+
+template<>
+class PartialSpecilizationClass<Cls, Cls> : Cls { };
+// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#$@S@Cls#S0_ | <no-cgname> | Def,RelSpecialization | rel: 1
+// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass
+// CHECK-NEXT: [[@LINE-3]]:45 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#$@S@Cls#S0_
+// CHECK-NEXT: [[@LINE-5]]:7 | class(Gen)/C++ | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass | <no-cgname> | Ref | rel: 0
+// CHECK-NEXT: [[@LINE-6]]:33 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
+// CHECK-NEXT: [[@LINE-7]]:38 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
+
+template<typename T, int x>
+void functionSp() { }
+
+struct Record {
+  constexpr static int C = 2;
+};
+
+template<>
+void functionSp<SpecializationDecl<Cls>, Record::C>() {
+// CHECK: [[@LINE-1]]:6 | function(Gen,TS)/C++ | functionSp | c:@F@functionSp<#$@S@SpecializationDecl>#$@S@Cls#VI2># | __Z10functionSpI18SpecializationDeclI3ClsELi2EEvv | Def,RelSpecialization | rel: 1
+// CHECK:   RelSpecialization | functionSp | c:@FT@>2#T#NIfunctionSp#v#
+// CHECK: [[@LINE-3]]:17 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:36 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-5]]:50 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE
+// CHECK: [[@LINE-6]]:42 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+}
+
+template<typename T, int x>
+class ClassWithCorrectSpecialization { };
+
+template<>
+class ClassWithCorrectSpecialization<SpecializationDecl<Cls>, Record::C> { };
+// CHECK: [[@LINE-1]]:38 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-2]]:57 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-3]]:71 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read | rel: 0
+// CHECK: [[@LINE-4]]:63 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref | rel: 0
+
+namespace ns {
+// CHECK: [[@LINE-1]]:11 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Decl | rel: 0
+namespace inner {
+// CHECK: [[@LINE-1]]:11 | namespace/C++ | inner | c:@N@ns@N@inner | <no-cgname> | Decl,RelChild | rel: 1
+void func();
+
+}
+namespace innerAlias = inner;
+// CHECK: [[@LINE-1]]:11 | namespace-alias/C++ | innerAlias | c:@N@ns@NA@innerAlias | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE-2]]:24 | namespace/C++ | inner | c:@N@ns@N@inner | <no-cgname> | Ref,RelCont | rel: 1
+}
+
+namespace namespaceAlias = ::ns::innerAlias;
+// CHECK: [[@LINE-1]]:11 | namespace-alias/C++ | namespaceAlias | c:@NA@namespaceAlias | <no-cgname> | Decl | rel: 0
+// CHECK: [[@LINE-2]]:30 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:34 | namespace-alias/C++ | innerAlias | c:@N@ns@NA@innerAlias | <no-cgname> | Ref,RelCont | rel: 1
+
+void ::ns::inner::func() {
+// CHECK: [[@LINE-1]]:8 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:12 | namespace/C++ | inner | c:@N@ns@N@inner | <no-cgname> | Ref,RelCont | rel: 1
+  ns::innerAlias::func();
+// CHECK: [[@LINE-1]]:3 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:7 | namespace-alias/C++ | innerAlias | c:@N@ns@NA@innerAlias | <no-cgname> | Ref,RelCont | rel: 1
+}
+
+void innerUsingNamespace() {
+  using namespace ns;
+// CHECK: [[@LINE-1]]:19 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+  {
+    using namespace ns::innerAlias;
+// CHECK: [[@LINE-1]]:25 | namespace-alias/C++ | innerAlias | c:@N@ns@NA@innerAlias | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:21 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-3]]:21
+  }
+}
+
+void indexDefaultValueInDefn(Cls cls = Cls(gvi), Record param = Record()) {
+// CHECK: [[@LINE-1]]:40 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:44 | variable/C | gvi | c:@gvi | _gvi | Ref,Read,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-3]]:44
+// CHECK: [[@LINE-4]]:65 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-5]]:65
+}
+
+template<template <typename> class T>
+struct IndexDefaultValue {
+   IndexDefaultValue(int k = Record::C) {
+// CHECK: [[@LINE-1]]:38 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:30 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+   }
+};
+
+struct DeletedMethods {
+  DeletedMethods(const DeletedMethods &) = delete;
+// CHECK: [[@LINE-1]]:3 | constructor/cxx-copy-ctor/C++ | DeletedMethods | c:@S@DeletedMethods@F@DeletedMethods#&1$@S@DeletedMethods# | __ZN14DeletedMethodsC1ERKS_ | Def,RelChild | rel: 1
+// CHECK: RelChild | DeletedMethods | c:@S@DeletedMethods
+// CHECK: [[@LINE-3]]:24 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:3 | struct/C++ | DeletedMethods | c:@S@DeletedMethods | <no-cgname> | Ref,RelCont | rel: 1
+};
+
+namespace ns2 {
+template<typename T> struct ACollectionDecl { };
+}
+
+template<typename T = Cls,
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+         int x = Record::C,
+// CHECK: [[@LINE-1]]:26 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+// CHECK: [[@LINE-3]]:18 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+         template <typename> class Collection = ns2::ACollectionDecl>
+// CHECK: [[@LINE-1]]:49 | namespace/C++ | ns2 | c:@N@ns2 | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+// CHECK: [[@LINE-3]]:54 | struct(Gen)/C++ | ACollectionDecl | c:@N@ns2@ST>1#T@ACollectionDecl | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | TemplateDefaultValues | c:@ST>3#T#NI#t>1#T@TemplateDefaultValues
+struct TemplateDefaultValues { };
+
+template<typename T = Record,
+// CHECK: [[@LINE-1]]:23 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+         int x = sizeof(Cls)>
+// CHECK: [[@LINE-1]]:25 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+void functionTemplateDefaultValues() { }
+
+namespace ensureDefaultTemplateParamsAreRecordedOnce {
+
+template<typename T = Cls>
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-2]]:23
+void functionDecl();
+
+template<typename T>
+void functionDecl() { }
+
+template<typename T = Cls>
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-2]]:23
+class TagDecl;
+
+template<typename T>
+class TagDecl;
+
+template<typename T>
+class TagDecl { };
+
+template<typename T = Cls>
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+using TypeAlias = TagDecl<T>;
+
+template<typename T = Cls>
+// CHECK: [[@LINE-1]]:23 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE-2]]:23
+extern T varDecl;
+
+template<typename T>
+T varDecl = T();
+
+} // end namespace ensureDefaultTemplateParamsAreRecordedOnce
diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m
index 880028d..a64c34a 100644
--- a/test/Index/Core/index-source.m
+++ b/test/Index/Core/index-source.m
@@ -1,4 +1,5 @@
 // RUN: c-index-test core -print-source-symbols -- %s -target x86_64-apple-macosx10.7 | FileCheck %s
+// RUN: c-index-test core -print-source-symbols -include-locals -- %s -target x86_64-apple-macosx10.7 | FileCheck -check-prefix=LOCAL %s
 
 @interface Base
 // CHECK: [[@LINE-1]]:12 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Decl | rel: 0
@@ -13,10 +14,33 @@
 @end
 
 void foo();
-// CHECK: [[@LINE+3]]:6 | function/C | goo | c:@F@goo | _goo | Def | rel: 0
-// CHECK: [[@LINE+2]]:10 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+6]]:6 | function/C | goo | c:@F@goo | _goo | Def | rel: 0
+// CHECK: [[@LINE+5]]:10 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
 // CHECK-NEXT: RelCont | goo | c:@F@goo
+// CHECK-NOT: [[@LINE+3]]:16 | param
+// LOCAL: [[@LINE+2]]:16 | param(local)/C | b | [[b_USR:c:.*]] | _b | Def,RelChild | rel: 1
+// LOCAL-NEXT: RelChild | goo | c:@F@goo
 void goo(Base *b) {
+  // CHECK-NOT: [[@LINE+6]]:7 | variable
+  // LOCAL: [[@LINE+5]]:7 | variable(local)/C | x | [[x_USR:c:.*]] | _x | Def,RelCont | rel: 1
+  // LOCAL-NEXT: RelCont | goo | c:@F@goo
+  // CHECK-NOT: [[@LINE+3]]:11 | param
+  // LOCAL: [[@LINE+2]]:11 | param(local)/C | b | [[b_USR]] | _b | Ref,Read,RelCont | rel: 1
+  // LOCAL-NEXT: RelCont | x | [[x_USR]]
+  int x = b;
+  // CHECK-NOT: [[@LINE+5]]:7 | variable
+  // LOCAL: [[@LINE+4]]:7 | variable(local)/C | y | [[y_USR:c:.*]] | _y | Def,RelCont | rel: 1
+  // CHECK-NOT: [[@LINE+3]]:11 | variable
+  // LOCAL: [[@LINE+2]]:11 | variable(local)/C | x | [[x_USR]] | _x | Ref,Read,RelCont | rel: 1
+  // LOCAL-NEXT: RelCont | y | [[y_USR]]
+  int y = x;
+
+  // CHECK-NOT: [[@LINE+1]]:10 | struct
+  // LOCAL: [[@LINE+1]]:10 | struct(local)/C | Foo | c:{{.*}} | <no-cgname> | Def,RelCont | rel: 1
+  struct Foo {
+    int i;
+  };
+
   // CHECK: [[@LINE+2]]:3 | function/C | foo | c:@F@foo | _foo | Ref,Call,RelCall,RelCont | rel: 1
   // CHECK-NEXT: RelCall,RelCont | goo | c:@F@goo
   foo();
@@ -97,32 +121,79 @@
 @end
 
 @interface I2
-@property (readwrite) id prop;
+// CHECK: [[@LINE-1]]:12 | class/ObjC | I2 | [[I2_USR:.*]] | {{.*}} | Decl | rel: 0
 
-// CHECK: [[@LINE+4]]:63 | instance-property(IB,IBColl)/ObjC | buttons | c:objc(cs)I2(py)buttons | <no-cgname> | Decl,RelChild | rel: 1
-// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
+@property (readwrite) id prop;
+// CHECK: [[@LINE-1]]:26 | instance-method/acc-get/ObjC | prop | [[I2_prop_getter_USR:.*]] | -[I2 prop] | Decl,Dyn,Impl,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE-2]]:26 | instance-method/acc-set/ObjC | setProp: | [[I2_prop_setter_USR:.*]] | -[I2 setProp:] | Decl,Dyn,Impl,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE-3]]:26 | instance-property/ObjC | prop | [[I2_prop_USR:.*]] | <no-cgname> | Decl,RelChild | rel: 1
+
+@property (readwrite, getter=customGet, setter=customSet:) id unrelated;
+// CHECK: [[@LINE-1]]:30 | instance-method/acc-get/ObjC | customGet | {{.*}} | -[I2 customGet] | Decl,Dyn,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE-2]]:48 | instance-method/acc-set/ObjC | customSet: | {{.*}} | -[I2 customSet:] | Decl,Dyn,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE-3]]:63 | instance-property/ObjC | unrelated | {{.*}} | <no-cgname> | Decl,RelChild | rel: 1
+
+-(id)declaredGet;
+@property (readwrite, getter=declaredGet) id otherProp;
+// CHECK: [[@LINE-1]]:30 | instance-method/acc-get/ObjC | declaredGet | {{.*}} | -[I2 declaredGet] | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:6 | instance-method/acc-get/ObjC | declaredGet | {{.*}} | -[I2 declaredGet] | Decl,Dyn,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE-3]]:46 | instance-method/acc-set/ObjC | setOtherProp: | {{.*}} | -[I2 setOtherProp:] | Decl,Dyn,Impl,RelChild,RelAcc | rel: 2
+
+// CHECK: [[@LINE+4]]:63 | instance-property(IB,IBColl)/ObjC | buttons | [[buttons_USR:.*]] | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I2 | [[I2_USR]]
 // CHECK: [[@LINE+2]]:50 | class/ObjC | I1 | c:objc(cs)I1 | _OBJC_CLASS_$_I1 | Ref,RelCont,RelIBType | rel: 1
-// CHECK-NEXT: RelCont,RelIBType | buttons | c:objc(cs)I2(py)buttons
+// CHECK-NEXT: RelCont,RelIBType | buttons | [[buttons_USR]]
 @property (nonatomic, strong) IBOutletCollection(I1) NSArray *buttons;
 @end
 
-// CHECK: [[@LINE+2]]:17 | field/ObjC | _prop | c:objc(cs)I2@_prop | <no-cgname> | Def,Impl,RelChild | rel: 1
-// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
 @implementation I2
-// CHECK: [[@LINE+6]]:13 | instance-property/ObjC | prop | c:objc(cs)I2(py)prop | <no-cgname> | Ref,RelCont | rel: 1
-// CHECK-NEXT: RelCont | I2 | c:objc(cs)I2
-// CHECK: [[@LINE+4]]:13 | instance-method/acc-get/ObjC | prop | c:objc(cs)I2(im)prop | -[I2 prop] | Def,RelChild | rel: 1
-// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
-// CHECK: [[@LINE+2]]:13 | instance-method/acc-set/ObjC | setProp: | c:objc(cs)I2(im)setProp: | -[I2 setProp:] | Def,RelChild | rel: 1
-// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
+// CHECK: [[@LINE+9]]:13 | instance-property/ObjC | prop | [[I2_prop_USR:.*]] | <no-cgname> | Def,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I2 | [[I2_USR]]
+// CHECK-NEXT: RelAcc | _prop | c:objc(cs)I2@_prop
+// CHECK: [[@LINE+6]]:13 | instance-method/acc-get/ObjC | prop | [[I2_prop_getter_USR]] | -[I2 prop] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I2 | [[I2_USR]]
+// CHECK: [[@LINE+4]]:13 | instance-method/acc-set/ObjC | setProp: | [[I2_prop_setter_USR]] | -[I2 setProp:] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I2 | [[I2_USR]]
+// CHECK: [[@LINE+2]]:20 | field/ObjC | _prop | c:objc(cs)I2@_prop | <no-cgname> | Def,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I2 | [[I2_USR]]
 @synthesize prop = _prop;
 
-// CHECK: [[@LINE+5]]:12 | instance-method(IB)/ObjC | doAction:foo: | c:objc(cs)I2(im)doAction:foo: | -[I2 doAction:foo:] | Def,Dyn,RelChild | rel: 1
-// CHECK-NEXT: RelChild | I2 | c:objc(cs)I2
-// CHECK: [[@LINE+3]]:22 | class/ObjC | I1 | c:objc(cs)I1 | _OBJC_CLASS_$_I1 | Ref,RelCont,RelIBType | rel: 1
-// CHECK-NEXT: RelCont,RelIBType | doAction:foo: | c:objc(cs)I2(im)doAction:foo:
-// CHECK: [[@LINE+1]]:39 | class/ObjC | I1 | c:objc(cs)I1 | _OBJC_CLASS_$_I1 | Ref,RelCont | rel: 1
--(IBAction)doAction:(I1 *)sender foo:(I1 *)bar {}
+// CHECK: [[@LINE+11]]:12 | instance-method(IB)/ObjC | doAction:foo: | [[doAction_USR:.*]] | -[I2 doAction:foo:] | Def,Dyn,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I2 | [[I2_USR]]
+// CHECK: [[@LINE+9]]:22 | class/ObjC | I1 | c:objc(cs)I1 | _OBJC_CLASS_$_I1 | Ref,RelCont,RelIBType | rel: 1
+// CHECK-NEXT: RelCont,RelIBType | doAction:foo: | [[doAction_USR]]
+// CHECK-NOT: [[@LINE+7]]:27 | param
+// LOCAL: [[@LINE+6]]:27 | param(local)/C | sender | c:{{.*}} | _sender | Def,RelChild | rel: 1
+// LOCAL-NEXT: RelChild | doAction:foo: | [[doAction_USR:.*]]
+// CHECK: [[@LINE+4]]:39 | class/ObjC | I1 | c:objc(cs)I1 | _OBJC_CLASS_$_I1 | Ref,RelCont | rel: 1
+// CHECK-NOT: [[@LINE+3]]:44 | param
+// LOCAL: [[@LINE+2]]:44 | param(local)/C | bar | c:{{.*}} | _bar | Def,RelChild | rel: 1
+// LOCAL-NEXT: RelChild | doAction:foo: | [[doAction_USR]]
+-(IBAction)doAction:(I1 *)sender foo:(I1 *)bar {
+  [self prop];
+  // CHECK: [[@LINE-1]]:9 | instance-method/acc-get/ObjC | prop | [[I2_prop_getter_USR]] | -[I2 prop] | Ref,Call,Dyn,RelRec,RelCall,RelCont | rel: 2
+  // CHECK-NEXT: RelCall,RelCont | doAction:foo: | [[doAction_USR]]
+  // CHECK-NEXT: RelRec | I2 | [[I2_USR]]
+
+  [self setProp: bar];
+  // CHECK: [[@LINE-1]]:9 | instance-method/acc-set/ObjC | setProp: | [[I2_prop_setter_USR]] | -[I2 setProp:] | Ref,Call,Dyn,RelRec,RelCall,RelCont | rel: 2
+  // CHECK-NEXT: RelCall,RelCont | doAction:foo: | [[doAction_USR]]
+  // CHECK-NEXT: RelRec | I2 | [[I2_USR]]
+
+  self.prop;
+  // CHECK: [[@LINE-1]]:8 | instance-property/ObjC | prop | [[I2_prop_USR]] | <no-cgname> | Ref,RelCont | rel: 1
+  // CHECK-NEXT: RelCont | doAction:foo: | [[doAction_USR]]
+  // CHECK: [[@LINE-3]]:8 | instance-method/acc-get/ObjC | prop | [[I2_prop_getter_USR]] | -[I2 prop] | Ref,Call,Dyn,Impl,RelRec,RelCall,RelCont | rel: 2
+  // CHECK-NEXT: RelCall,RelCont | doAction:foo: | [[doAction_USR]]
+  // CHECK-NEXT: RelRec | I2 | [[I2_USR]]
+
+  self.prop = self.prop;
+  // CHECK: [[@LINE-1]]:8 | instance-property/ObjC | prop | [[I2_prop_USR]] | <no-cgname> | Ref,Writ,RelCont | rel: 1
+  // CHECK-NEXT: RelCont | doAction:foo: | [[doAction_USR]]
+  // CHECK:[[@LINE-3]]:8 | instance-method/acc-set/ObjC | setProp: | [[I2_prop_setter_USR]] | -[I2 setProp:] | Ref,Call,Dyn,Impl,RelRec,RelCall,RelCont | rel: 2
+  // CHECK-NEXT: RelCall,RelCont | doAction:foo: | [[doAction_USR]]
+  // CHECK-NEXT: RelRec | I2 | [[I2_USR]]
+}
 @end
 
 @interface I3
@@ -131,18 +202,20 @@
 // CHECK-NEXT: RelChild | I3 | c:objc(cs)I3
 // CHECK-NEXT: RelAcc | prop | c:objc(cs)I3(py)prop
 -(id)prop;
-// CHECK: [[@LINE+3]]:8 | instance-method/acc-set/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Decl,Dyn,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE+4]]:8 | instance-method/acc-set/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Decl,Dyn,RelChild,RelAcc | rel: 2
 // CHECK-NEXT: RelChild | I3 | c:objc(cs)I3
 // CHECK-NEXT: RelAcc | prop | c:objc(cs)I3(py)prop
+// LOCAL-NOT: [[@LINE+1]]:20 | param
 -(void)setProp:(id)p;
 @end
 
 // CHECK: [[@LINE+1]]:17 | class/ObjC | I3 | c:objc(cs)I3 | <no-cgname> | Def | rel: 0
 @implementation I3
-// CHECK: [[@LINE+4]]:13 | instance-property/ObjC | prop | c:objc(cs)I3(py)prop | <no-cgname> | Ref,RelCont | rel: 1
-// CHECK-NEXT: RelCont | I3 | c:objc(cs)I3
-// CHECK: [[@LINE+2]]:13 | instance-method/acc-get/ObjC | prop | c:objc(cs)I3(im)prop | -[I3 prop] | Def,RelChild | rel: 1
-// CHECK: [[@LINE+1]]:13 | instance-method/acc-set/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Def,RelChild | rel: 1
+// CHECK: [[@LINE+5]]:13 | instance-property/ObjC | prop | c:objc(cs)I3(py)prop | <no-cgname> | Def,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I3 | c:objc(cs)I3
+// CHECK-NEXT: RelAcc | _prop | c:objc(cs)I3@_prop
+// CHECK: [[@LINE+2]]:13 | instance-method/acc-get/ObjC | prop | c:objc(cs)I3(im)prop | -[I3 prop] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:13 | instance-method/acc-set/ObjC | setProp: | c:objc(cs)I3(im)setProp: | -[I3 setProp:] | Def,Dyn,Impl,RelChild | rel: 1
 @synthesize prop = _prop;
 @end
 
@@ -155,7 +228,7 @@
 @end
 
 // CHECK: [[@LINE+2]]:17 | class/ObjC | I3 | c:objc(cs)I3 | _OBJC_CLASS_$_I3 | Ref,RelCont | rel: 1
-// CHECK: [[@LINE+1]]:20 | extension/ObjC | I3 | c:objc(cy)I3@bar | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+1]]:20 | extension/ObjC | bar | c:objc(cy)I3@bar | <no-cgname> | Def | rel: 0
 @implementation I3(bar)
 @end
 
@@ -169,16 +242,174 @@
 @protocol MyEnumerating
 @end
 
-// CHECK: [[@LINE+4]]:41 | type-alias/C | MyEnumerator | c:index-source.m@T@MyEnumerator | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+4]]:41 | type-alias/C | MyEnumerator | [[MyEnumerator_USR:.*]] | <no-cgname> | Def | rel: 0
 // CHECK: [[@LINE+3]]:26 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,RelCont | rel: 1
 // CHECK: [[@LINE+2]]:9 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,RelCont | rel: 1
 // CHECK: [[@LINE+1]]:18 | class/ObjC | Base | c:objc(cs)Base | _OBJC_CLASS_$_Base | Ref,RelCont | rel: 1
 typedef MyGenCls<Base *><MyEnumerating> MyEnumerator;
 
-// CHECK: [[@LINE+5]]:12 | class/ObjC | PermanentEnumerator | c:objc(cs)PermanentEnumerator | _OBJC_CLASS_$_PermanentEnumerator | Decl | rel: 0
-// CHECK: [[@LINE+4]]:34 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,RelBase,RelCont | rel: 1
-// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | c:objc(cs)PermanentEnumerator
-// CHECK: [[@LINE+2]]:34 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,RelBase,RelCont | rel: 1
-// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | c:objc(cs)PermanentEnumerator
+// CHECK: [[@LINE+7]]:12 | class/ObjC | PermanentEnumerator | [[PermanentEnumerator_USR:.*]] | _OBJC_CLASS_$_PermanentEnumerator | Decl | rel: 0
+// CHECK: [[@LINE+6]]:34 | type-alias/C | MyEnumerator | [[MyEnumerator_USR]] | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | PermanentEnumerator | [[PermanentEnumerator_USR]]
+// CHECK: [[@LINE+4]]:34 | class/ObjC | MyGenCls | c:objc(cs)MyGenCls | _OBJC_CLASS_$_MyGenCls | Ref,Impl,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | [[PermanentEnumerator_USR]]
+// CHECK: [[@LINE+2]]:34 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,Impl,RelBase,RelCont | rel: 1
+// CHECK-NEXT: RelBase,RelCont | PermanentEnumerator | [[PermanentEnumerator_USR]]
 @interface PermanentEnumerator : MyEnumerator
 @end
+
+// CHECK: [[@LINE+2]]:48 | protocol/ObjC | Prot1 | c:objc(pl)Prot1 | <no-cgname> | Ref,RelBase,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:35 | protocol/ObjC | MyEnumerating | c:objc(pl)MyEnumerating | <no-cgname> | Ref,Impl,RelBase,RelCont | rel: 1
+@interface PermanentEnumerator2 : MyEnumerator<Prot1>
+@end
+
+@interface I4
+@property id foo;
+@end
+
+@implementation I4 {
+  id _blahfoo; // explicit def
+  // CHECK: [[@LINE-1]]:6 | field/ObjC | _blahfoo | c:objc(cs)I4@_blahfoo | <no-cgname> | Def,RelChild | rel: 1
+}
+@synthesize foo = _blahfoo; // ref of field _blahfoo
+// CHECK: [[@LINE-1]]:13 | instance-property/ObjC | foo | c:objc(cs)I4(py)foo | <no-cgname> | Def,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I4 | c:objc(cs)I4
+// CHECK-NEXT: RelAcc | _blahfoo | c:objc(cs)I4@_blahfoo
+// CHECK: [[@LINE-4]]:13 | instance-method/acc-get/ObjC | foo | c:objc(cs)I4(im)foo | -[I4 foo] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I4 | c:objc(cs)I4
+// CHECK: [[@LINE-6]]:13 | instance-method/acc-set/ObjC | setFoo: | c:objc(cs)I4(im)setFoo: | -[I4 setFoo:] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I4 | c:objc(cs)I4
+// CHECK: [[@LINE-8]]:19 | field/ObjC | _blahfoo | c:objc(cs)I4@_blahfoo | <no-cgname> | Ref | rel: 0
+
+-(void)method {
+  _blahfoo = 0;
+  // CHECK: [[@LINE-1]]:3 | field/ObjC | _blahfoo | c:objc(cs)I4@_blahfoo | <no-cgname> | Ref,Writ,RelCont | rel: 1
+}
+@end
+
+@interface I5
+@property id foo;
+@end
+
+@implementation I5
+@synthesize foo = _blahfoo; // explicit def of field _blahfoo
+// CHECK: [[@LINE-1]]:13 | instance-property/ObjC | foo | c:objc(cs)I5(py)foo | <no-cgname> | Def,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I5 | c:objc(cs)I5
+// CHECK-NEXT: RelAcc | _blahfoo | c:objc(cs)I5@_blahfoo
+// CHECK: [[@LINE-4]]:13 | instance-method/acc-get/ObjC | foo | c:objc(cs)I5(im)foo | -[I5 foo] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I5 | c:objc(cs)I5
+// CHECK: [[@LINE-6]]:13 | instance-method/acc-set/ObjC | setFoo: | c:objc(cs)I5(im)setFoo: | -[I5 setFoo:] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I5 | c:objc(cs)I5
+// CHECK: [[@LINE-8]]:19 | field/ObjC | _blahfoo | c:objc(cs)I5@_blahfoo | <no-cgname> | Def,RelChild | rel: 1
+
+-(void)method {
+  _blahfoo = 0;
+  // CHECK: [[@LINE-1]]:3 | field/ObjC | _blahfoo | c:objc(cs)I5@_blahfoo | <no-cgname> | Ref,Writ,RelCont | rel: 1
+}
+@end
+
+@interface I6
+@property id foo;
+@end
+
+@implementation I6
+@synthesize foo; // implicit def of field foo
+// CHECK: [[@LINE-1]]:13 | instance-property/ObjC | foo | c:objc(cs)I6(py)foo | <no-cgname> | Def,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I6 | c:objc(cs)I6
+// CHECK-NEXT: RelAcc | foo | c:objc(cs)I6@foo
+// CHECK: [[@LINE-4]]:13 | instance-method/acc-get/ObjC | foo | c:objc(cs)I6(im)foo | -[I6 foo] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I6 | c:objc(cs)I6
+// CHECK: [[@LINE-6]]:13 | instance-method/acc-set/ObjC | setFoo: | c:objc(cs)I6(im)setFoo: | -[I6 setFoo:] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I6 | c:objc(cs)I6
+// CHECK: [[@LINE-8]]:13 | field/ObjC | foo | c:objc(cs)I6@foo | <no-cgname> | Def,Impl,RelChild | rel: 1
+
+-(void)method {
+  foo = 0;
+  // CHECK: [[@LINE-1]]:3 | field/ObjC | foo | c:objc(cs)I6@foo | <no-cgname> | Ref,Writ,RelCont | rel: 1
+}
+@end
+
+@interface I7
+@property id foo;
+@end
+
+@implementation I7 // implicit def of field _foo
+// CHECK: [[@LINE-1]]:17 | instance-property/ObjC | foo | c:objc(cs)I7(py)foo | <no-cgname> | Def,Impl,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | I7 | c:objc(cs)I7
+// CHECK-NEXT: RelAcc | _foo | c:objc(cs)I7@_foo
+// CHECK: [[@LINE-4]]:17 | instance-method/acc-get/ObjC | foo | c:objc(cs)I7(im)foo | -[I7 foo] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I7 | c:objc(cs)I7
+// CHECK: [[@LINE-6]]:17 | instance-method/acc-set/ObjC | setFoo: | c:objc(cs)I7(im)setFoo: | -[I7 setFoo:] | Def,Dyn,Impl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | I7 | c:objc(cs)I7
+// CHECK: [[@LINE-8]]:17 | field/ObjC | _foo | c:objc(cs)I7@_foo | <no-cgname> | Def,Impl,RelChild | rel: 1
+
+-(void)method {
+  _foo = 0;
+// CHECK: [[@LINE-1]]:3 | field/ObjC | _foo | c:objc(cs)I7@_foo | <no-cgname> | Ref,Writ,RelCont | rel: 1
+}
+@end
+
+#define NS_ENUM(_name, _type) enum _name:_type _name; enum _name : _type
+
+typedef NS_ENUM(AnotherEnum, int) {
+// CHECK-NOT: [[@LINE-1]]:17 | type-alias/C | AnotherEnum |
+// CHECK-NOT: [[@LINE-2]]:17 | {{.*}} | Ref
+// CHECK: [[@LINE-3]]:17 | enum/C | AnotherEnum | [[AnotherEnum_USR:.*]] | {{.*}} | Def | rel: 0
+  AnotherEnumFirst = 0,
+  AnotherEnumSecond = 1,
+  AnotherEnumThird = 2,
+};
+
+AnotherEnum anotherT;
+// CHECK: [[@LINE-1]]:1 | enum/C | AnotherEnum | [[AnotherEnum_USR]] | {{.*}} | Ref,RelCont | rel: 1
+enum AnotherEnum anotherE;
+// CHECK: [[@LINE-1]]:6 | enum/C | AnotherEnum | [[AnotherEnum_USR]] | {{.*}} | Ref,RelCont | rel: 1
+
+#define TRANSPARENT(_name) struct _name _name; struct _name
+#define OPAQUE(_name) struct _name *_name; struct _name
+
+typedef TRANSPARENT(AStruct) {
+  int x;
+};
+
+AStruct aStructT;
+// CHECK: [[@LINE-1]]:1 | struct/C | AStruct | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
+struct AStruct aStructS;
+// CHECK: [[@LINE-1]]:8 | struct/C | AStruct | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
+
+typedef OPAQUE(Separate) {
+  int x;
+};
+
+Separate separateT;
+// CHECK: [[@LINE-1]]:1 | type-alias/C | Separate | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
+struct Separate separateE;
+// CHECK: [[@LINE-1]]:8 | struct/C | Separate | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
+
+@interface ClassReceivers
+
+@property(class) int p1;
++ (int)implicit;
++ (void)setImplicit:(int)x;
+
+@end
+
+void classReceivers() {
+  ClassReceivers.p1 = 0;
+// CHECK: [[@LINE-1]]:3 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:18 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Ref,Writ,RelCont | rel: 1
+// CHECK-NEXT: RelCont | classReceivers | c:@F@classReceivers
+// CHECK: [[@LINE-4]]:18 | class-method/ObjC | setP1: | c:objc(cs)ClassReceivers(cm)setP1: | +[ClassReceivers setP1:] | Ref,Call,Impl,RelCall,RelCont | rel: 1
+// CHECK-NEXT: RelCall,RelCont | classReceivers | c:@F@classReceivers
+  (void)ClassReceivers.p1;
+// CHECK: [[@LINE-1]]:9 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:24 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | classReceivers | c:@F@classReceivers
+// CHECK: [[@LINE-4]]:24 | class-method/ObjC | p1 | c:objc(cs)ClassReceivers(cm)p1 | +[ClassReceivers p1] | Ref,Call,Impl,RelCall,RelCont | rel: 1
+// CHECK-NEXT: RelCall,RelCont | classReceivers | c:@F@classReceivers
+
+  ClassReceivers.implicit = 0;
+// CHECK: [[@LINE-1]]:3 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+  (void)ClassReceivers.implicit;
+// CHECK: [[@LINE-1]]:9 | class/ObjC | ClassReceivers | c:objc(cs)ClassReceivers | _OBJC_CLASS_$_ClassReceivers | Ref,RelCont | rel: 1
+}
diff --git a/test/Index/Core/index-subkinds.m b/test/Index/Core/index-subkinds.m
index 15d60b1..5eea046 100644
--- a/test/Index/Core/index-subkinds.m
+++ b/test/Index/Core/index-subkinds.m
@@ -28,11 +28,11 @@
 
 // CHECK: [[@LINE+3]]:12 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelExt,RelCont | rel: 1
 // CHECK-NEXT: RelExt,RelCont | cat | c:objc(cy)MyTestCase@cat
-// CHECK: [[@LINE+1]]:23 | extension/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Decl | rel: 0
+// CHECK: [[@LINE+1]]:23 | extension(test)/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Decl | rel: 0
 @interface MyTestCase(cat)
 @end
 // CHECK: [[@LINE+2]]:17 | class(test)/ObjC | MyTestCase | c:objc(cs)MyTestCase | _OBJC_CLASS_$_MyTestCase | Ref,RelCont | rel: 1
-// CHECK: [[@LINE+1]]:28 | extension/ObjC | MyTestCase | c:objc(cy)MyTestCase@cat | <no-cgname> | Def | rel: 0
+// CHECK: [[@LINE+1]]:28 | extension(test)/ObjC | cat | c:objc(cy)MyTestCase@cat | <no-cgname> | Def | rel: 0
 @implementation MyTestCase(cat)
 // CHECK: [[@LINE+1]]:9 | instance-method(test)/ObjC | testInCat | c:objc(cs)MyTestCase(im)testInCat | -[MyTestCase(cat) testInCat] | Def,Dyn,RelChild | rel: 1
 - (void)testInCat {}
@@ -42,7 +42,7 @@
 @class NSButton;
 @interface IBCls
 
-// CHECK: [[@LINE+2]]:34 | instance-method/acc-get/ObjC | prop | c:objc(cs)IBCls(im)prop | -[IBCls prop] | Decl,Dyn,RelChild,RelAcc | rel: 2
+// CHECK: [[@LINE+2]]:34 | instance-method/acc-get/ObjC | prop | c:objc(cs)IBCls(im)prop | -[IBCls prop] | Decl,Dyn,Impl,RelChild,RelAcc | rel: 2
 // CHECK: [[@LINE+1]]:34 | instance-property(IB)/ObjC | prop | c:objc(cs)IBCls(py)prop | <no-cgname> | Decl,RelChild | rel: 1
 @property (readonly) IBOutlet id prop;
 // CHECK: [[@LINE+1]]:54 | instance-property(IB,IBColl)/ObjC | propColl | c:objc(cs)IBCls(py)propColl | <no-cgname> | Decl,RelChild | rel: 1
diff --git a/test/Index/Core/index-system.mm b/test/Index/Core/index-system.mm
new file mode 100644
index 0000000..2ad31fa
--- /dev/null
+++ b/test/Index/Core/index-system.mm
@@ -0,0 +1,3 @@
+// RUN: c-index-test core -print-source-symbols -- %s -isystem %S/Inputs/sys | FileCheck %S/Inputs/sys/system-head.h
+
+#include "system-head.h"
diff --git a/test/Index/Core/index-with-module.m b/test/Index/Core/index-with-module.m
index e50b247..c83de63 100644
--- a/test/Index/Core/index-with-module.m
+++ b/test/Index/Core/index-with-module.m
@@ -1,5 +1,5 @@
 // RUN: rm -rf %t.mcp
-// RUN: c-index-test core -print-source-symbols -- %s -I %S/Inputs/module -fmodules -fmodules-cache-path=%t.mcp | FileCheck %s
+// RUN: c-index-test core -print-source-symbols -dump-imported-module-files -- %s -I %S/Inputs/module -fmodules -fmodules-cache-path=%t.mcp | FileCheck %s
 
 // CHECK: [[@LINE+1]]:9 | module/C | ModA | Decl |
 @import ModA;
@@ -10,3 +10,9 @@
   // CHECK: [[@LINE+1]]:3 | function/C | ModA_func | c:@F@ModA_func | {{.*}} | Ref,Call,RelCall,RelCont | rel: 1
   ModA_func();
 }
+
+// CHECK: ==== Module ModA ====
+// CHECK: 2:6 | function/C | ModA_func | c:@F@ModA_func | {{.*}} | Decl | rel: 0
+// CHECK: ---- Module Inputs ----
+// CHECK: user | {{.*}}ModA.h
+// CHECK: user | {{.*}}module.modulemap
diff --git a/test/Index/allow-editor-placeholders.cpp b/test/Index/allow-editor-placeholders.cpp
new file mode 100644
index 0000000..5a7207d
--- /dev/null
+++ b/test/Index/allow-editor-placeholders.cpp
@@ -0,0 +1,5 @@
+// RUN: c-index-test -test-load-source all %s 2>&1 | FileCheck %s
+
+<#placeholder#>;
+
+// CHECK-NOT: error
diff --git a/test/Index/comment-cplus-decls.cpp b/test/Index/comment-cplus-decls.cpp
index d4f968f..4c9ce88 100644
--- a/test/Index/comment-cplus-decls.cpp
+++ b/test/Index/comment-cplus-decls.cpp
@@ -96,7 +96,7 @@
     friend void ns::f(int a);
   };
 }
-// CHECK: <Declaration>friend void f(int a)</Declaration>
+// CHECK: <Declaration>friend void ns::f(int a)</Declaration>
 
 namespace test1 {
   template <class T> struct Outer {
@@ -109,7 +109,7 @@
     };
   };
 }
-// CHECK: <Declaration>friend void foo(T)</Declaration>
+// CHECK: <Declaration>friend void Outer&lt;T&gt;::foo(T)</Declaration>
 
 namespace test2 {
   namespace foo {
@@ -123,7 +123,7 @@
     friend void ::test2::foo::Func(int x);
   };
 }
-// CHECK: <Declaration>friend void Func(int x)</Declaration>
+// CHECK: <Declaration>friend void ::test2::foo::Func(int x)</Declaration>
 
 namespace test3 {
   template<class T> class vector {
@@ -143,7 +143,7 @@
   };
 }
 // CHECK: <Declaration>void f(const T &amp;t = T())</Declaration>
-// CHECK: <Declaration>friend void f(const test3::A &amp;)</Declaration>
+// CHECK: <Declaration>friend void vector&lt;A&gt;::f(const test3::A &amp;)</Declaration>
 
 class MyClass
 {
diff --git a/test/Index/complete-available.m b/test/Index/complete-available.m
new file mode 100644
index 0000000..8267dbd
--- /dev/null
+++ b/test/Index/complete-available.m
@@ -0,0 +1,20 @@
+/* The run lines are below, because this test is line- and
+   column-number sensitive. */
+void atAvailable() {
+  if (@available(macOS 10.10, *)) {
+
+  }
+  if (__builtin_available(iOS 8, *)) {
+  }
+}
+
+// RUN: c-index-test -code-completion-at=%s:4:18 %s | FileCheck -check-prefix=CHECK %s
+// RUN: c-index-test -code-completion-at=%s:7:27 %s | FileCheck -check-prefix=CHECK %s
+// CHECK: {TypedText iOS} (40)
+// CHECK: {TypedText iOSApplicationExtension} (40)
+// CHECK: {TypedText macOS} (40)
+// CHECK: {TypedText macOSApplicationExtension} (40)
+// CHECK: {TypedText tvOS} (40)
+// CHECK: {TypedText tvOSApplicationExtension} (40)
+// CHECK: {TypedText watchOS} (40)
+// CHECK: {TypedText watchOSApplicationExtension} (40)
diff --git a/test/Index/complete-block-properties.m b/test/Index/complete-block-properties.m
index 4697703..a754712 100644
--- a/test/Index/complete-block-properties.m
+++ b/test/Index/complete-block-properties.m
@@ -68,8 +68,8 @@
 // RUN: c-index-test -code-completion-at=%s:65:6 %s | FileCheck -check-prefix=CHECK-CC2 %s
 //CHECK-CC2: ObjCInstanceMethodDecl:{ResultType void (^)(void)}{TypedText blockProperty} (35)
 //CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType BarBlock}{TypedText blockProperty2} (35)
-//CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlockProperty2:}{Placeholder BarBlock blockProperty2} (35)
-//CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlockProperty:}{Placeholder void (^)(void)blockProperty} (35)
+//CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlockProperty2:}{Placeholder ^int(int *)blockProperty2} (35)
+//CHECK-CC2-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlockProperty:}{Placeholder ^(void)blockProperty} (35)
 
 @interface ClassProperties
 
@@ -86,3 +86,9 @@
 //CHECK-CC3: ObjCPropertyDecl:{ResultType void}{TypedText explicit}{LeftParen (}{RightParen )} (35)
 //CHECK-CC3-NEXT: ObjCPropertyDecl:{ResultType void (^)()}{TypedText explicit}{Equal  = }{Placeholder ^(void)} (38)
 //CHECK-CC3-NEXT: ObjCPropertyDecl:{ResultType void}{TypedText explicitReadonly}{LeftParen (}{RightParen )} (35)
+
+void implicitSetterBlockPlaceholder(Test* test) {
+  [test setBlock: ^{}];
+}
+// RUN: c-index-test -code-completion-at=%s:91:9 %s | FileCheck -check-prefix=CHECK-CC4 %s
+// CHECK-CC4: ObjCInstanceMethodDecl:{ResultType void}{TypedText setBlocker:}{Placeholder ^Foo(int x, Foo y, FooBlock foo)blocker} (37)
diff --git a/test/Index/complete-cached-globals.cpp b/test/Index/complete-cached-globals.cpp
new file mode 100644
index 0000000..791faf2
--- /dev/null
+++ b/test/Index/complete-cached-globals.cpp
@@ -0,0 +1,25 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test.
+
+namespace SomeNamespace {
+    class SomeClass {
+    };
+    void SomeFunction();
+}
+
+using SomeNamespace::SomeClass;
+using SomeNamespace::SomeFunction;
+
+static void foo() {
+  return;
+}
+
+// rdar://23454249
+
+// RUN: c-index-test -code-completion-at=%s:14:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:14:3 %s | FileCheck -check-prefix=CHECK-CC1 %s
+
+// CHECK-CC1: ClassDecl:{TypedText SomeClass} (50)
+// CHECK-CC1: FunctionDecl:{ResultType void}{TypedText SomeFunction}{LeftParen (}{RightParen )} (50)
+// CHECK-CC1-NOT: {Text SomeNamespace::}{TypedText SomeClass}
+// CHECK-CC1-NOT: {Text SomeNamespace::}{TypedText SomeFunction}
diff --git a/test/Index/complete-objc-message.m b/test/Index/complete-objc-message.m
index e3fce6b..c2b0670 100644
--- a/test/Index/complete-objc-message.m
+++ b/test/Index/complete-objc-message.m
@@ -346,3 +346,54 @@
 
 // RUN: c-index-test -code-completion-at=%s:197:6 %s | FileCheck -check-prefix=CHECK-NULLABLE %s
 // CHECK-NULLABLE: ObjCInstanceMethodDecl:{ResultType A * _Nonnull}{TypedText method:}{Placeholder (nullable A *)}
+
+// rdar://28012953
+// Code completion results should include instance methods from RootProtocol and
+// RootClass when completing a method invocation for a RootClass object because
+// RootClasses metaclass subclasses from RootClass (i.e. RootClass is actually
+// an instance of RootClass).
+
+@protocol SubRootProtocol
+
+- (void)subProtocolInstanceMethod;
+
+@end
+
+@protocol RootProtocol <SubRootProtocol>
+
+- (void)protocolInstanceMethod;
++ (void)protocolClassMethod;
+
+@end
+
+@interface RootClass <RootProtocol>
+
+- (void)instanceMethod;
++ (void)classMethod;
+
+@end
+
+@protocol RootCategoryProtocol
+
+- (void)categoryProtocolInstanceMethod;
+
+@end
+
+@interface RootClass (Cat) <RootCategoryProtocol>
+
+- (void)categoryInstanceMethod;
+
+@end
+
+void completeAllTheRootThings() {
+  [RootClass classMethod];
+}
+
+// RUN: c-index-test -code-completion-at=%s:389:14 %s | FileCheck -check-prefix=CHECK-ROOT %s
+// CHECK-ROOT: ObjCInstanceMethodDecl:{ResultType void}{TypedText categoryInstanceMethod} (35)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText categoryProtocolInstanceMethod} (37)
+// CHECK-ROOT-NEXT: ObjCClassMethodDecl:{ResultType void}{TypedText classMethod} (35)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText instanceMethod} (35)
+// CHECK-ROOT-NEXT: ObjCClassMethodDecl:{ResultType void}{TypedText protocolClassMethod} (37)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText protocolInstanceMethod} (37)
+// CHECK-ROOT-NEXT: ObjCInstanceMethodDecl:{ResultType void}{TypedText subProtocolInstanceMethod} (37)
diff --git a/test/Index/cursor-dynamic-call.mm b/test/Index/cursor-dynamic-call.mm
index a926c3d..33d1c68 100644
--- a/test/Index/cursor-dynamic-call.mm
+++ b/test/Index/cursor-dynamic-call.mm
@@ -49,6 +49,14 @@
   id o = [[Test alloc] init];
 }
 
+@interface Test2 : NSObject
+@property (assign) id someProp;
+@end
+
+void test3(Test2 *o) {
+  id v = o.someProp;
+}
+
 // RUN: c-index-test -cursor-at=%s:8:11 \
 // RUN:              -cursor-at=%s:9:11 \
 // RUN:              -cursor-at=%s:25:11 \
@@ -59,6 +67,7 @@
 // RUN:              -cursor-at=%s:36:9 \
 // RUN:              -cursor-at=%s:37:9 \
 // RUN:              -cursor-at=%s:49:26 \
+// RUN:              -cursor-at=%s:57:12 \
 // RUN:       %s | FileCheck %s
 
 // CHECK:     8:11 MemberRefExpr=meth:3:16 {{.*}} Dynamic-call
@@ -67,9 +76,10 @@
 // CHECK-NOT: 26:3 {{.*}} Dynamic-call
 // CHECK-NOT: 29:3 {{.*}} Dynamic-call
 // CHECK:     29:3 {{.*}} Receiver-type=ObjCInterface
-// CHECK:     34:7 MemberRefExpr=meth:3:16 {{.*}} Dynamic-call
+// CHECK:     34:7 MemberRefExpr=meth:3:16 {{.*}} Dynamic-call Receiver-type=Pointer
 // CHECK:     35:3 ObjCMessageExpr=meth:14:8 {{.*}} Dynamic-call Receiver-type=ObjCObjectPointer
 // CHECK-NOT: 36:3 {{.*}} Dynamic-call
 // CHECK:     36:3 {{.*}} Receiver-type=ObjCInterface
 // CHECK:     37:3 ObjCMessageExpr=ClsMeth:15:8 {{.*}} Dynamic-call Receiver-type=ObjCClass
 // CHECK-NOT: 49:10 {{.*}} Dynamic-call
+// CHECK:     57:12 MemberRefExpr=someProp:53:23 {{.*}} Dynamic-call  Receiver-type=ObjCObjectPointer
diff --git a/test/Index/get-cursor.m b/test/Index/get-cursor.m
index d321233..e85d49f 100644
--- a/test/Index/get-cursor.m
+++ b/test/Index/get-cursor.m
@@ -129,6 +129,37 @@
 }
 @end
 
+#define NS_ENUM(_name, _type) enum _name : _type _name; enum _name : _type
+typedef NS_ENUM(TestTransparent, int) {
+  TestTransparentFirst = 0,
+  TestTransparentSecond = 1,
+};
+typedef enum TestTransparent NotTransparent;
+
+TestTransparent transparentTypedef;
+enum TestTransparent transparentUnderlying;
+NotTransparent opaqueTypedef;
+
+#define MY_ENUM(_name, _type) enum _name : _type _name##_t; enum _name : _type
+typedef MY_ENUM(TokenPaste, int) {
+  TokenPasteFirst = 0,
+};
+TokenPaste_t opaqueTypedef2;
+
+#define MY_TYPE(_name) struct _name _name; struct _name
+typedef MY_TYPE(SomeT) { int x; };
+SomeT someVar;
+
+#define MY_TYPE2(_name) struct _name *_name; struct _name
+typedef MY_TYPE2(SomeT2) { int x; };
+SomeT2 someVar2;
+
+#define GEN_DECL(mod_name) __attribute__((external_source_symbol(language="Swift", defined_in=mod_name, generated_declaration)))
+
+GEN_DECL("some_module")
+@interface ExtCls
+-(void)method;
+@end
 
 // RUN: c-index-test -cursor-at=%s:4:28 -cursor-at=%s:5:28 %s | FileCheck -check-prefix=CHECK-PROP %s
 // CHECK-PROP: ObjCPropertyDecl=foo1:4:26
@@ -193,3 +224,16 @@
 // RUN: c-index-test -cursor-at=%s:127:8 %s | FileCheck -check-prefix=CHECK-RECEIVER-WITH-NULLABILITY %s
 // RUN: c-index-test -cursor-at=%s:128:8 %s | FileCheck -check-prefix=CHECK-RECEIVER-WITH-NULLABILITY %s
 // CHECK-RECEIVER-WITH-NULLABILITY: Receiver-type=ObjCId
+
+// RUN: c-index-test -cursor-at=%s:139:1 -cursor-at=%s:140:6 -cursor-at=%s:141:1 -cursor-at=%s:147:1 -cursor-at=%s:151:1 -cursor-at=%s:155:1 %s | FileCheck -check-prefix=CHECK-TRANSPARENT %s
+// CHECK-TRANSPARENT: 139:1 TypeRef=TestTransparent:133:17 (Transparent: enum TestTransparent) Extent=[139:1 - 139:16] Spelling=TestTransparent ([139:1 - 139:16])
+// CHECK-TRANSPARENT: 140:6 TypeRef=enum TestTransparent:133:17 Extent=[140:6 - 140:21] Spelling=enum TestTransparent ([140:6 - 140:21])
+// CHECK-TRANSPARENT: 141:1 TypeRef=NotTransparent:137:30 Extent=[141:1 - 141:15] Spelling=NotTransparent ([141:1 - 141:15])
+// CHECK-TRANSPARENT: 147:1 TypeRef=TokenPaste_t:144:9 Extent=[147:1 - 147:13] Spelling=TokenPaste_t ([147:1 - 147:13])
+// CHECK-TRANSPARENT: 151:1 TypeRef=SomeT:150:17 (Transparent: struct SomeT) Extent=[151:1 - 151:6] Spelling=SomeT ([151:1 - 151:6])
+// CHECK-TRANSPARENT: 155:1 TypeRef=SomeT2:154:18 Extent=[155:1 - 155:7] Spelling=SomeT2 ([155:1 - 155:7])
+
+// RUN: c-index-test -cursor-at=%s:160:12 -cursor-at=%s:161:8 %s | FileCheck -check-prefix=CHECK-EXTERNAL %s
+// CHECK-EXTERNAL: 160:12 ObjCInterfaceDecl=ExtCls:160:12 (external lang: Swift, defined: some_module, gen: 1)
+// CHECK-EXTERNAL: 161:8 ObjCInstanceMethodDecl=method:161:8 (external lang: Swift, defined: some_module, gen: 1)
+C
\ No newline at end of file
diff --git a/test/Index/index-decls.m b/test/Index/index-decls.m
index 7f7f115..a5368ec 100644
--- a/test/Index/index-decls.m
+++ b/test/Index/index-decls.m
@@ -64,9 +64,9 @@
 // CHECK: [indexDeclaration]: kind: objc-instance-method | name: setProp: | {{.*}} | loc: 7:33
 // CHECK: [indexDeclaration]: kind: objc-property | name: prop | {{.*}} | loc: 7:33
 
-// CHECK: [indexDeclaration]: kind: objc-ivar | name: _prop | {{.*}} | loc: 11:20
 // CHECK: [indexDeclaration]: kind: objc-instance-method | name: prop | {{.*}} | loc: 11:13 | {{.*}} | lexical-container: [I:10:17]
 // CHECK: [indexDeclaration]: kind: objc-instance-method | name: setProp: | {{.*}} | loc: 11:13 | {{.*}} | lexical-container: [I:10:17]
+// CHECK: [indexDeclaration]: kind: objc-ivar | name: _prop | {{.*}} | loc: 11:20
 
 // CHECK: [indexDeclaration]: kind: objc-ivar | name: _auto_prop | {{.*}} | loc: 20:33
 // CHECK: [indexEntityReference]: kind: objc-ivar | name: _auto_prop | {{.*}} | loc: 25:3
diff --git a/test/Index/index-refs.cpp b/test/Index/index-refs.cpp
index 5a1ba1e..d8bede0 100644
--- a/test/Index/index-refs.cpp
+++ b/test/Index/index-refs.cpp
@@ -105,6 +105,7 @@
 // CHECK:      [indexDeclaration]: kind: c++-class-template | name: TS | {{.*}} | loc: 47:8
 // CHECK-NEXT: [indexDeclaration]: kind: struct-template-partial-spec | name: TS | USR: c:@SP>1#T@TS>#t0.0#I | {{.*}} | loc: 50:8
 // CHECK-NEXT: [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@SP>1#T@TS>#t0.0#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
+// CHECK-NEXT: [indexEntityReference]: kind: c++-class-template | name: TS | USR: c:@ST>2#T#T@TS | lang: C++ | cursor: TemplateRef=TS:47:8 | loc: 50:8 | <parent>:: <<NULL>> | container: [TU] | refkind: direct
 /* when indexing implicit instantiations
   [indexDeclaration]: kind: struct-template-spec | name: TS | USR: c:@S@TS>#I | {{.*}} | loc: 50:8
   [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@593@S@TS>#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
diff --git a/test/Index/overriding-method-comments.mm b/test/Index/overriding-method-comments.mm
index d995e0e..824d055 100644
--- a/test/Index/overriding-method-comments.mm
+++ b/test/Index/overriding-method-comments.mm
@@ -78,7 +78,7 @@
 
 void Base::foo_outofline(int RRR) {}
 
-// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-2]]" column="12"><Name>foo_outofline</Name><USR>c:@S@Base@F@foo_outofline#I#</USR><Declaration>void foo_outofline(int RRR)</Declaration><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>RRR</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to undefined virtual.</Para></Discussion></Parameter></Parameters></Function>]
+// CHECK: FullCommentAsXML=[<Function isInstanceMethod="1" file="{{[^"]+}}overriding-method-comments.mm" line="[[@LINE-2]]" column="12"><Name>foo_outofline</Name><USR>c:@S@Base@F@foo_outofline#I#</USR><Declaration>void Base::foo_outofline(int RRR)</Declaration><Abstract><Para> Does something. </Para></Abstract><Parameters><Parameter><Name>RRR</Name><Index>0</Index><Direction isExplicit="0">in</Direction><Discussion><Para> argument to undefined virtual.</Para></Discussion></Parameter></Parameters></Function>]
 
 struct Derived : public Base {
   virtual void foo_pure(int PPP);
diff --git a/test/Index/pch-from-libclang.c b/test/Index/pch-from-libclang.c
new file mode 100644
index 0000000..349fcac
--- /dev/null
+++ b/test/Index/pch-from-libclang.c
@@ -0,0 +1,27 @@
+// Check that clang can use a PCH created from libclang.
+
+// FIXME: Non-darwin bots fail. Would need investigation using -module-file-info to see what is the difference in modules generated from libclang vs the compiler invocation, in those systems.
+// REQUIRES: system-darwin
+
+// RUN: %clang_cc1 -fsyntax-only %s -verify
+// RUN: c-index-test -write-pch %t.h.pch %s -fmodules -fmodules-cache-path=%t.mcp -Xclang -triple -Xclang x86_64-apple-darwin
+// RUN: %clang -fsyntax-only -include %t.h %s -Xclang -verify -fmodules -fmodules-cache-path=%t.mcp -Xclang -detailed-preprocessing-record -Xclang -triple -Xclang x86_64-apple-darwin -Xclang -fallow-pch-with-compiler-errors
+// RUN: %clang -x c-header %s -o %t.clang.h.pch -fmodules -fmodules-cache-path=%t.mcp -Xclang -detailed-preprocessing-record -Xclang -triple -Xclang x86_64-apple-darwin -Xclang -fallow-pch-with-compiler-errors -Xclang -verify
+// RUN: c-index-test -test-load-source local %s -include %t.clang.h -fmodules -fmodules-cache-path=%t.mcp -Xclang -triple -Xclang x86_64-apple-darwin | FileCheck %s
+
+#ifndef HEADER
+#define HEADER
+
+void some_function(undeclared_type p); // expected-error{{unknown type name}}
+
+struct S { int x; };
+
+#else
+// expected-no-diagnostics
+
+void test(struct S *s) {
+  // CHECK: [[@LINE+1]]:6: MemberRefExpr=x:[[@LINE-6]]:16
+  s->x = 0;
+}
+
+#endif
diff --git a/test/Index/usrs.cpp b/test/Index/usrs.cpp
index 8ad1702..2bd5744 100644
--- a/test/Index/usrs.cpp
+++ b/test/Index/usrs.cpp
@@ -95,6 +95,14 @@
   void meth(TC1);
 };
 
+typedef __attribute__((__ext_vector_type__(3))) float float3;
+
+typedef float __m128 __attribute__((__vector_size__(16)));
+
+float3 vectorOverload(float3 f);
+
+__m128 vectorOverload(__m128 f);
+
 // RUN: c-index-test -test-load-source-usrs all -fno-delayed-template-parsing %s | FileCheck %s
 // CHECK: usrs.cpp c:@N@foo Extent=[1:1 - 4:2]
 // CHECK: usrs.cpp c:@N@foo@x Extent=[2:3 - 2:8]
@@ -172,3 +180,6 @@
 // CHECK: usrs.cpp c:usrs.cpp@S@usrs.cpp@1510@FI@x Extent=[91:10 - 91:15]
 
 // CHECK: usrs.cpp c:@ST>1#T@TC1@F@meth#>@ST>1#T@TC11t0.0# Extent=[95:3 - 95:17]
+
+// CHECK: usrs.cpp c:@F@vectorOverload#]3f# Extent=[102:1 - 102:32]
+// CHECK: usrs.cpp c:@F@vectorOverload#[4f# Extent=[104:1 - 104:32]
diff --git a/test/Lexer/cxx-features.cpp b/test/Lexer/cxx-features.cpp
index 5fc1722..0af42dc 100644
--- a/test/Lexer/cxx-features.cpp
+++ b/test/Lexer/cxx-features.cpp
@@ -9,7 +9,6 @@
 
 // expected-no-diagnostics
 
-// FIXME using `defined` in a macro has undefined behavior.
 #if __cplusplus < 201103L
 #define check(macro, cxx98, cxx11, cxx14, cxx1z) cxx98 == 0 ? defined(__cpp_##macro) : __cpp_##macro != cxx98
 #elif __cplusplus < 201402L
diff --git a/test/Misc/ast-dump-attr.cpp b/test/Misc/ast-dump-attr.cpp
index e0575cb..f18fbac 100644
--- a/test/Misc/ast-dump-attr.cpp
+++ b/test/Misc/ast-dump-attr.cpp
@@ -154,3 +154,28 @@
 struct __attribute__((objc_bridge_related(NSParagraphStyle,,))) TestBridgedRef;
 // CHECK: CXXRecordDecl{{.*}} struct TestBridgedRef
 // CHECK-NEXT: ObjCBridgeRelatedAttr{{.*}} NSParagraphStyle
+
+void TestExternalSourceSymbolAttr1()
+__attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration)));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr1
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration
+
+void TestExternalSourceSymbolAttr2()
+__attribute__((external_source_symbol(defined_in="module", language="Swift")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr2
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module"{{$}}
+
+void TestExternalSourceSymbolAttr3()
+__attribute__((external_source_symbol(generated_declaration, language="Objective-C++", defined_in="module")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr3
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Objective-C++" "module" GeneratedDeclaration
+
+void TestExternalSourceSymbolAttr4()
+__attribute__((external_source_symbol(defined_in="Some external file.cs", generated_declaration, language="C Sharp")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr4
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "C Sharp" "Some external file.cs" GeneratedDeclaration
+
+void TestExternalSourceSymbolAttr5()
+__attribute__((external_source_symbol(generated_declaration, defined_in="module", language="Swift")));
+// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr5
+// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration
diff --git a/test/Misc/ast-dump-decl.m b/test/Misc/ast-dump-decl.m
index 539923b..4cfb8aa 100644
--- a/test/Misc/ast-dump-decl.m
+++ b/test/Misc/ast-dump-decl.m
@@ -77,7 +77,7 @@
 @end
 // CHECK:      ObjCCategoryDecl{{.*}} TestObjCCategoryDecl
 // CHECK-NEXT:   ObjCInterface{{.*}} 'TestObjCClass'
-// CHECK-NEXT:   ObjCCategoryImpl{{.*}} 'TestObjCClass'
+// CHECK-NEXT:   ObjCCategoryImpl{{.*}} 'TestObjCCategoryDecl'
 // CHECK-NEXT:   ObjCProtocol{{.*}} 'P'
 // CHECK-NEXT:   ObjCMethodDecl{{.*}} bar
 
@@ -85,7 +85,7 @@
 - (void) bar {
 }
 @end
-// CHECK:      ObjCCategoryImplDecl{{.*}} TestObjCClass
+// CHECK:      ObjCCategoryImplDecl{{.*}} TestObjCCategoryDecl
 // CHECK-NEXT:   ObjCInterface{{.*}} 'TestObjCClass'
 // CHECK-NEXT:   ObjCCategory{{.*}} 'TestObjCCategoryDecl'
 // CHECK-NEXT:   ObjCMethodDecl{{.*}} bar
diff --git a/test/Misc/ast-print-out-of-line-func.cpp b/test/Misc/ast-print-out-of-line-func.cpp
new file mode 100644
index 0000000..7c4f7ae
--- /dev/null
+++ b/test/Misc/ast-print-out-of-line-func.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -ast-print -std=c++14 %s | FileCheck %s
+
+namespace ns {
+
+struct Wrapper {
+class Inner {
+  Inner();
+  Inner(int);
+  ~Inner();
+
+  void operator += (int);
+
+  template<typename T>
+  void member();
+
+  static void staticMember();
+
+  operator int();
+
+  operator ns::Wrapper();
+  // CHECK: operator ns::Wrapper()
+};
+};
+
+Wrapper::Inner::Inner() { }
+// CHECK: Wrapper::Inner::Inner()
+
+void Wrapper::Inner::operator +=(int) { }
+// CHECK: void Wrapper::Inner::operator+=(int)
+
+}
+
+ns::Wrapper::Inner::Inner(int) { }
+// CHECK: ns::Wrapper::Inner::Inner(int)
+
+ns::Wrapper::Inner::~Inner() { }
+// CHECK: ns::Wrapper::Inner::~Inner()
+
+template<typename T>
+void ::ns::Wrapper::Inner::member() { }
+// CHECK: template <typename T> void ::ns::Wrapper::Inner::member()
+
+ns::Wrapper::Inner::operator int() { return 0; }
+// CHECK: ns::Wrapper::Inner::operator int()
+
+ns::Wrapper::Inner::operator ::ns::Wrapper() { return ns::Wrapper(); }
+// CHECK: ns::Wrapper::Inner::operator ::ns::Wrapper()
+
+namespace ns {
+
+void Wrapper::Inner::staticMember() { }
+// CHECK: void Wrapper::Inner::staticMember()
+
+}
diff --git a/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp b/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp
new file mode 100644
index 0000000..b774134
--- /dev/null
+++ b/test/Misc/pragma-attribute-cxx-subject-match-rules.cpp
@@ -0,0 +1,169 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=namespace" %s | FileCheck --check-prefix=CHECK-NAMESPACE %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=type_alias" %s | FileCheck --check-prefix=CHECK-TYPE_ALIAS %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=enum" %s | FileCheck --check-prefix=CHECK-ENUM %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=enum_constant" %s | FileCheck --check-prefix=CHECK-ENUM_CONSTANT %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=record" %s | FileCheck --check-prefix=CHECK-RECORD %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=record(unless(is_union))" %s | FileCheck --check-prefix=CHECK-RECORD_UNLESS_IS_UNION %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=field" %s | FileCheck --check-prefix=CHECK-FIELD %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=function" %s | FileCheck --check-prefix=CHECK-FUNCTION %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=hasType(functionType)" %s | FileCheck --check-prefix=CHECK-HAS_TYPE_FUNCTION_TYPE %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=function(is_member)" %s | FileCheck --check-prefix=CHECK-FUNCTION_IS_MEMBER %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=variable" %s | FileCheck --check-prefix=CHECK-VARIABLE %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=variable(is_global)" %s | FileCheck --check-prefix=CHECK-VARIABLE_IS_GLOBAL %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=variable(is_parameter)" %s | FileCheck --check-prefix=CHECK-VARIABLE_IS_PARAMETER %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=variable(unless(is_parameter))" %s | FileCheck --check-prefix=CHECK-VARIABLE_UNLESS_IS_PARAMETER %s
+
+#pragma clang attribute push (__attribute__((annotate("test"))), apply_to = any(SUBJECT))
+
+namespace testNamespace {
+// CHECK-NAMESPACE: NamespaceDecl{{.*}} testNamespace
+// CHECK-NAMESPACE-NEXT: AnnotateAttr{{.*}} "test"
+
+typedef int testTypedef;
+// CHECK-TYPE_ALIAS: TypedefDecl{{.*}} testTypedef
+// CHECK-TYPE_ALIAS-NEXT: BuiltinType
+// CHECK-TYPE_ALIAS-NEXT: AnnotateAttr{{.*}} "test"
+
+using testTypeAlias = double;
+// CHECK-TYPE_ALIAS: TypeAliasDecl{{.*}} testTypeAlias
+// CHECK-TYPE_ALIAS-NEXT: BuiltinType
+// CHECK-TYPE_ALIAS-NEXT: AnnotateAttr{{.*}} "test"
+
+enum testEnum {
+  testEnumCase1,
+  testEnumCase2
+};
+// CHECK-ENUM: EnumDecl{{.*}} testEnum
+// CHECK-ENUM-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-ENUM_CONSTANT: EnumConstantDecl{{.*}} testEnumCase1
+// CHECK-ENUM_CONSTANT-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-ENUM_CONSTANT: EnumConstantDecl{{.*}} testEnumCase2
+// CHECK-ENUM_CONSTANT-NEXT: AnnotateAttr{{.*}} "test"
+
+struct testStructRecord {
+  int testStructRecordField;
+};
+// CHECK-RECORD: CXXRecordDecl{{.*}} testStructRecord
+// CHECK-RECORD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testStructRecord
+// CHECK-RECORD_UNLESS_IS_UNION-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-FIELD: FieldDecl{{.*}} testStructRecordField
+// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test"
+
+class testClassRecord {
+  int testClassRecordField;
+};
+// CHECK-RECORD: CXXRecordDecl{{.*}} testClassRecord
+// CHECK-RECORD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testClassRecord
+// CHECK-RECORD_UNLESS_IS_UNION-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-FIELD: FieldDecl{{.*}} testClassRecordField
+// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test"
+
+union testUnionRecord {
+  int testUnionRecordField;
+};
+// CHECK-RECORD: CXXRecordDecl{{.*}} testUnionRecord
+// CHECK-RECORD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl{{.*}} testUnionRecord
+// CHECK-RECORD_UNLESS_IS_UNION-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-FIELD: FieldDecl{{.*}} testUnionRecordField
+// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test"
+
+// CHECK-RECORD_UNLESS_IS_UNION-LABEL: CXXRecordDecl
+void testFunctionDecl();
+// CHECK-FUNCTION: FunctionDecl{{.*}} testFunctionDecl
+// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE: FunctionDecl{{.*}} testFunctionDecl
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test"
+
+void testFunctionDecl() { }
+// CHECK-FUNCTION: FunctionDecl{{.*}} testFunctionDecl
+// CHECK-FUNCTION-NEXT: CompoundStmt
+// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE: FunctionDecl{{.*}} testFunctionDecl
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: CompoundStmt
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test"
+
+void (*testFunctionVar)();
+// CHECK-HAS_TYPE_FUNCTION_TYPE: VarDecl{{.*}} testFunctionVar
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test"
+// 'function' should not apply to variables with a function type!
+// CHECK-FUNCTION: VarDecl{{.*}} testFunctionVar
+// CHECK-FUNCTION-NOT: AnnotateAttr{{.*}} "test"
+
+class testMethods {
+  testMethods();
+  void testMethod();
+};
+void testMethods::testMethod() { }
+void testFunctionNotMethod();
+// CHECK-FUNCTION-LABEL: CXXConstructorDecl{{.*}} testMethods
+// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-FUNCTION_IS_MEMBER: CXXConstructorDecl{{.*}} testMethods
+// CHECK-FUNCTION_IS_MEMBER-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE: CXXConstructorDecl{{.*}} testMethods
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-FUNCTION: CXXMethodDecl{{.*}} testMethod
+// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-FUNCTION_IS_MEMBER: CXXMethodDecl{{.*}} testMethod
+// CHECK-FUNCTION_IS_MEMBER-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE: CXXMethodDecl{{.*}} testMethod
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-FUNCTION: CXXMethodDecl{{.*}} testMethod
+// CHECK-FUNCTION-NEXT: CompoundStmt
+// CHECK-FUNCTION-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-FUNCTION_IS_MEMBER: CXXMethodDecl{{.*}} testMethod
+// CHECK-FUNCTION_IS_MEMBER-NEXT: CompoundStmt
+// CHECK-CXX_METHOD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE: CXXMethodDecl{{.*}} testMethod
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: CompoundStmt
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-FUNCTION_IS_MEMBER: FunctionDecl{{.*}} testFunctionNotMethod
+// CHECK-FUNCTION_IS_MEMBER-NOT: AnnotateAttr{{.*}} "test"
+
+int testVariable;
+// CHECK-VARIABLE: VarDecl{{.*}} testVariable
+// CHECK-VARIABLE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_IS_GLOBAL-LABEL: VarDecl{{.*}} testVariable
+// CHECK-VARIABLE_IS_GLOBAL-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_IS_PARAMETER-LABEL: VarDecl{{.*}} testVariable
+// CHECK-VARIABLE_IS_PARAMETER-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_UNLESS_IS_PARAMETER-LABEL: VarDecl{{.*}} testVariable
+// CHECK-VARIABLE_UNLESS_IS_PARAMETER-NEXT: AnnotateAttr{{.*}} "test"
+void testVarFunction(int testParam) {
+// CHECK-VARIABLE: VarDecl{{.*}} testParam
+// CHECK-VARIABLE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_IS_GLOBAL-LABEL: VarDecl{{.*}} testParam
+// CHECK-VARIABLE_IS_GLOBAL-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_IS_PARAMETER-LABEL: VarDecl{{.*}} testParam
+// CHECK-VARIABLE_IS_PARAMETER-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_UNLESS_IS_PARAMETER-LABEL: VarDecl{{.*}} testParam
+// CHECK-VARIABLE_UNLESS_IS_PARAMETER-NOT: AnnotateAttr{{.*}} "test"
+
+  int testLocalVariable;
+// CHECK-VARIABLE: VarDecl{{.*}} testLocalVariable
+// CHECK-VARIABLE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_IS_GLOBAL-LABEL: VarDecl{{.*}} testLocalVariable
+// CHECK-VARIABLE_IS_GLOBAL-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_IS_PARAMETER-LABEL: VarDecl{{.*}} testLocalVariable
+// CHECK-VARIABLE_IS_PARAMETER-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_UNLESS_IS_PARAMETER-LABEL: VarDecl{{.*}} testLocalVariable
+// CHECK-VARIABLE_UNLESS_IS_PARAMETER-NEXT: AnnotateAttr{{.*}} "test"
+}
+class testVarClass {
+  static int testStaticVar;
+};
+// CHECK-VARIABLE: VarDecl{{.*}} testStaticVar
+// CHECK-VARIABLE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_IS_GLOBAL-LABEL: VarDecl{{.*}} testStaticVar
+// CHECK-VARIABLE_IS_GLOBAL-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_IS_PARAMETER-LABEL: VarDecl{{.*}} testStaticVar
+// CHECK-VARIABLE_IS_PARAMETER-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-VARIABLE_UNLESS_IS_PARAMETER-LABEL: VarDecl{{.*}} testStaticVar
+// CHECK-VARIABLE_UNLESS_IS_PARAMETER-NEXT: AnnotateAttr{{.*}} "test"
+
+
+}
+
+#pragma clang attribute pop
diff --git a/test/Misc/pragma-attribute-cxx.cpp b/test/Misc/pragma-attribute-cxx.cpp
new file mode 100644
index 0000000..c241c4e
--- /dev/null
+++ b/test/Misc/pragma-attribute-cxx.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -fcxx-exceptions %s
+// RUN: %clang_cc1 -fsyntax-only -ast-dump -ast-dump-filter test -std=c++11 -fcxx-exceptions %s | FileCheck %s
+// expected-no-diagnostics
+
+class testClass1 {
+};
+// CHECK-LABEL: CXXRecordDecl{{.*}} testClass1
+// CHECK-NOT: AnnotateAttr
+
+#pragma clang attribute push (__attribute__((annotate("test"))), apply_to=any(record, field, variable, function, namespace, type_alias))
+
+class testClass2 {
+  void testMethod1(int param);
+
+  testClass2();
+
+  testClass2 *operator -> ();
+};
+// CHECK-LABEL: CXXRecordDecl{{.*}} testClass2
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK: CXXMethodDecl{{.*}} testMethod1
+// CHECK-NEXT: ParmVarDecl{{.*}} param
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NEXT: CXXConstructorDecl
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NEXT: CXXMethodDecl{{.*}} operator->
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+
+#pragma clang attribute push (__attribute__((annotate("method"))), apply_to=any(record, field, variable, function, namespace, type_alias))
+
+void testClass2::testMethod1(int param) {
+
+#pragma clang attribute pop
+}
+// CHECK-LABEL: CXXMethodDecl{{.*}}prev{{.*}} testMethod1
+// CHECK-NEXT: ParmVarDecl{{.*}} param
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NEXT: AnnotateAttr{{.*}} "method"
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NEXT: AnnotateAttr{{.*}} "method"
+
+namespace testNamespace {
+}
+// CHECK-LABEL: NamespaceDecl{{.*}} testNamespace
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+
+class testClassForward;
+// CHECK-LABEL: CXXRecordDecl{{.*}} testClassForward
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+
+namespace testNamespaceAlias = testNamespace;
+// CHECK-LABEL: NamespaceAliasDecl{{.*}} testNamespaceAlias
+// CHECK-NOT: AnnotateAttr
+
+using testTypeAlias = testClass2;
+// CHECK-LABEL: TypeAliasDecl{{.*}} testTypeAlias
+// CHECK: AnnotateAttr{{.*}} "test"
+
+void testCatchVariable() {
+  try {
+  } catch (int testCatch) {
+  }
+  testCatchVariable();
+}
+// CHECK-LABEL: FunctionDecl{{.*}} testCatchVariable
+// CHECK: CXXCatchStmt
+// CHECK-NEXT: VarDecl{{.*}} testCatch
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+
+void testLambdaMethod() {
+  auto l = [] () { };
+  testLambdaMethod();
+}
+// CHECK-LABEL: FunctionDecl{{.*}} testLambdaMethod
+// CHECK: LambdaExpr
+// CHECK-NEXT: CXXRecordDecl
+// CHECK-NEXT: CXXMethodDecl{{.*}} operator()
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((require_constant_initialization)), apply_to=variable(is_global))
+
+int testCI1 = 1;
+// CHECK-LABEL: VarDecl{{.*}} testCI1
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: RequireConstantInitAttr
+
+#pragma clang attribute pop
+
+int testNoCI = 0;
+// CHECK-LABEL: VarDecl{{.*}} testNoCI
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NOT: RequireConstantInitAttr
+
+// Check support for CXX11 style attributes
+#pragma clang attribute push ([[noreturn]], apply_to = function)
+
+void testNoReturn();
+// CHECK-LABEL: FunctionDecl{{.*}} testNoReturn
+// CHECK-NEXT: CXX11NoReturnAttr
+
+#pragma clang attribute pop
diff --git a/test/Misc/pragma-attribute-objc-subject-match-rules.m b/test/Misc/pragma-attribute-objc-subject-match-rules.m
new file mode 100644
index 0000000..09ab5e1
--- /dev/null
+++ b/test/Misc/pragma-attribute-objc-subject-match-rules.m
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump "-DSUBJECT=objc_interface" %s | FileCheck --check-prefix=CHECK-OBJC_INTERFACE %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=objc_protocol" %s | FileCheck --check-prefix=CHECK-OBJC_PROTOCOL %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump "-DSUBJECT=objc_category" %s | FileCheck --check-prefix=CHECK-OBJC_CATEGORY %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=objc_method" %s | FileCheck --check-prefix=CHECK-OBJC_METHOD %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=objc_method(is_instance)" %s | FileCheck --check-prefix=CHECK-OBJC_METHOD_IS_INSTANCE %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=field" %s | FileCheck --check-prefix=CHECK-FIELD %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=objc_property" %s | FileCheck --check-prefix=CHECK-OBJC_PROPERTY %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=block" %s | FileCheck --check-prefix=CHECK-BLOCK %s
+// RUN: %clang_cc1 -fblocks -fobjc-arc -Wno-objc-root-class -fsyntax-only -ast-dump -ast-dump-filter test "-DSUBJECT=hasType(functionType)" %s | FileCheck --check-prefix=CHECK-HAS_TYPE_FUNCTION_TYPE %s
+
+#pragma clang attribute push (__attribute__((annotate("test"))), apply_to = any(SUBJECT))
+
+@interface testInterface
+@end
+// CHECK-OBJC_INTERFACE: ObjCInterfaceDecl{{.*}} testInterface
+// CHECK-OBJC_INTERFACE-NEXT: AnnotateAttr{{.*}} "test"
+
+@interface testInterface ()
+@end
+// CHECK-OBJC_INTERFACE: ObjCCategoryDecl
+// CHECK-OBJC_INTERFACE-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-OBJC_CATEGORY: ObjCCategoryDecl
+// CHECK-OBJC_CATEGORY-NEXT: ObjCInterface
+// CHECK-OBJC_CATEGORY-NEXT: AnnotateAttr{{.*}} "test"
+
+@interface testInterface (testCategory)
+@end
+// CHECK-OBJC_INTERFACE: ObjCCategoryDecl{{.*}} testCategory
+// CHECK-OBJC_INTERFACE-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-OBJC_CATEGORY: ObjCCategoryDecl{{.*}} testCategory
+// CHECK-OBJC_CATEGORY-NEXT: ObjCInterface
+// CHECK-OBJC_CATEGORY-NEXT: AnnotateAttr{{.*}} "test"
+
+// CHECK-OBJC_INTERFACE-LABEL: ObjCProtocolDecl
+@protocol testProtocol
+@end
+// CHECK-OBJC_PROTOCOL: ObjCProtocolDecl{{.*}} testProtocol
+// CHECK-OBJC_PROTOCOL-NEXT: AnnotateAttr{{.*}} "test"
+
+@interface methodContainer
+- (void) testInstanceMethod;
++ (void) testClassMethod;
+@end
+// CHECK-OBJC_METHOD: ObjCMethodDecl{{.*}} testInstanceMethod
+// CHECK-OBJC_METHOD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-OBJC_METHOD: ObjCMethodDecl{{.*}} testClassMethod
+// CHECK-OBJC_METHOD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-OBJC_METHOD_IS_INSTANCE: ObjCMethodDecl{{.*}} testInstanceMethod
+// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-OBJC_METHOD_IS_INSTANCE-LABEL: ObjCMethodDecl{{.*}} testClassMethod
+// CHECK-OBJC_METHOD_IS_INSTANCE-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: ObjCMethodDecl{{.*}} testInstanceMethod
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: ObjCMethodDecl{{.*}} testClassMethod
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test"
+
+@implementation methodContainer
+- (void) testInstanceMethod { }
++ (void) testClassMethod { }
+@end
+// CHECK-OBJC_METHOD: ObjCMethodDecl{{.*}} testInstanceMethod
+// CHECK-OBJC_METHOD-NEXT: ImplicitParamDecl
+// CHECK-OBJC_METHOD-NEXT: ImplicitParamDecl
+// CHECK-OBJC_METHOD-NEXT: CompoundStmt
+// CHECK-OBJC_METHOD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-OBJC_METHOD: ObjCMethodDecl{{.*}} testClassMethod
+// CHECK-OBJC_METHOD-NEXT: ImplicitParamDecl
+// CHECK-OBJC_METHOD-NEXT: ImplicitParamDecl
+// CHECK-OBJC_METHOD-NEXT: CompoundStmt
+// CHECK-OBJC_METHOD-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-OBJC_METHOD_IS_INSTANCE-LABEL: ObjCMethodDecl{{.*}} testInstanceMethod
+// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: ImplicitParamDecl
+// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: ImplicitParamDecl
+// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: CompoundStmt
+// CHECK-OBJC_METHOD_IS_INSTANCE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-OBJC_METHOD_IS_INSTANCE: ObjCMethodDecl{{.*}} testClassMethod
+// CHECK-OBJC_METHOD_IS_INSTANCE-NOT: AnnotateAttr{{.*}} "test"
+
+// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: ObjCMethodDecl{{.*}} testInstanceMethod
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: ObjCMethodDecl{{.*}} testClassMethod
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test"
+@interface propertyContainer {
+  int testIvar;
+// CHECK-FIELD: ObjCIvarDecl{{.*}} testIvar
+// CHECK-FIELD-NEXT: AnnotateAttr{{.*}} "test"
+
+}
+@property int testProperty;
+// CHECK-OBJC_PROPERTY: ObjCPropertyDecl{{.*}} testProperty
+// CHECK-OBJC_PROPERTY-NEXT: AnnotateAttr{{.*}} "test"
+
+@end
+
+void (^testBlockVar)();
+// CHECK-BLOCK: VarDecl{{.*}} testBlockVar
+// CHECK-BLOCK-NOT: AnnotateAttr{{.*}} "test"
+
+void testBlock() {
+  (void)(^ { });
+}
+// CHECK-BLOCK-LABEL: BlockDecl
+// CHECK-BLOCK-NEXT: CompoundStmt
+// CHECK-BLOCK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE-LABEL: FunctionDecl{{.*}} testBlock
+// CHECK-HAS_TYPE_FUNCTION_TYPE: BlockDecl
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: CompoundStmt
+// The attribute applies to function, but not to block:
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-HAS_TYPE_FUNCTION_TYPE-NOT: AnnotateAttr{{.*}} "test"
+
+
+#pragma clang attribute pop
diff --git a/test/Misc/pragma-attribute-objc.m b/test/Misc/pragma-attribute-objc.m
new file mode 100644
index 0000000..541cfa9
--- /dev/null
+++ b/test/Misc/pragma-attribute-objc.m
@@ -0,0 +1,164 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fsyntax-only -Wno-objc-root-class -ast-dump -ast-dump-filter test %s | FileCheck %s
+
+#pragma clang attribute push (__attribute__((annotate("test"))), apply_to = any(objc_interface, objc_protocol, objc_property, field, objc_method, variable))
+#pragma clang attribute push (__attribute__((objc_subclassing_restricted)), apply_to = objc_interface)
+
+@interface testInterface1
+// CHECK-LABEL: ObjCInterfaceDecl{{.*}}testInterface1
+// CHECK-NEXT: ObjCImplementation
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NEXT: ObjCSubclassingRestrictedAttr{{.*}}
+
+// CHECK-NOT: AnnotateAttr
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+{
+  int testIvar1;
+  // CHECK-LABEL: ObjCIvarDecl{{.*}} testIvar1
+  // CHECK-NEXT: AnnotateAttr{{.*}} "test"
+  // CHECK-NOT: ObjCSubclassingRestrictedAttr
+}
+
+@property int testProp1;
+// CHECK-LABEL: ObjCPropertyDecl{{.*}} testProp1
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+- (void)testIm:(int) x;
+// CHECK-LABEL: ObjCMethodDecl{{.*}}testIm
+// CHECK-NEXT: ParmVarDecl{{.*}} x
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
++ (void)testCm;
+// CHECK-LABEL: ObjCMethodDecl{{.*}}testCm
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+// Implicit getters/setters shouldn't receive the attributes.
+// CHECK-LABEL: ObjCMethodDecl{{.*}}testProp1
+// CHECK-NOT: AnnotateAttr
+// CHECK-LABEL: ObjCMethodDecl{{.*}}setTestProp1
+// CHECK-NOT: AnnotateAttr
+
+@end
+
+// @implementation can't receive explicit attributes, so don't add the pragma
+// attributes to them.
+@implementation testInterface1
+// CHECK-LABEL: ObjCImplementationDecl{{.*}}testInterface1
+// CHECK-NOT: AnnotateAttr
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+{
+  int testIvar2;
+  // CHECK-LABEL: ObjCIvarDecl{{.*}} testIvar2
+  // CHECK-NEXT: AnnotateAttr{{.*}} "test"
+  // CHECK-NOT: ObjCSubclassingRestrictedAttr
+}
+
+// Don't add attributes to implicit parameters!
+- (void)testIm:(int) x {
+// CHECK-LABEL: ObjCMethodDecl{{.*}}testIm
+// CHECK-NEXT: ImplicitParamDecl
+// CHECK-NEXT: ImplicitParamDecl
+// CHECK-NEXT: ParmVarDecl{{.*}} x
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NEXT: CompoundStmt
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+}
+
++ (void)testCm {
+// CHECK-LABEL: ObjCMethodDecl{{.*}}testCm
+// CHECK: AnnotateAttr{{.*}} "test"
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+// CHECK-NOT: AnnotateAttr
+  _Pragma("clang attribute push (__attribute__((annotate(\"applied at container start\"))), apply_to=objc_interface)");
+}
+
+// Implicit ivars shouldn't receive the attributes.
+// CHECK-LABEL: ObjCIvarDecl{{.*}}_testProp1
+// CHECK-NOT: AnnotateAttr
+
+@end
+
+@implementation testImplWithoutInterface // expected-warning {{cannot find interface declaration for 'testImplWithoutInterface'}}
+// CHECK-LABEL: ObjCInterfaceDecl{{.*}}testImplWithoutInterface
+// CHECK-NEXT: ObjCImplementation
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NEXT: ObjCSubclassingRestrictedAttr
+// CHECK-NEXT: AnnotateAttr{{.*}} "applied at container start"
+
+// CHECK-LABEL: ObjCImplementationDecl{{.*}}testImplWithoutInterface
+// CHECK-NOT: AnnotateAttr
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+@end
+
+#pragma clang attribute pop
+
+@protocol testProtocol
+// CHECK-LABEL: ObjCProtocolDecl{{.*}}testProtocol
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+// CHECK-NOT: AnnotateAttr
+
+- (void)testProtIm;
+// CHECK-LABEL: ObjCMethodDecl{{.*}}testProtIm
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+@end
+
+@protocol testForwardProtocol;
+// CHECK-LABEL: ObjCProtocolDecl{{.*}}testForwardProtocol
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+
+// Categories can't receive explicit attributes, so don't add pragma attributes
+// to them.
+@interface testInterface1(testCat)
+// CHECK-LABEL: ObjCCategoryDecl{{.*}}testCat
+// CHECK-NOT: AnnotateAttr
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+@end
+
+@implementation testInterface1(testCat)
+// CHECK-LABEL: ObjCCategoryImplDecl{{.*}}testCat
+// CHECK-NOT: AnnotateAttr
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+@end
+
+// @class/@compatibility_alias declarations can't receive explicit attributes,
+// so don't add pragma attributes to them.
+@class testClass;
+// CHECK-LABEL: ObjCInterfaceDecl{{.*}}testClass
+// CHECK-NOT: AnnotateAttr
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+@compatibility_alias testCompat testInterface1;
+// CHECK-LABEL: ObjCCompatibleAliasDecl{{.*}}testCompat
+// CHECK-NOT: AnnotateAttr
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+
+#pragma clang attribute pop // objc_subclassing_restricted
+
+@interface testInterface3
+// CHECK-LABEL: ObjCInterfaceDecl{{.*}}testInterface3
+// CHECK-NEXT: AnnotateAttr{{.*}} "test"
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+@end
+
+#pragma clang attribute pop // annotate("test")
+
+@interface testInterface4
+// CHECK-LABEL: ObjCInterfaceDecl{{.*}}testInterface4
+// CHECK-NOT: AnnotateAttr
+// CHECK-NOT: ObjCSubclassingRestrictedAttr
+@end
diff --git a/test/Misc/pragma-attribute-strict-subjects.c b/test/Misc/pragma-attribute-strict-subjects.c
new file mode 100644
index 0000000..ecd551b
--- /dev/null
+++ b/test/Misc/pragma-attribute-strict-subjects.c
@@ -0,0 +1,222 @@
+// RUN: %clang_cc1 -fsyntax-only -Wno-pragma-clang-attribute -verify %s
+// RUN: not %clang_cc1 -fsyntax-only -ast-dump -ast-dump-filter test %s | FileCheck %s
+
+// Check for contradictions in rules for attribute without a strict subject set:
+
+#pragma clang attribute push (__attribute__((annotate("subRuleContradictions"))), apply_to = any(variable, variable(is_parameter), function(is_member), variable(is_global)))
+// expected-error@-1 {{redundant attribute subject matcher sub-rule 'variable(is_parameter)'; 'variable' already matches those declarations}}
+// expected-error@-2 {{redundant attribute subject matcher sub-rule 'variable(is_global)'; 'variable' already matches those declarations}}
+
+// Ensure that we've recovered from the error:
+int testRecoverSubRuleContradiction = 0;
+// CHECK-LABEL: VarDecl{{.*}} testRecoverSubRuleContradiction
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: AnnotateAttr{{.*}} "subRuleContradictions"
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((annotate("negatedSubRuleContradictions2"))), apply_to = any(variable(unless(is_parameter)), variable(is_thread_local), function, variable(is_global)))
+// expected-error@-1 {{negated attribute subject matcher sub-rule 'variable(unless(is_parameter))' contradicts sub-rule 'variable(is_global)'}}
+// We have just one error, don't error on 'variable(is_global)'
+
+// Ensure that we've recovered from the error:
+int testRecoverNegatedContradiction = 0;
+// CHECK-LABEL: VarDecl{{.*}} testRecoverNegatedContradiction
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: AnnotateAttr{{.*}} "negatedSubRuleContradictions2"
+
+void testRecoverNegatedContradictionFunc(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testRecoverNegatedContradictionFunc
+// CHECK-NEXT: AnnotateAttr{{.*}} "negatedSubRuleContradictions2"
+
+#pragma clang attribute pop
+
+// Verify the strict subject set verification.
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function))
+
+int testRecoverStrictnessVar = 0;
+// CHECK-LABEL: VarDecl{{.*}} testRecoverStrictnessVar
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NOT: AbiTagAttr
+
+void testRecoverStrictnessFunc(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testRecoverStrictnessFunc
+// CHECK-NEXT: AbiTagAttr
+
+struct testRecoverStrictnessStruct { };
+// CHECK-LABEL: RecordDecl{{.*}} testRecoverStrictnessStruct
+// CHECK-NOT: AbiTagAttr
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, record(unless(is_union)), variable, enum))
+// expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum'}}
+
+int testRecoverExtraVar = 0;
+// CHECK-LABEL: VarDecl{{.*}} testRecoverExtraVar
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: AbiTagAttr
+
+void testRecoverExtraFunc(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testRecoverExtraFunc
+// CHECK-NEXT: AbiTagAttr
+
+struct testRecoverExtraStruct { };
+// CHECK-LABEL: RecordDecl{{.*}} testRecoverExtraStruct
+// CHECK-NEXT: AbiTagAttr
+
+enum testNoEnumAbiTag { CaseCase };
+// CHECK-LABEL: EnumDecl{{.*}} testNoEnumAbiTag
+// CHECK-NO: AbiTagAttr
+
+#pragma clang attribute pop
+
+// Verify the non-strict subject set verification.
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function))
+
+int testSubset1Var;
+// CHECK-LABEL: VarDecl{{.*}} testSubset1Var
+// CHECK-NOT: AbiTagAttr
+
+void testSubset1Func(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testSubset1Func
+// CHECK-NEXT: AbiTagAttr
+
+struct testSubset1Struct { };
+// CHECK-LABEL: RecordDecl{{.*}} testSubset1Struct
+// CHECK-NOT: AbiTagAttr
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = variable)
+
+int testSubset2Var;
+// CHECK-LABEL: VarDecl{{.*}} testSubset2Var
+// CHECK-NEXT: AbiTagAttr
+
+void testSubset2Func(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testSubset2Func
+// CHECK-NOT: AbiTagAttr
+
+struct testSubset2Struct { };
+// CHECK-LABEL: RecordDecl{{.*}} testSubset2Struct
+// CHECK-NOT: AbiTagAttr
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union))))
+
+int testSubset3Var;
+// CHECK-LABEL: VarDecl{{.*}} testSubset3Var
+// CHECK-NOT: AbiTagAttr
+
+void testSubset3Func(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testSubset3Func
+// CHECK-NOT: AbiTagAttr
+
+struct testSubset3Struct { };
+// CHECK-LABEL: RecordDecl{{.*}} testSubset3Struct
+// CHECK-NEXT: AbiTagAttr
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, variable))
+
+int testSubset4Var;
+// CHECK-LABEL: VarDecl{{.*}} testSubset4Var
+// CHECK-NEXT: AbiTagAttr
+
+void testSubset4Func(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testSubset4Func
+// CHECK-NEXT: AbiTagAttr
+
+struct testSubset4Struct { };
+// CHECK-LABEL: RecordDecl{{.*}} testSubset4Struct
+// CHECK-NOT: AbiTagAttr
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(variable, record(unless(is_union))))
+
+int testSubset5Var;
+// CHECK-LABEL: VarDecl{{.*}} testSubset5Var
+// CHECK-NEXT: AbiTagAttr
+
+void testSubset5Func(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testSubset5Func
+// CHECK-NOT: AbiTagAttr
+
+struct testSubset5Struct { };
+// CHECK-LABEL: RecordDecl{{.*}} testSubset5Struct
+// CHECK-NEXT: AbiTagAttr
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function))
+
+int testSubset6Var;
+// CHECK-LABEL: VarDecl{{.*}} testSubset6Var
+// CHECK-NOT: AbiTagAttr
+
+void testSubset6Func(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testSubset6Func
+// CHECK-NEXT: AbiTagAttr
+
+struct testSubset6Struct { };
+// CHECK-LABEL: RecordDecl{{.*}} testSubset6Struct
+// CHECK-NEXT: AbiTagAttr
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable))
+
+int testSubset7Var;
+// CHECK-LABEL: VarDecl{{.*}} testSubset7Var
+// CHECK-NEXT: AbiTagAttr
+
+void testSubset7Func(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testSubset7Func
+// CHECK-NEXT: AbiTagAttr
+
+struct testSubset7Struct { };
+// CHECK-LABEL: RecordDecl{{.*}} testSubset7Struct
+// CHECK-NEXT: AbiTagAttr
+
+#pragma clang attribute pop
+
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable, enum, enum_constant))
+// expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum_constant', and 'enum'}}
+
+int testSubsetRecoverVar;
+// CHECK-LABEL: VarDecl{{.*}} testSubsetRecoverVar
+// CHECK-NEXT: AbiTagAttr
+
+void testSubsetRecoverFunc(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testSubsetRecoverFunc
+// CHECK-NEXT: AbiTagAttr
+
+struct testSubsetRecoverStruct { };
+// CHECK-LABEL: RecordDecl{{.*}} testSubsetRecoverStruct
+// CHECK-NEXT: AbiTagAttr
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = enum)
+// expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum'}}
+
+int testSubsetNoVar;
+// CHECK-LABEL: VarDecl{{.*}} testSubsetNoVar
+// CHECK-NOT: AbiTagAttr
+
+void testSubsetNoFunc(void);
+// CHECK-LABEL: FunctionDecl{{.*}} testSubsetNoFunc
+// CHECK-NOT: AbiTagAttr
+
+struct testSubsetNoStruct { };
+// CHECK-LABEL: RecordDecl{{.*}} testSubsetNoStruct
+// CHECK-NOT: AbiTagAttr
+
+#pragma clang attribute pop
diff --git a/test/Misc/pragma-attribute-supported-attributes-list.test b/test/Misc/pragma-attribute-supported-attributes-list.test
new file mode 100644
index 0000000..0288d31
--- /dev/null
+++ b/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -0,0 +1,65 @@
+// RUN: clang-tblgen -gen-clang-test-pragma-attribute-supported-attributes -I%src_include_dir %src_include_dir/clang/Basic/Attr.td -o - | FileCheck %s
+
+// The number of supported attributes should never go down!
+
+// CHECK: #pragma clang attribute supports 60 attributes:
+// CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
+// CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
+// CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
+// CHECK-NEXT: AMDGPUWavesPerEU (SubjectMatchRule_function)
+// CHECK-NEXT: AbiTag (SubjectMatchRule_record_not_is_union, SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_namespace)
+// CHECK-NEXT: AlignValue (SubjectMatchRule_variable, SubjectMatchRule_type_alias)
+// CHECK-NEXT: AllocSize (SubjectMatchRule_function)
+// CHECK-NEXT: Annotate ()
+// CHECK-NEXT: AssumeAligned (SubjectMatchRule_objc_method, SubjectMatchRule_function)
+// CHECK-NEXT: Availability ((SubjectMatchRule_record, SubjectMatchRule_enum, SubjectMatchRule_enum_constant, SubjectMatchRule_field, SubjectMatchRule_function, SubjectMatchRule_namespace, SubjectMatchRule_objc_category, SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, SubjectMatchRule_record, SubjectMatchRule_type_alias, SubjectMatchRule_variable))
+// CHECK-NEXT: CXX11NoReturn (SubjectMatchRule_function)
+// CHECK-NEXT: CallableWhen (SubjectMatchRule_function_is_member)
+// CHECK-NEXT: CarriesDependency (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_objc_method, SubjectMatchRule_function)
+// CHECK-NEXT: Consumable (SubjectMatchRule_record)
+// CHECK-NEXT: Convergent (SubjectMatchRule_function)
+// CHECK-NEXT: DLLExport (SubjectMatchRule_function, SubjectMatchRule_variable, SubjectMatchRule_record, SubjectMatchRule_objc_interface)
+// CHECK-NEXT: DLLImport (SubjectMatchRule_function, SubjectMatchRule_variable, SubjectMatchRule_record, SubjectMatchRule_objc_interface)
+// CHECK-NEXT: DisableTailCalls (SubjectMatchRule_function, SubjectMatchRule_objc_method)
+// CHECK-NEXT: EnableIf (SubjectMatchRule_function)
+// CHECK-NEXT: EnumExtensibility (SubjectMatchRule_enum)
+// CHECK-NEXT: ExternalSourceSymbol ((SubjectMatchRule_record, SubjectMatchRule_enum, SubjectMatchRule_enum_constant, SubjectMatchRule_field, SubjectMatchRule_function, SubjectMatchRule_namespace, SubjectMatchRule_objc_category, SubjectMatchRule_objc_interface, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property, SubjectMatchRule_objc_protocol, SubjectMatchRule_record, SubjectMatchRule_type_alias, SubjectMatchRule_variable))
+// CHECK-NEXT: FlagEnum (SubjectMatchRule_enum)
+// CHECK-NEXT: Flatten (SubjectMatchRule_function)
+// CHECK-NEXT: IFunc (SubjectMatchRule_function)
+// CHECK-NEXT: InternalLinkage (SubjectMatchRule_variable, SubjectMatchRule_function, SubjectMatchRule_record)
+// CHECK-NEXT: LTOVisibilityPublic (SubjectMatchRule_record)
+// CHECK-NEXT: NoDebug (SubjectMatchRule_hasType_functionType, SubjectMatchRule_objc_method, SubjectMatchRule_variable_not_is_parameter)
+// CHECK-NEXT: NoDuplicate (SubjectMatchRule_function)
+// CHECK-NEXT: NoSanitize (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_variable_is_global)
+// CHECK-NEXT: NoSanitizeSpecific (SubjectMatchRule_function, SubjectMatchRule_variable_is_global)
+// CHECK-NEXT: NoSplitStack (SubjectMatchRule_function)
+// CHECK-NEXT: NotTailCalled (SubjectMatchRule_function)
+// CHECK-NEXT: ObjCBoxable (SubjectMatchRule_record)
+// CHECK-NEXT: ObjCMethodFamily (SubjectMatchRule_objc_method)
+// CHECK-NEXT: ObjCRequiresSuper (SubjectMatchRule_objc_method)
+// CHECK-NEXT: ObjCRuntimeName (SubjectMatchRule_objc_interface, SubjectMatchRule_objc_protocol)
+// CHECK-NEXT: ObjCRuntimeVisible (SubjectMatchRule_objc_interface)
+// CHECK-NEXT: ObjCSubclassingRestricted (SubjectMatchRule_objc_interface)
+// CHECK-NEXT: OpenCLNoSVM (SubjectMatchRule_variable)
+// CHECK-NEXT: OptimizeNone (SubjectMatchRule_function, SubjectMatchRule_objc_method)
+// CHECK-NEXT: Overloadable (SubjectMatchRule_function)
+// CHECK-NEXT: ParamTypestate (SubjectMatchRule_variable_is_parameter)
+// CHECK-NEXT: PassObjectSize (SubjectMatchRule_variable_is_parameter)
+// CHECK-NEXT: RenderScriptKernel (SubjectMatchRule_function)
+// CHECK-NEXT: RequireConstantInit (SubjectMatchRule_variable_is_global)
+// CHECK-NEXT: ReturnTypestate (SubjectMatchRule_function, SubjectMatchRule_variable_is_parameter)
+// CHECK-NEXT: ReturnsNonNull (SubjectMatchRule_objc_method, SubjectMatchRule_function)
+// CHECK-NEXT: Section (SubjectMatchRule_function, SubjectMatchRule_variable_is_global, SubjectMatchRule_objc_method, SubjectMatchRule_objc_property)
+// CHECK-NEXT: SetTypestate (SubjectMatchRule_function_is_member)
+// CHECK-NEXT: SwiftContext (SubjectMatchRule_variable_is_parameter)
+// CHECK-NEXT: SwiftError (SubjectMatchRule_objc_method, SubjectMatchRule_function)
+// CHECK-NEXT: SwiftErrorResult (SubjectMatchRule_variable_is_parameter)
+// CHECK-NEXT: SwiftIndirectResult (SubjectMatchRule_variable_is_parameter)
+// CHECK-NEXT: SwiftNewtype (SubjectMatchRule_type_alias)
+// CHECK-NEXT: SwiftObjCMembers (SubjectMatchRule_objc_interface)
+// CHECK-NEXT: TLSModel (SubjectMatchRule_variable_is_thread_local)
+// CHECK-NEXT: Target (SubjectMatchRule_function)
+// CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member)
+// CHECK-NEXT: WarnUnusedResult (SubjectMatchRule_objc_method, SubjectMatchRule_enum, SubjectMatchRule_record, SubjectMatchRule_hasType_functionType)
+// CHECK-NEXT: XRayInstrument (SubjectMatchRule_function_is_member, SubjectMatchRule_objc_method, SubjectMatchRule_function)
diff --git a/test/Modules/DebugInfoNamespace.cpp b/test/Modules/DebugInfoNamespace.cpp
new file mode 100644
index 0000000..33add08
--- /dev/null
+++ b/test/Modules/DebugInfoNamespace.cpp
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -debug-info-kind=standalone \
+// RUN:     -dwarf-ext-refs -fmodules \
+// RUN:     -fmodule-format=obj -fimplicit-module-maps \
+// RUN:     -triple %itanium_abi_triple -fmodules-cache-path=%t \
+// RUN:     %s -I %S/Inputs/DebugInfoNamespace -I %t -emit-llvm -o - \
+// RUN:     |  FileCheck %s
+
+#include "A.h"
+#include "B.h"
+using namespace N;
+B b;
+
+// Verify that the forward decl of B is in module B.
+//
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "B",
+// CHECK-SAME:             scope: ![[N:[0-9]+]]
+// CHECK: ![[N]] = !DINamespace(name: "N", scope: ![[B:[0-9]+]])
+// CHECK: ![[B]] = !DIModule(scope: null, name: "B",
diff --git a/test/Modules/DebugInfoSubmoduleImport.c b/test/Modules/DebugInfoSubmoduleImport.c
index 1b31aad..b608d30 100644
--- a/test/Modules/DebugInfoSubmoduleImport.c
+++ b/test/Modules/DebugInfoSubmoduleImport.c
@@ -2,6 +2,11 @@
 // RUN: %clang_cc1 -fmodules -fmodule-format=obj -debug-info-kind=limited -dwarf-ext-refs \
 // RUN:     -fimplicit-module-maps -x c -fmodules-cache-path=%t -I %S/Inputs \
 // RUN:     %s -emit-llvm -debugger-tuning=lldb -o - | FileCheck %s
+//
+// RUN: %clang_cc1 -fmodules -fmodule-format=obj -debug-info-kind=limited -dwarf-ext-refs \
+// RUN:     -fimplicit-module-maps -x c -fmodules-cache-path=%t -I %S/Inputs \
+// RUN:     -fmodules-local-submodule-visibility \
+// RUN:     %s -emit-llvm -debugger-tuning=lldb -o - | FileCheck %s
 #include "DebugSubmoduleA.h"
 #include "DebugSubmoduleB.h"
 
diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp
index c39bce9..a3e6776 100644
--- a/test/Modules/ExtDebugInfo.cpp
+++ b/test/Modules/ExtDebugInfo.cpp
@@ -76,7 +76,7 @@
 // CHECK-SAME:             flags: DIFlagFwdDecl,
 // CHECK-SAME:             identifier:  "_ZTSN8DebugCXX4EnumE")
 
-// CHECK: ![[NS]] = !DINamespace(name: "DebugCXX", scope: ![[MOD:[0-9]+]],
+// CHECK: ![[NS]] = !DINamespace(name: "DebugCXX", scope: ![[MOD:[0-9]+]])
 // CHECK: ![[MOD]] = !DIModule(scope: null, name: {{.*}}DebugCXX
 
 // This type is anchored in the module by an explicit template instantiation.
diff --git a/test/Modules/Inputs/DebugInfoNamespace/A.h b/test/Modules/Inputs/DebugInfoNamespace/A.h
new file mode 100644
index 0000000..dc5a1cd
--- /dev/null
+++ b/test/Modules/Inputs/DebugInfoNamespace/A.h
@@ -0,0 +1,3 @@
+namespace N {
+  struct A {};
+}
diff --git a/test/Modules/Inputs/DebugInfoNamespace/B.h b/test/Modules/Inputs/DebugInfoNamespace/B.h
new file mode 100644
index 0000000..c9033a5
--- /dev/null
+++ b/test/Modules/Inputs/DebugInfoNamespace/B.h
@@ -0,0 +1,3 @@
+namespace N {
+  struct B {};
+}
diff --git a/test/Modules/Inputs/DebugInfoNamespace/module.modulemap b/test/Modules/Inputs/DebugInfoNamespace/module.modulemap
new file mode 100644
index 0000000..9300fcf
--- /dev/null
+++ b/test/Modules/Inputs/DebugInfoNamespace/module.modulemap
@@ -0,0 +1,8 @@
+module A {
+  header "A.h"
+  export *
+}
+module B {
+  header "B.h"
+  export *
+}
diff --git a/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/B.h b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/B.h
new file mode 100644
index 0000000..761540b
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/B.h
@@ -0,0 +1 @@
+// B.h
diff --git a/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/Sub.h b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/Sub.h
new file mode 100644
index 0000000..fd86e3c
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/Headers/Sub.h
@@ -0,0 +1,2 @@
+// Sub.h
+#import "B.h"
diff --git a/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h
new file mode 100644
index 0000000..4ab49b7
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h
@@ -0,0 +1 @@
+// BPriv.h
diff --git a/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h
new file mode 100644
index 0000000..f6ac618
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h
@@ -0,0 +1 @@
+#import "BPriv.h"
diff --git a/test/Modules/Inputs/Main.framework/Headers/A.h b/test/Modules/Inputs/Main.framework/Headers/A.h
new file mode 100644
index 0000000..975f1f0
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/Headers/A.h
@@ -0,0 +1 @@
+// A.h
diff --git a/test/Modules/Inputs/Main.framework/Headers/Main.h b/test/Modules/Inputs/Main.framework/Headers/Main.h
new file mode 100644
index 0000000..cb8cc00
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/Headers/Main.h
@@ -0,0 +1,2 @@
+// Main.h
+#import "A.h"
diff --git a/test/Modules/Inputs/Main.framework/Modules/module.modulemap b/test/Modules/Inputs/Main.framework/Modules/module.modulemap
new file mode 100644
index 0000000..9fab5d3
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/Modules/module.modulemap
@@ -0,0 +1,12 @@
+framework module Main {
+  umbrella header "Main.h"
+
+  module * { export * }
+  export *
+
+  framework module Sub {
+    umbrella header "Sub.h"
+    module * { export * }
+    export *
+  }
+}
diff --git a/test/Modules/Inputs/Main.framework/Modules/module.private.modulemap b/test/Modules/Inputs/Main.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..54e8be7
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/Modules/module.private.modulemap
@@ -0,0 +1,11 @@
+module Main.Private {
+  umbrella header "MainPriv.h"
+  module * { export * }
+  export *
+}
+
+module Main.Sub.Private {
+  umbrella header "SubPriv.h"
+  module * { export * }
+  export *
+}
diff --git a/test/Modules/Inputs/Main.framework/PrivateHeaders/APriv.h b/test/Modules/Inputs/Main.framework/PrivateHeaders/APriv.h
new file mode 100644
index 0000000..6ac683c
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/PrivateHeaders/APriv.h
@@ -0,0 +1 @@
+// APriv.h
diff --git a/test/Modules/Inputs/Main.framework/PrivateHeaders/MainPriv.h b/test/Modules/Inputs/Main.framework/PrivateHeaders/MainPriv.h
new file mode 100644
index 0000000..6810301
--- /dev/null
+++ b/test/Modules/Inputs/Main.framework/PrivateHeaders/MainPriv.h
@@ -0,0 +1 @@
+#import "APriv.h"
diff --git a/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/B.h b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/B.h
new file mode 100644
index 0000000..761540b
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/B.h
@@ -0,0 +1 @@
+// B.h
diff --git a/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/Sub.h b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/Sub.h
new file mode 100644
index 0000000..fd86e3c
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/Sub.h
@@ -0,0 +1,2 @@
+// Sub.h
+#import "B.h"
diff --git a/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h
new file mode 100644
index 0000000..4ab49b7
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h
@@ -0,0 +1 @@
+// BPriv.h
diff --git a/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h
new file mode 100644
index 0000000..f6ac618
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h
@@ -0,0 +1 @@
+#import "BPriv.h"
diff --git a/test/Modules/Inputs/MainA.framework/Headers/A.h b/test/Modules/Inputs/MainA.framework/Headers/A.h
new file mode 100644
index 0000000..975f1f0
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Headers/A.h
@@ -0,0 +1 @@
+// A.h
diff --git a/test/Modules/Inputs/MainA.framework/Headers/Main.h b/test/Modules/Inputs/MainA.framework/Headers/Main.h
new file mode 100644
index 0000000..cb8cc00
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Headers/Main.h
@@ -0,0 +1,2 @@
+// Main.h
+#import "A.h"
diff --git a/test/Modules/Inputs/MainA.framework/Modules/module.modulemap b/test/Modules/Inputs/MainA.framework/Modules/module.modulemap
new file mode 100644
index 0000000..4b0b5e9
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Modules/module.modulemap
@@ -0,0 +1,12 @@
+framework module MainA {
+  umbrella header "Main.h"
+
+  module * { export * }
+  export *
+
+  framework module Sub {
+    umbrella header "Sub.h"
+    module * { export * }
+    export *
+  }
+}
diff --git a/test/Modules/Inputs/MainA.framework/Modules/module.private.modulemap b/test/Modules/Inputs/MainA.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..a8dc5c2
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Modules/module.private.modulemap
@@ -0,0 +1,12 @@
+framework module MainA_Private {
+  umbrella header "MainPriv.h"
+
+  module * { export * }
+  export *
+
+  explicit framework module Sub {
+    umbrella header "SubPriv.h"
+    module * { export * }
+    export *
+  }
+}
diff --git a/test/Modules/Inputs/MainA.framework/PrivateHeaders/APriv.h b/test/Modules/Inputs/MainA.framework/PrivateHeaders/APriv.h
new file mode 100644
index 0000000..6ac683c
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/PrivateHeaders/APriv.h
@@ -0,0 +1 @@
+// APriv.h
diff --git a/test/Modules/Inputs/MainA.framework/PrivateHeaders/MainPriv.h b/test/Modules/Inputs/MainA.framework/PrivateHeaders/MainPriv.h
new file mode 100644
index 0000000..6810301
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/PrivateHeaders/MainPriv.h
@@ -0,0 +1 @@
+#import "APriv.h"
diff --git a/test/Modules/Inputs/SameHeader/A.h b/test/Modules/Inputs/SameHeader/A.h
new file mode 100644
index 0000000..bebe9c3
--- /dev/null
+++ b/test/Modules/Inputs/SameHeader/A.h
@@ -0,0 +1,3 @@
+#ifndef __A_h__
+#define __A_h__
+#endif
diff --git a/test/Modules/Inputs/SameHeader/B.h b/test/Modules/Inputs/SameHeader/B.h
new file mode 100644
index 0000000..c3fe49c
--- /dev/null
+++ b/test/Modules/Inputs/SameHeader/B.h
@@ -0,0 +1,4 @@
+#ifndef __B_h__
+#define __B_h__
+#include "C.h"
+#endif
diff --git a/test/Modules/Inputs/SameHeader/C.h b/test/Modules/Inputs/SameHeader/C.h
new file mode 100644
index 0000000..33c3316
--- /dev/null
+++ b/test/Modules/Inputs/SameHeader/C.h
@@ -0,0 +1,12 @@
+#ifndef __C_h__
+#define __C_h__
+int c = 1;
+
+struct aaa {
+  int b;
+};
+
+typedef struct fd_set {
+  char c;
+};
+#endif
diff --git a/test/Modules/Inputs/SameHeader/module.modulemap b/test/Modules/Inputs/SameHeader/module.modulemap
new file mode 100644
index 0000000..d0283a7
--- /dev/null
+++ b/test/Modules/Inputs/SameHeader/module.modulemap
@@ -0,0 +1,11 @@
+module X {
+  module A {
+    header "A.h"
+    export *
+  }
+  module B {
+    header "B.h"
+    export *
+  }
+  export *
+}
diff --git a/test/Modules/Inputs/category_right_sub.h b/test/Modules/Inputs/category_right_sub.h
index 231f65f..c8ba793 100644
--- a/test/Modules/Inputs/category_right_sub.h
+++ b/test/Modules/Inputs/category_right_sub.h
@@ -15,3 +15,8 @@
 
 @interface Foo(LeftP4) <P4>
 @end
+
+// A hidden extension
+@interface Foo ()
+@property (assign) int hiddenPropertyFromExtension;
+@end
diff --git a/test/Modules/Inputs/diag_pragma.h b/test/Modules/Inputs/diag_pragma.h
index a8f9589..59c73ea 100644
--- a/test/Modules/Inputs/diag_pragma.h
+++ b/test/Modules/Inputs/diag_pragma.h
@@ -1,3 +1,13 @@
 #define DIAG_PRAGMA_MACRO 1
 
 #pragma clang diagnostic ignored "-Wparentheses"
+
+#ifdef __cplusplus
+template<typename T> const char *f(T t) {
+  return "foo" + t;
+}
+#pragma clang diagnostic ignored "-Wstring-plus-int"
+template<typename T> const char *g(T t) {
+  return "foo" + t;
+}
+#endif
diff --git a/test/Modules/Inputs/diagnose-missing-import/a.h b/test/Modules/Inputs/diagnose-missing-import/a.h
new file mode 100644
index 0000000..2121e96
--- /dev/null
+++ b/test/Modules/Inputs/diagnose-missing-import/a.h
@@ -0,0 +1,8 @@
+#ifndef A_h
+#define A_h
+
+@class NSString;
+static NSString * const xyzRiskyCloseOpenParam = @"riskyCloseParam";
+static inline void XYZLogEvent(NSString* eventName, NSString* params);
+
+#endif
diff --git a/test/Modules/Inputs/diagnose-missing-import/module.modulemap b/test/Modules/Inputs/diagnose-missing-import/module.modulemap
new file mode 100644
index 0000000..690501e
--- /dev/null
+++ b/test/Modules/Inputs/diagnose-missing-import/module.modulemap
@@ -0,0 +1,3 @@
+module NCI {
+  explicit module A { header "a.h" }
+}
diff --git a/test/Modules/Inputs/import-textual/M/A/A.h b/test/Modules/Inputs/import-textual/M/A/A.h
deleted file mode 100644
index ebe4979..0000000
--- a/test/Modules/Inputs/import-textual/M/A/A.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#import "someheader.h"
-
-typedef myint aint;
diff --git a/test/Modules/Inputs/import-textual/M/B/B.h b/test/Modules/Inputs/import-textual/M/B/B.h
deleted file mode 100644
index ba85071..0000000
--- a/test/Modules/Inputs/import-textual/M/B/B.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#import "someheader.h"
-
-typedef myint bint;
diff --git a/test/Modules/Inputs/import-textual/M/module.modulemap b/test/Modules/Inputs/import-textual/M/module.modulemap
deleted file mode 100644
index f801948..0000000
--- a/test/Modules/Inputs/import-textual/M/module.modulemap
+++ /dev/null
@@ -1,17 +0,0 @@
-
-module M {
-
-  module A {
-    header "A/A.h"
-    textual header "someheader.h"
-    export *
-  }
-
-  module B {
-    header "B/B.h"
-    textual header "someheader.h"
-    export *
-  }
-
-  export *
-}
diff --git a/test/Modules/Inputs/import-textual/M/someheader.h b/test/Modules/Inputs/import-textual/M/someheader.h
deleted file mode 100644
index 16fae40..0000000
--- a/test/Modules/Inputs/import-textual/M/someheader.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef C_GUARD
-#define C_GUARD
-
-typedef int myint;
-
-#endif
diff --git a/test/Modules/Inputs/import-textual/M2/A/A.h b/test/Modules/Inputs/import-textual/M2/A/A.h
deleted file mode 100644
index ebe4979..0000000
--- a/test/Modules/Inputs/import-textual/M2/A/A.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#import "someheader.h"
-
-typedef myint aint;
diff --git a/test/Modules/Inputs/import-textual/M2/B/B.h b/test/Modules/Inputs/import-textual/M2/B/B.h
deleted file mode 100644
index ba85071..0000000
--- a/test/Modules/Inputs/import-textual/M2/B/B.h
+++ /dev/null
@@ -1,4 +0,0 @@
-
-#import "someheader.h"
-
-typedef myint bint;
diff --git a/test/Modules/Inputs/import-textual/M2/module.modulemap b/test/Modules/Inputs/import-textual/M2/module.modulemap
deleted file mode 100644
index f801948..0000000
--- a/test/Modules/Inputs/import-textual/M2/module.modulemap
+++ /dev/null
@@ -1,17 +0,0 @@
-
-module M {
-
-  module A {
-    header "A/A.h"
-    textual header "someheader.h"
-    export *
-  }
-
-  module B {
-    header "B/B.h"
-    textual header "someheader.h"
-    export *
-  }
-
-  export *
-}
diff --git a/test/Modules/Inputs/import-textual/M2/someheader.h b/test/Modules/Inputs/import-textual/M2/someheader.h
deleted file mode 100644
index df2009a..0000000
--- a/test/Modules/Inputs/import-textual/M2/someheader.h
+++ /dev/null
@@ -1 +0,0 @@
-typedef int myint;
diff --git a/test/Modules/Inputs/incomplete-type/A.h b/test/Modules/Inputs/incomplete-type/A.h
new file mode 100644
index 0000000..6943aaf
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/A.h
@@ -0,0 +1 @@
+#define __P(protos)     ()
diff --git a/test/Modules/Inputs/incomplete-type/B.h b/test/Modules/Inputs/incomplete-type/B.h
new file mode 100644
index 0000000..51df71e
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/B.h
@@ -0,0 +1,2 @@
+#import "A.h"
+#import "B2.h"
diff --git a/test/Modules/Inputs/incomplete-type/B2.h b/test/Modules/Inputs/incomplete-type/B2.h
new file mode 100644
index 0000000..def109f
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/B2.h
@@ -0,0 +1,2 @@
+void test(int __P) {
+}
diff --git a/test/Modules/Inputs/incomplete-type/C.h b/test/Modules/Inputs/incomplete-type/C.h
new file mode 100644
index 0000000..ea6a2ee
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/C.h
@@ -0,0 +1,2 @@
+#import "A.h"
+#import "B.h"
diff --git a/test/Modules/Inputs/incomplete-type/module.modulemap b/test/Modules/Inputs/incomplete-type/module.modulemap
new file mode 100644
index 0000000..17c8d7d
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-type/module.modulemap
@@ -0,0 +1,15 @@
+module X {
+  header "A.h"
+  export *
+}
+
+// Y imports X
+module Y {
+  header "B.h"
+  export *
+}
+
+// Z imports X and Y
+module Z {
+  header "C.h"
+}
diff --git a/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/Bar.h b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/Bar.h
new file mode 100644
index 0000000..fb5da09
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/Bar.h
@@ -0,0 +1 @@
+#define BAR_PUBLIC 1
diff --git a/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/FooPublic.h b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/FooPublic.h
new file mode 100644
index 0000000..cbbb44f
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Headers/FooPublic.h
@@ -0,0 +1 @@
+// FooPublic.h
diff --git a/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.modulemap b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.modulemap
new file mode 100644
index 0000000..af67e65
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.modulemap
@@ -0,0 +1,5 @@
+framework module Foo {
+    umbrella header "FooPublic.h"
+    requires objc
+    export *
+}
diff --git a/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.private.modulemap b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..f6d9dfd
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/Modules/module.private.modulemap
@@ -0,0 +1,5 @@
+explicit module Foo.Private {
+    umbrella header "Foo.h"
+    requires objc
+    export *
+}
diff --git a/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Baz.h b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Baz.h
new file mode 100644
index 0000000..98064e0
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Baz.h
@@ -0,0 +1 @@
+#define BAZ_PRIVATE 1
diff --git a/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Foo.h b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Foo.h
new file mode 100644
index 0000000..9381133
--- /dev/null
+++ b/test/Modules/Inputs/incomplete-umbrella/Foo.framework/PrivateHeaders/Foo.h
@@ -0,0 +1 @@
+// Foo.h
diff --git a/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch b/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch
new file mode 100644
index 0000000..73a9816
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC-Prefix.pch
@@ -0,0 +1,3 @@
+#ifdef __OBJC__
+  #import <NC/NULog.h>
+#endif
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h
new file mode 100644
index 0000000..3866c88
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NC.h
@@ -0,0 +1 @@
+#import <NC/NUGeometry.h>
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h
new file mode 100644
index 0000000..1e7614c
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NU-Visibility.h
@@ -0,0 +1 @@
+// NU-Visibility.h
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h
new file mode 100644
index 0000000..8923e04
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Headers/NUGeometry.h
@@ -0,0 +1 @@
+#import <NC/NU-Visibility.h>
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap
new file mode 100644
index 0000000..475b414
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.modulemap
@@ -0,0 +1,6 @@
+framework module NC {
+  umbrella header "NC.h"
+
+  export *
+  module * { export * }
+}
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap
new file mode 100644
index 0000000..80488bd
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/Modules/module.private.modulemap
@@ -0,0 +1,5 @@
+explicit module NC.Private
+{
+	header "NULog.h"
+	header "NUAssert.h"
+}
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h
new file mode 100644
index 0000000..7bf8def
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NUAssert.h
@@ -0,0 +1 @@
+#import <NC/NULog.h>
diff --git a/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h
new file mode 100644
index 0000000..8923e04
--- /dev/null
+++ b/test/Modules/Inputs/invalid-module-id/NC.framework/PrivateHeaders/NULog.h
@@ -0,0 +1 @@
+#import <NC/NU-Visibility.h>
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/cstddef b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/cstddef
deleted file mode 100644
index 4898c05..0000000
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/cstddef
+++ /dev/null
@@ -1,9 +0,0 @@
-#ifndef _LIBCPP_CSTDDEF
-#define _LIBCPP_CSTDDEF
-
-#include <stddef.h>
-#include <type_traits>
-
-typedef ptrdiff_t my_ptrdiff_t;
-
-#endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
index 9e2b693..f761b91 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/math.h
@@ -4,6 +4,4 @@
 #include_next <math.h>
 template<typename T> T abs(T t) { return (t < 0) ? -t : t; }
 
-#include <type_traits>
-
 #endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
index f57c11c..b06142a 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/module.modulemap
@@ -6,7 +6,5 @@
   // FIXME: remove "textual" from stdint module below once the issue
   // between umbrella headers and builtins is resolved.
   module stdint { textual header "stdint.h" export * }
-  module type_traits { header "type_traits" export * }
-  module cstddef { header "cstddef" export * }
   module __config { header "__config" export * }
 }
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
index 14167cf..bd42008 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/stddef.h
@@ -2,6 +2,5 @@
 #define LIBCXX_STDDEF_H
 
 #include <__config>
-#include_next <stddef.h>
 
 #endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/type_traits b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/type_traits
deleted file mode 100644
index a91056e..0000000
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/c++/v1/type_traits
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _LIBCPP_TYPE_TRAITS
-#define _LIBCPP_TYPE_TRAITS
-
-#include <cstddef>
-
-#endif
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
index 25b9468..7244cb0 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/module.modulemap
@@ -5,12 +5,4 @@
   module stdint { header "stdint.h" export * }
   module stdio { header "stdio.h" export * }
   module util { header "util.h" export * }
-  module POSIX {
-    module sys {
-      module types {
-        umbrella header "sys/_types/_types.h"
-        export *
-      }
-    }
-  }
 }
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
index b98249f..eca7241 100644
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
+++ b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/stddef.h
@@ -1,6 +1 @@
-#ifndef __STDDEF_H__
-#define __STDDEF_H__
-
-#include "sys/_types/_ptrdiff_t.h"
-
-#endif
+// stddef.h
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_ptrdiff_t.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_ptrdiff_t.h
deleted file mode 100644
index d14110e..0000000
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_ptrdiff_t.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef int * ptrdiff_t;
-#endif /* _PTRDIFF_T */
diff --git a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_types.h b/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_types.h
deleted file mode 100644
index 33d5e51..0000000
--- a/test/Modules/Inputs/libc-libcxx/sysroot/usr/include/sys/_types/_types.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _SYS_TYPES_UMBRELLA
-#define _SYS_TYPES_UMBRELLA
-
-#include "_ptrdiff_t.h"
-
-#endif
diff --git a/test/Modules/Inputs/malformed-overload/X.h b/test/Modules/Inputs/malformed-overload/X.h
new file mode 100644
index 0000000..b659406
--- /dev/null
+++ b/test/Modules/Inputs/malformed-overload/X.h
@@ -0,0 +1,2 @@
+@class NSString;
+extern void NSLog(NSString *format, ...) __attribute__((format(__NSString__, 1, 2))) __attribute__((not_tail_called));
diff --git a/test/Modules/Inputs/malformed-overload/module.modulemap b/test/Modules/Inputs/malformed-overload/module.modulemap
new file mode 100644
index 0000000..8fe4c92
--- /dev/null
+++ b/test/Modules/Inputs/malformed-overload/module.modulemap
@@ -0,0 +1,4 @@
+module X {
+  header "X.h"
+  export *
+}
diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map
index 2beb942..094578a 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -265,6 +265,11 @@
   header "diag_pragma.h"
 }
 
+module pragma_pack {
+  module set { header "pragma_pack_set.h" }
+  module empty { header "empty.h" }
+}
+
 module dummy {
   header "dummy.h"
 }
@@ -432,3 +437,7 @@
   header "DebugNestedB.h"
   export *
 }
+
+module objcAtKeywordMissingEnd {
+  header "objcAtKeywordMissingEnd.h"
+}
diff --git a/test/Modules/Inputs/objc-desig-init/A.h b/test/Modules/Inputs/objc-desig-init/A.h
new file mode 100644
index 0000000..02e0105
--- /dev/null
+++ b/test/Modules/Inputs/objc-desig-init/A.h
@@ -0,0 +1 @@
+#import "A2.h"
diff --git a/test/Modules/Inputs/objc-desig-init/A2.h b/test/Modules/Inputs/objc-desig-init/A2.h
new file mode 100644
index 0000000..5a4ceb4
--- /dev/null
+++ b/test/Modules/Inputs/objc-desig-init/A2.h
@@ -0,0 +1,4 @@
+#import "Base.h"
+
+@interface A2 : Base
+@end
diff --git a/test/Modules/Inputs/objc-desig-init/Base.h b/test/Modules/Inputs/objc-desig-init/Base.h
new file mode 100644
index 0000000..4718425
--- /dev/null
+++ b/test/Modules/Inputs/objc-desig-init/Base.h
@@ -0,0 +1,4 @@
+@class NSString;
+@interface Base
+- (id)initWithNibName:(NSString *)nibNameOrNil __attribute__((objc_designated_initializer));
+@end
diff --git a/test/Modules/Inputs/objc-desig-init/X.h b/test/Modules/Inputs/objc-desig-init/X.h
new file mode 100644
index 0000000..cb46ba7
--- /dev/null
+++ b/test/Modules/Inputs/objc-desig-init/X.h
@@ -0,0 +1,4 @@
+#import "A2.h"
+
+@interface X : A2
+@end
diff --git a/test/Modules/Inputs/objc-desig-init/module.modulemap b/test/Modules/Inputs/objc-desig-init/module.modulemap
new file mode 100644
index 0000000..0150efb
--- /dev/null
+++ b/test/Modules/Inputs/objc-desig-init/module.modulemap
@@ -0,0 +1,9 @@
+module Base {
+  header "Base.h"
+  export *
+}
+
+module A {
+  header "A.h"
+  export *
+}
diff --git a/test/Modules/Inputs/objcAtKeywordMissingEnd.h b/test/Modules/Inputs/objcAtKeywordMissingEnd.h
new file mode 100644
index 0000000..1196b87
--- /dev/null
+++ b/test/Modules/Inputs/objcAtKeywordMissingEnd.h
@@ -0,0 +1,3 @@
+@interface MissingEnd // expected-note {{class started here}}
+
+@ // expected-error {{expected an Objective-C directive after '@'}} expected-error {{missing '@end'}}
diff --git a/test/Modules/Inputs/outofdate-rebuild/AppKit.h b/test/Modules/Inputs/outofdate-rebuild/AppKit.h
new file mode 100644
index 0000000..e357918
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/AppKit.h
@@ -0,0 +1,3 @@
+// AppKit
+#import "CoreVideo.h" // CoreVideo
+struct B { int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/Cocoa.h b/test/Modules/Inputs/outofdate-rebuild/Cocoa.h
new file mode 100644
index 0000000..d631140
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/Cocoa.h
@@ -0,0 +1,5 @@
+// Cocoa
+#import "Foundation.h"
+#import "AppKit.h"
+
+struct A {  int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/CoreText.h b/test/Modules/Inputs/outofdate-rebuild/CoreText.h
new file mode 100644
index 0000000..7ff0e23
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/CoreText.h
@@ -0,0 +1 @@
+struct C { int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/CoreVideo.h b/test/Modules/Inputs/outofdate-rebuild/CoreVideo.h
new file mode 100644
index 0000000..bd249dc
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/CoreVideo.h
@@ -0,0 +1,3 @@
+// CoreVideo
+#import "Foundation.h" // Foundation
+struct E { int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/Foundation.h b/test/Modules/Inputs/outofdate-rebuild/Foundation.h
new file mode 100644
index 0000000..b2d053a
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/Foundation.h
@@ -0,0 +1,3 @@
+// Foundation
+#import "CoreText.h"
+struct D { int i; };
diff --git a/test/Modules/Inputs/outofdate-rebuild/module.modulemap b/test/Modules/Inputs/outofdate-rebuild/module.modulemap
new file mode 100644
index 0000000..71c99e8
--- /dev/null
+++ b/test/Modules/Inputs/outofdate-rebuild/module.modulemap
@@ -0,0 +1,19 @@
+module Cocoa {
+  header "Cocoa.h"
+}
+
+module AppKit {
+  header "AppKit.h"
+}
+
+module CoreText {
+  header "CoreText.h"
+}
+
+module Foundation {
+  header "Foundation.h"
+}
+
+module CoreVideo {
+  header "CoreVideo.h"
+}
diff --git a/test/Modules/Inputs/pragma_pack_set.h b/test/Modules/Inputs/pragma_pack_set.h
new file mode 100644
index 0000000..b123c11
--- /dev/null
+++ b/test/Modules/Inputs/pragma_pack_set.h
@@ -0,0 +1,3 @@
+
+#pragma pack (1)
+
diff --git a/test/Modules/Inputs/shadow/A1/A.h b/test/Modules/Inputs/shadow/A1/A.h
new file mode 100644
index 0000000..f07c681
--- /dev/null
+++ b/test/Modules/Inputs/shadow/A1/A.h
@@ -0,0 +1 @@
+#define A1_A_h
diff --git a/test/Modules/Inputs/shadow/A1/module.modulemap b/test/Modules/Inputs/shadow/A1/module.modulemap
new file mode 100644
index 0000000..9439a43
--- /dev/null
+++ b/test/Modules/Inputs/shadow/A1/module.modulemap
@@ -0,0 +1,5 @@
+module A {
+  header "A.h"
+}
+
+module A1 {}
diff --git a/test/Modules/Inputs/shadow/A2/A.h b/test/Modules/Inputs/shadow/A2/A.h
new file mode 100644
index 0000000..9880ed0
--- /dev/null
+++ b/test/Modules/Inputs/shadow/A2/A.h
@@ -0,0 +1 @@
+#define A2_A_h
diff --git a/test/Modules/Inputs/shadow/A2/module.modulemap b/test/Modules/Inputs/shadow/A2/module.modulemap
new file mode 100644
index 0000000..935d89b
--- /dev/null
+++ b/test/Modules/Inputs/shadow/A2/module.modulemap
@@ -0,0 +1,5 @@
+module A {
+  header "A.h"
+}
+
+module A2 {}
diff --git a/test/Modules/Inputs/swift_name/module.modulemap b/test/Modules/Inputs/swift_name/module.modulemap
new file mode 100644
index 0000000..b7ec6b1
--- /dev/null
+++ b/test/Modules/Inputs/swift_name/module.modulemap
@@ -0,0 +1,2 @@
+module SwiftNameInferred [swift_infer_import_as_member] {
+}
\ No newline at end of file
diff --git a/test/Modules/Inputs/system-out-of-date/X.h b/test/Modules/Inputs/system-out-of-date/X.h
new file mode 100644
index 0000000..edcfa18
--- /dev/null
+++ b/test/Modules/Inputs/system-out-of-date/X.h
@@ -0,0 +1 @@
+#import <Y.h>
diff --git a/test/Modules/Inputs/system-out-of-date/Y.h b/test/Modules/Inputs/system-out-of-date/Y.h
new file mode 100644
index 0000000..90fe1bc
--- /dev/null
+++ b/test/Modules/Inputs/system-out-of-date/Y.h
@@ -0,0 +1 @@
+//empty
diff --git a/test/Modules/Inputs/system-out-of-date/Z.h b/test/Modules/Inputs/system-out-of-date/Z.h
new file mode 100644
index 0000000..edcfa18
--- /dev/null
+++ b/test/Modules/Inputs/system-out-of-date/Z.h
@@ -0,0 +1 @@
+#import <Y.h>
diff --git a/test/Modules/Inputs/system-out-of-date/module.map b/test/Modules/Inputs/system-out-of-date/module.map
new file mode 100644
index 0000000..0c0f42a
--- /dev/null
+++ b/test/Modules/Inputs/system-out-of-date/module.map
@@ -0,0 +1,12 @@
+module X [system] {
+  header "X.h" // imports Y
+  export *
+}
+module Y {
+  header "Y.h"
+  export *
+}
+module Z {
+  header "Z.h" // imports Y
+  export *
+}
diff --git a/test/Modules/Inputs/warning-mismatch/Mismatch.h b/test/Modules/Inputs/warning-mismatch/Mismatch.h
new file mode 100644
index 0000000..a07b0ee
--- /dev/null
+++ b/test/Modules/Inputs/warning-mismatch/Mismatch.h
@@ -0,0 +1 @@
+struct Mismatch { int i; };
diff --git a/test/Modules/Inputs/warning-mismatch/System.h b/test/Modules/Inputs/warning-mismatch/System.h
new file mode 100644
index 0000000..8e69e70
--- /dev/null
+++ b/test/Modules/Inputs/warning-mismatch/System.h
@@ -0,0 +1,2 @@
+#import "Mismatch.h"
+struct System { int i; };
diff --git a/test/Modules/Inputs/warning-mismatch/module.modulemap b/test/Modules/Inputs/warning-mismatch/module.modulemap
new file mode 100644
index 0000000..c22cde4
--- /dev/null
+++ b/test/Modules/Inputs/warning-mismatch/module.modulemap
@@ -0,0 +1,7 @@
+module System [system] {
+  header "System.h"
+}
+
+module Mismatch {
+  header "Mismatch.h"
+}
diff --git a/test/Modules/builtin-import.mm b/test/Modules/builtin-import.mm
deleted file mode 100644
index 2536ac5..0000000
--- a/test/Modules/builtin-import.mm
+++ /dev/null
@@ -1,12 +0,0 @@
-// REQUIRES: system-darwin
-
-// RUN: rm -rf %t
-// RUN: %clang -cc1 -fsyntax-only -nostdinc++ -isysroot %S/Inputs/libc-libcxx/sysroot -isystem %S/Inputs/libc-libcxx/sysroot/usr/include/c++/v1 -std=c++11 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s
-
-#include <stdio.h>
-#include <stddef.h>
-#include <cstddef>
-
-typedef ptrdiff_t try1_ptrdiff_t;
-typedef my_ptrdiff_t try2_ptrdiff_t;
-
diff --git a/test/Modules/diag-pragma.cpp b/test/Modules/diag-pragma.cpp
new file mode 100644
index 0000000..347401f
--- /dev/null
+++ b/test/Modules/diag-pragma.cpp
@@ -0,0 +1,47 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodules-cache-path=%t -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -fmodules-ts
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -emit-module -fmodule-name=diag_pragma -x c++ %S/Inputs/module.map -fmodules-ts -o %t/explicit.pcm -Werror=string-plus-int
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -I %S/Inputs %s -fmodules-ts -DEXPLICIT_FLAG -fmodule-file=%t/explicit.pcm
+
+import diag_pragma;
+
+int foo(int x) {
+  // Diagnostics from templates in the module follow the diagnostic state from
+  // when the module was built.
+#ifdef EXPLICIT_FLAG
+  // expected-error@diag_pragma.h:7 {{adding 'int' to a string}}
+#else
+  // expected-warning@diag_pragma.h:7 {{adding 'int' to a string}}
+#endif
+  // expected-note@diag_pragma.h:7 {{use array indexing}}
+  f(0); // expected-note {{instantiation of}}
+
+  g(0); // ok, warning was ignored when building module
+
+  // Diagnostics from this source file ignore the diagnostic state from the
+  // module.
+  void("foo" + x); // expected-warning {{adding 'int' to a string}}
+  // expected-note@-1 {{use array indexing}}
+
+#pragma clang diagnostic ignored "-Wstring-plus-int"
+
+  // Diagnostics from the module ignore diagnostic state changes from this
+  // source file.
+#ifdef EXPLICIT_FLAG
+  // expected-error@diag_pragma.h:7 {{adding 'long' to a string}}
+#else
+  // expected-warning@diag_pragma.h:7 {{adding 'long' to a string}}
+#endif
+  // expected-note@diag_pragma.h:7 {{use array indexing}}
+  f(0L); // expected-note {{instantiation of}}
+
+  g(0L);
+
+  void("bar" + x);
+
+  if (x = DIAG_PRAGMA_MACRO) // expected-warning {{using the result of an assignment as a condition without parentheses}} \
+                             // expected-note {{place parentheses}} expected-note {{use '=='}}
+    return 0;
+  return 1;
+}
diff --git a/test/Modules/diagnose-missing-import.m b/test/Modules/diagnose-missing-import.m
new file mode 100644
index 0000000..e0c0457
--- /dev/null
+++ b/test/Modules/diagnose-missing-import.m
@@ -0,0 +1,14 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I%S/Inputs/diagnose-missing-import \
+// RUN:   -Werror=implicit-function-declaration -fsyntax-only \
+// RUN:   -fimplicit-module-maps -verify %s
+@import NCI;
+
+void foo() {
+  XYZLogEvent(xyzRiskyCloseOpenParam, xyzRiskyCloseOpenParam); // expected-error {{implicit declaration of function 'XYZLogEvent'}} expected-error {{declaration of 'XYZLogEvent' must be imported}} expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}} expected-error {{declaration of 'xyzRiskyCloseOpenParam' must be imported from module 'NCI.A'}}
+}
+
+// expected-note@Inputs/diagnose-missing-import/a.h:5 {{previous declaration is here}}
+// expected-note@Inputs/diagnose-missing-import/a.h:5 {{previous declaration is here}}
+// expected-note@Inputs/diagnose-missing-import/a.h:6 {{previous declaration is here}}
+
diff --git a/test/Modules/diagnostic-options-out-of-date.m b/test/Modules/diagnostic-options-out-of-date.m
index ed9e8e1..fd98a8f 100644
--- a/test/Modules/diagnostic-options-out-of-date.m
+++ b/test/Modules/diagnostic-options-out-of-date.m
@@ -7,6 +7,16 @@
 // RUN: %clang_cc1 -Werror -Wconversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s -fmodules-disable-diagnostic-validation
 // Make sure we don't error out when using the pch
 // RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify -fmodules-disable-diagnostic-validation
+
+// Build A.pcm
+// RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s
+// Build pch that imports A.pcm
+// RUN: %clang_cc1 -Werror -Wno-conversion -emit-pch -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -o %t.pch -I %S/Inputs -x objective-c-header %S/Inputs/pch-import-module-out-of-date.pch
+// We will rebuild A.pcm and overwrite the original A.pcm that the pch imports, but the two versions have the same hash.
+// RUN: %clang_cc1 -Werror -Wconversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s
+// Make sure we don't error out when using the pch
+// RUN: %clang_cc1 -Werror -Wno-conversion -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -fsyntax-only -I %S/Inputs -include-pch %t.pch %s -verify
+
 // expected-no-diagnostics
 
 @import DiagOutOfDate;
diff --git a/test/Modules/find-privateheaders.m b/test/Modules/find-privateheaders.m
new file mode 100644
index 0000000..5720a73
--- /dev/null
+++ b/test/Modules/find-privateheaders.m
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t.cache
+// RUN: %clang_cc1 -fmodules -fsyntax-only -F%S/Inputs -fimplicit-module-maps \
+// RUN:   -fmodules-cache-path=%t.cache -Wno-private-module -DBUILD_PUBLIC -verify %s
+// RUN: rm -rf %t.cache
+// RUN: %clang_cc1 -fmodules -fsyntax-only -F%S/Inputs -fimplicit-module-maps \
+// RUN:   -fmodules-cache-path=%t.cache -Wno-private-module -verify %s
+//expected-no-diagnostics
+
+#ifdef BUILD_PUBLIC
+#import "Main/Main.h"
+#else
+#import "MainA/MainPriv.h"
+#endif
diff --git a/test/Modules/hash-werror.m b/test/Modules/hash-werror.m
new file mode 100644
index 0000000..85446ce
--- /dev/null
+++ b/test/Modules/hash-werror.m
@@ -0,0 +1,54 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+
+// (1) Test -Werror
+// RUN: echo 'int foo() { return fn(); }' > %t/foo.h
+// RUN: echo 'module foo { header "foo.h" export * }' > %t/module.modulemap
+//
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps %s -fsyntax-only \
+// RUN:   -I%t -fmodules-cache-path=%t/cache -Rmodule-build \
+// RUN:   -fmodules-hash-error-diagnostics 2>%t/out
+//
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps %s -fsyntax-only \
+// RUN:   -I%t -Werror -fmodules-cache-path=%t/cache -Rmodule-build \
+// RUN:   -Wno-implicit-function-declaration \
+// RUN:   -fmodules-hash-error-diagnostics 2>>%t/out
+
+// RUN: FileCheck --check-prefix=CHECKWERROR %s -input-file %t/out
+// CHECKWERROR: remark: building module 'foo' as '/[[PATH:.*]]/foo-
+// CHECKWERROR-NOT: remark: building module 'foo' as '/[[PATH]]/foo-
+
+// (2) Test -Werror=
+// RUN: rm -rf %t/out %t/cache
+//
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps %s -fsyntax-only \
+// RUN:   -I%t -Werror -fmodules-cache-path=%t/cache -Rmodule-build \
+// RUN:   -fmodules-hash-error-diagnostics 2>%t/out
+//
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps %s -fsyntax-only \
+// RUN:   -I%t -fmodules-cache-path=%t/cache -Rmodule-build \
+// RUN:   -Werror=implicit-function-declaration \
+// RUN:   -fmodules-hash-error-diagnostics 2>>%t/out
+
+// RUN: FileCheck --check-prefix=CHECKWERROREQUALS %s -input-file %t/out
+// CHECKWERROREQUALS: remark: building module 'foo' as '/[[PATH:.*]]/foo-
+// CHECKWERROREQUALS-NOT: remark: building module 'foo' as '/[[PATH]]/foo-
+
+// (3) Test -pedantic-errors
+// RUN: rm -rf %t/out %t/cache
+// RUN: echo '#ifdef foo' > %t/foo.h
+// RUN: echo '#endif bad // extension!' >> %t/foo.h
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps %s -fsyntax-only \
+// RUN:   -I%t -fmodules-cache-path=%t/cache -Rmodule-build -x c \
+// RUN:   -fmodules-hash-error-diagnostics 2>%t/out
+//
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps %s -fsyntax-only \
+// RUN:   -I%t -pedantic-errors -fmodules-cache-path=%t/cache -Rmodule-build -x c \
+// RUN:   -fmodules-hash-error-diagnostics 2>>%t/out
+
+// RUN: FileCheck --check-prefix=CHECKPEDANTICERROR %s -input-file %t/out
+// CHECKPEDANTICERROR: remark: building module 'foo' as '/[[PATH:.*]]/foo-
+// CHECKPEDANTICERROR-NOT: remark: building module 'foo' as '/[[PATH]]/foo-
+
+#include "foo.h"
diff --git a/test/Modules/import-textual-noguard.mm b/test/Modules/import-textual-noguard.mm
deleted file mode 100644
index dd124b6..0000000
--- a/test/Modules/import-textual-noguard.mm
+++ /dev/null
@@ -1,8 +0,0 @@
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fmodules -fimplicit-module-maps -I%S/Inputs/import-textual/M2 -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s -verify
-
-#include "A/A.h" // expected-error {{could not build module 'M'}}
-#include "B/B.h"
-
-typedef aint xxx;
-typedef bint yyy;
diff --git a/test/Modules/import-textual.mm b/test/Modules/import-textual.mm
deleted file mode 100644
index 6593239..0000000
--- a/test/Modules/import-textual.mm
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fmodules -fimplicit-module-maps -I%S/Inputs/import-textual/M -fmodules-cache-path=%t -x objective-c++ -fmodules-local-submodule-visibility %s -verify
-
-// expected-no-diagnostics
-
-#include "A/A.h"
-#include "B/B.h"
-
-typedef aint xxx;
-typedef bint yyy;
diff --git a/test/Modules/incomplete-type-void.c b/test/Modules/incomplete-type-void.c
new file mode 100644
index 0000000..2ce00f7
--- /dev/null
+++ b/test/Modules/incomplete-type-void.c
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t.cache
+// RUN: %clang_cc1 -fmodules %s -fmodules-cache-path=%t.cache \
+// RUN:     -fsyntax-only -I %S/Inputs/incomplete-type -verify
+
+// expected-no-diagnostics
+
+#import "C.h"
+#import "A.h"
+void foo __P(());
diff --git a/test/Modules/incomplete-umbrella.m b/test/Modules/incomplete-umbrella.m
new file mode 100644
index 0000000..8760b81
--- /dev/null
+++ b/test/Modules/incomplete-umbrella.m
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -F%S/Inputs/incomplete-umbrella -fsyntax-only %s 2>&1 | FileCheck %s
+
+#import <Foo/Foo.h>
+#import <Foo/Bar.h>
+#import <Foo/Baz.h>
+@import Foo.Private;
+
+// CHECK: warning: umbrella header for module 'Foo' does not include header 'Bar.h'
+// CHECK: warning: umbrella header for module 'Foo.Private' does not include header 'Baz.h'
+int foo() {
+  int a = BAR_PUBLIC;
+  int b = BAZ_PRIVATE;
+  return 0;
+}
diff --git a/test/Modules/infer_swift_name.m b/test/Modules/infer_swift_name.m
new file mode 100644
index 0000000..d4b4a5d
--- /dev/null
+++ b/test/Modules/infer_swift_name.m
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/swift_name %s -verify
+// REQUIRES: shell
+
+@import SwiftNameInferred; // ok
+@import SwiftName; // expected-error{{module 'SwiftName' not found}}
diff --git a/test/Modules/invalid-pch-module-id.m b/test/Modules/invalid-pch-module-id.m
new file mode 100644
index 0000000..34d9995
--- /dev/null
+++ b/test/Modules/invalid-pch-module-id.m
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t.cache
+//
+// RUN: %clang_cc1 -x objective-c-header -fmodules -F%S/Inputs/invalid-module-id \
+// RUN:  -fmodule-implementation-of NC -fmodules-cache-path=%t.cache \
+// RUN:  -fimplicit-module-maps \
+// RUN:  -emit-pch %S/Inputs/invalid-module-id/NC-Prefix.pch -o %t.pch
+//
+// RUN: %clang_cc1 -x objective-c -fmodules -F%S/Inputs/invalid-module-id \
+// RUN:  -fmodule-implementation-of NC -fmodules-cache-path=%t.cache \
+// RUN:  -fimplicit-module-maps -include-pch %t.pch %s -fsyntax-only
+
+#import <NC/NULog.h>
+#import <NC/NUGeometry.h>
diff --git a/test/Modules/localsubmodulevis.m b/test/Modules/localsubmodulevis.m
new file mode 100644
index 0000000..f8c4b3c
--- /dev/null
+++ b/test/Modules/localsubmodulevis.m
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fimplicit-module-maps -fmodules-cache-path=%t.a -I %S/Inputs/preprocess -verify %s
+// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fimplicit-module-maps -fmodules-cache-path=%t.b -I %S/Inputs/preprocess -x c -verify -x c %s
+
+// expected-no-diagnostics
+
+#include "file.h"
+
diff --git a/test/Modules/malformed-overload.m b/test/Modules/malformed-overload.m
new file mode 100644
index 0000000..ad6db8a
--- /dev/null
+++ b/test/Modules/malformed-overload.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -I%S/Inputs/malformed-overload -fmodules -fimplicit-module-maps -fmodules-cache-path=tmp -verify %s
+NSLog(@"%@", path); // expected-error {{expected parameter declarator}} expected-error {{expected ')'}} expected-warning {{type specifier missing}} expected-warning {{incompatible redeclaration}} expected-note {{to match this '('}} expected-note {{'NSLog' is a builtin with type}}
+#import "X.h"
+
+@class NSString;
+void f(NSString *a) {
+ NSLog(@"***** failed to get URL for %@", a);
+}
diff --git a/test/Modules/minimal-identifier-tables.cpp b/test/Modules/minimal-identifier-tables.cpp
deleted file mode 100644
index 0674746..0000000
--- a/test/Modules/minimal-identifier-tables.cpp
+++ /dev/null
@@ -1,10 +0,0 @@
-// RUN: rm -rf %t
-// RUN: mkdir %t
-// RUN: echo 'extern int some_long_variable_name;' > %t/x.h
-// RUN: echo 'extern int some_long_variable_name;' > %t/y.h
-// RUN: echo 'module X { header "x.h" } module Y { header "y.h" }' > %t/map
-// RUN: %clang_cc1 -fmodules -x c++ -fmodule-name=X %t/map -emit-module -o %t/x.pcm
-// RUN: %clang_cc1 -fmodules -x c++ -fmodule-name=Y %t/map -fmodule-file=%t/x.pcm -emit-module -o %t/y.pcm
-// RUN: cat %t/y.pcm | FileCheck %s
-//
-// CHECK-NOT: some_long_variable_name
diff --git a/test/Modules/module_file_info.m b/test/Modules/module_file_info.m
index fa841b7..f2967be 100644
--- a/test/Modules/module_file_info.m
+++ b/test/Modules/module_file_info.m
@@ -29,13 +29,9 @@
 // CHECK:     CPU:
 // CHECK:     ABI:
 
-// CHECK: Diagnostic options:
-// CHECK:   IgnoreWarnings: Yes
-// CHECK:   Diagnostic flags:
-// CHECK:     -Wunused
-
 // CHECK: Header search options:
 // CHECK:   System root [-isysroot=]: '/'
+// CHECK:   Resource dir [ -resource-dir=]: '{{.*}}clang{{.*}}'
 // CHECK:   Use builtin include directories [-nobuiltininc]: Yes
 // CHECK:   Use standard system include directories [-nostdinc]: No
 // CHECK:   Use standard C++ include directories [-nostdinc++]: Yes
@@ -47,3 +43,8 @@
 // CHECK:   Predefined macros:
 // CHECK:     -DBLARG
 // CHECK:     -DWIBBLE=WOBBLE
+
+// CHECK: Diagnostic options:
+// CHECK:   IgnoreWarnings: Yes
+// CHECK:   Diagnostic flags:
+// CHECK:     -Wunused
diff --git a/test/Modules/modules-cache-path-canonicalization.m b/test/Modules/modules-cache-path-canonicalization.m
new file mode 100644
index 0000000..5cb0ff5
--- /dev/null
+++ b/test/Modules/modules-cache-path-canonicalization.m
@@ -0,0 +1,30 @@
+// RUN: rm -rf %t/cache %T/rel
+
+// This testcase reproduces a use-after-free after looking up a PCM in
+// a non-canonical modules-cache-path.
+//
+// Prime the module cache (note the '.' in the path).
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/./cache \
+// RUN:   -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \
+// RUN:   %s -fsyntax-only
+//
+// Force a module to be rebuilt by creating a conflict.
+// RUN: echo "@import CoreText;" > %t.m
+// RUN: %clang_cc1 -DMISMATCH -Werror -fdisable-module-hash \
+// RUN:   -fmodules-cache-path=%t/./cache -fmodules -fimplicit-module-maps \
+// RUN:   -I %S/Inputs/outofdate-rebuild %t.m -fsyntax-only
+//
+// Rebuild.
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t/./cache \
+// RUN:   -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \
+// RUN:   %s -fsyntax-only
+
+
+// Unrelated to the above: Check that a relative path is resolved correctly.
+//
+// RUN: %clang_cc1 -working-directory %T/rel -fmodules-cache-path=./cache \
+// RUN:   -fmodules -fimplicit-module-maps -I %S/Inputs/outofdate-rebuild \
+// RUN:   -fdisable-module-hash %t.m -fsyntax-only -Rmodule-build 2>&1 \
+// RUN:   | FileCheck %s
+// CHECK: {{/|\\\\}}rel{{/|\\\\}}cache{{/|\\\\}}CoreText.pcm
+@import Cocoa;
diff --git a/test/Modules/objc-at-keyword.m b/test/Modules/objc-at-keyword.m
new file mode 100644
index 0000000..0e058a3
--- /dev/null
+++ b/test/Modules/objc-at-keyword.m
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -verify -x objective-c -fmodule-name=objcAtKeywordMissingEnd -emit-module %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -x objective-c -fmodule-name=Empty -emit-module %S/Inputs/module.map
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -verify -I %S/Inputs %s
+
+@interface X // expected-note {{class started here}}
+#pragma clang module import Empty // expected-error {{missing '@end'}}
diff --git a/test/Modules/objc-categories.m b/test/Modules/objc-categories.m
index 42baf35..fcffe3c 100644
--- a/test/Modules/objc-categories.m
+++ b/test/Modules/objc-categories.m
@@ -53,6 +53,9 @@
   p3p = foo.p3_prop; // expected-error{{property 'p3_prop' not found on object of type 'Foo *'}}
   id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}}
   p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'}}
+
+  if (foo.hiddenPropertyFromExtension) { // expected-error {{property 'hiddenPropertyFromExtension' not found on object of type 'Foo *'}}
+  }
 }
 
 @import category_left.sub;
@@ -74,6 +77,7 @@
   id p4p = p4.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'id<P4>'}}
   p4p = foo.p4_prop; // expected-error{{property 'p4_prop' not found on object of type 'Foo *'; did you mean 'p3_prop'?}}
   // expected-note@Inputs/category_left_sub.h:7{{'p3_prop' declared here}}
+  int hiddenFromExtension = foo.hiddenPropertyFromExtension; // expected-error {{property 'hiddenPropertyFromExtension' not found on object of type 'Foo *'}}
 }
 
 @import category_right.sub;
@@ -92,4 +96,6 @@
   p3p = foo.p3_prop;
   id p4p = p4.p4_prop;
   p4p = foo.p4_prop;
+  if (foo.hiddenPropertyFromExtension) {
+  }
 }
diff --git a/test/Modules/objc-designated-init-mod.m b/test/Modules/objc-designated-init-mod.m
new file mode 100644
index 0000000..15c25a3
--- /dev/null
+++ b/test/Modules/objc-designated-init-mod.m
@@ -0,0 +1,17 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/objc-desig-init %s -verify
+// expected-no-diagnostics
+
+#import "X.h"
+#import "Base.h"
+#import "A.h"
+
+@implementation X
+
+- (instancetype)initWithNibName:(NSString *)nibName {
+  if ((self = [super initWithNibName:nibName])) {
+		return self;
+  }
+  return self;
+}
+@end
diff --git a/test/Modules/outofdate-rebuild.m b/test/Modules/outofdate-rebuild.m
new file mode 100644
index 0000000..510325f
--- /dev/null
+++ b/test/Modules/outofdate-rebuild.m
@@ -0,0 +1,15 @@
+// RUN: rm -rf %t.cache
+// RUN: echo "@import CoreText;" > %t.m
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t.cache \
+// RUN:   -fmodules -fimplicit-module-maps -I%S/Inputs/outofdate-rebuild %s \
+// RUN:   -fsyntax-only
+// RUN: %clang_cc1 -DMISMATCH -Werror -fdisable-module-hash \
+// RUN:   -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps \
+// RUN:   -I%S/Inputs/outofdate-rebuild %t.m -fsyntax-only
+// RUN: %clang_cc1 -fdisable-module-hash -fmodules-cache-path=%t.cache \
+// RUN:   -fmodules -fimplicit-module-maps -I%S/Inputs/outofdate-rebuild %s \
+// RUN:   -fsyntax-only
+
+// This testcase reproduces a use-after-free in when ModuleManager removes an
+// entry from the PCMCache without notifying its parent ASTReader.
+@import Cocoa;
diff --git a/test/Modules/pragma-pack.cpp b/test/Modules/pragma-pack.cpp
new file mode 100644
index 0000000..96a880c
--- /dev/null
+++ b/test/Modules/pragma-pack.cpp
@@ -0,0 +1,25 @@
+// RUN: rm -rf %t.cache %tlocal.cache
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \
+// RUN:   -fimplicit-module-maps -x c++ -emit-module \
+// RUN:   -fmodules-cache-path=%t.cache \
+// RUN:   -fmodule-name=pragma_pack %S/Inputs/module.map
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \
+// RUN:   -fimplicit-module-maps -x c++ -verify \
+// RUN:   -fmodules-cache-path=%t.cache \
+// RUN:   -I%S/Inputs %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \
+// RUN:   -fmodules-local-submodule-visibility \
+// RUN:   -fimplicit-module-maps -x c++ -emit-module \
+// RUN:   -fmodules-cache-path=%tlocal.cache \
+// RUN:   -fmodule-name=pragma_pack %S/Inputs/module.map
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fmodules \
+// RUN:   -fmodules-local-submodule-visibility \
+// RUN:   -fimplicit-module-maps -x c++ -verify \
+// RUN:   -fmodules-cache-path=%tlocal.cache \
+// RUN:   -I%S/Inputs %s
+
+// Check that we don't serialize pragma pack state until/unless including an
+// empty file from the same module (but different submodule) has no effect.
+#pragma pack (show) // expected-warning {{value of #pragma pack(show) == 8}}
+#include "empty.h"
+#pragma pack (show) // expected-warning {{value of #pragma pack(show) == 8}}
diff --git a/test/Modules/rebuild.m b/test/Modules/rebuild.m
index 40f2d47..150c2ce 100644
--- a/test/Modules/rebuild.m
+++ b/test/Modules/rebuild.m
@@ -19,11 +19,10 @@
 // RUN: diff %t/Module.size %t/Module.size.saved
 // RUN: cp %t/Module.pcm %t/Module.pcm.saved.2
 
-// But the signature at least is expected to change, so we rebuild DependsOnModule.
-// NOTE: if we change how the signature is created, this test may need updating.
+// The signature is the hash of the PCM content, we will not rebuild rebuild DependsOnModule.
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -fsyntax-only -F %S/Inputs %s
 // RUN: diff %t/Module.pcm %t/Module.pcm.saved.2
-// RUN: not diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
+// RUN: diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
 
 // Rebuild Module, reset its timestamp, and verify its size hasn't changed
 // RUN: rm %t/Module.pcm
@@ -34,10 +33,9 @@
 // RUN: cp %t/Module.pcm %t/Module.pcm.saved.2
 
 // Verify again with Module pre-imported.
-// NOTE: if we change how the signature is created, this test may need updating.
 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fdisable-module-hash -fsyntax-only -F %S/Inputs %s
 // RUN: diff %t/Module.pcm %t/Module.pcm.saved.2
-// RUN: not diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
+// RUN: diff %t/DependsOnModule.pcm %t/DependsOnModule.pcm.saved
 
 #ifdef PREIMPORT
 @import Module;
diff --git a/test/Modules/redefinition-same-header.m b/test/Modules/redefinition-same-header.m
new file mode 100644
index 0000000..13b84be
--- /dev/null
+++ b/test/Modules/redefinition-same-header.m
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t.tmp
+// RUN: %clang_cc1 -fsyntax-only -I %S/Inputs/SameHeader -fmodules \
+// RUN:   -fimplicit-module-maps -fmodules-cache-path=%t.tmp %s -verify
+
+// expected-error@Inputs/SameHeader/C.h:3 {{redefinition of 'c'}}
+// expected-note-re@Inputs/SameHeader/B.h:3 {{'{{.*}}/C.h' included multiple times, additional include site in header from module 'X.B'}}
+// expected-note@Inputs/SameHeader/module.modulemap:6 {{X.B defined here}}
+// expected-note-re@redefinition-same-header.m:20 {{'{{.*}}/C.h' included multiple times, additional include site here}}
+
+// expected-error@Inputs/SameHeader/C.h:5 {{redefinition of 'aaa'}}
+// expected-note-re@Inputs/SameHeader/B.h:3 {{'{{.*}}/C.h' included multiple times, additional include site in header from module 'X.B'}}
+// expected-note@Inputs/SameHeader/module.modulemap:6 {{X.B defined here}}
+// expected-note-re@redefinition-same-header.m:20 {{'{{.*}}/C.h' included multiple times, additional include site here}}
+
+// expected-error@Inputs/SameHeader/C.h:9 {{redefinition of 'fd_set'}}
+// expected-note-re@Inputs/SameHeader/B.h:3 {{'{{.*}}/C.h' included multiple times, additional include site in header from module 'X.B'}}
+// expected-note@Inputs/SameHeader/module.modulemap:6 {{X.B defined here}}
+// expected-note-re@redefinition-same-header.m:20 {{'{{.*}}/C.h' included multiple times, additional include site here}}
+#include "A.h" // maps to a modular
+#include "C.h" // textual include
diff --git a/test/Modules/shadow.m b/test/Modules/shadow.m
new file mode 100644
index 0000000..44320af
--- /dev/null
+++ b/test/Modules/shadow.m
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/shadow/A1 -I %S/Inputs/shadow/A2 %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -fmodule-map-file=%S/Inputs/shadow/A2/module.modulemap %s -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION
+// REDEFINITION: error: redefinition of module 'A'
+// REDEFINITION: note: previously defined
+
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap -I %S/Inputs/shadow %s -verify
+
+@import A1;
+@import A2;
+@import A;
+
+#import "A2/A.h" // expected-note {{implicitly imported}}
+// expected-error@A2/module.modulemap:1 {{import of shadowed module 'A'}}
+// expected-note@A1/module.modulemap:1 {{previous definition}}
+
+#if defined(A2_A_h)
+#error got the wrong definition of module A
+#elif !defined(A1_A_h)
+#error missing definition from A1
+#endif
diff --git a/test/Modules/system-out-of-date-test.m b/test/Modules/system-out-of-date-test.m
new file mode 100644
index 0000000..e78df7b
--- /dev/null
+++ b/test/Modules/system-out-of-date-test.m
@@ -0,0 +1,17 @@
+// RUN: rm -rf %t.cache
+// RUN: echo '@import X;' | \
+// RUN:   %clang_cc1 -fmodules -fimplicit-module-maps \
+// RUN:     -fmodules-cache-path=%t.cache -I%S/Inputs/system-out-of-date \
+// RUN:     -fsyntax-only -x objective-c -
+//
+// Build something with different diagnostic options.
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps \
+// RUN:   -fmodules-cache-path=%t.cache -I%S/Inputs/system-out-of-date \
+// RUN:   -fsyntax-only %s -Wnon-modular-include-in-framework-module \
+// RUN:   -Werror=non-modular-include-in-framework-module 2>&1 \
+// RUN: | FileCheck %s
+@import X;
+
+#import <Z.h>
+// CHECK: While building module 'Z' imported from
+// CHECK: {{.*}}Y-{{.*}}pcm' was validated as a system module and is now being imported as a non-system module
diff --git a/test/Modules/warning-mismatch.m b/test/Modules/warning-mismatch.m
new file mode 100644
index 0000000..dd7c7f8
--- /dev/null
+++ b/test/Modules/warning-mismatch.m
@@ -0,0 +1,13 @@
+// RUN: rm -rf %t.cache
+// RUN: echo "@import Mismatch;" >%t.m
+// RUN: %clang_cc1 -Wno-system-headers -fdisable-module-hash \
+// RUN:   -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps \
+// RUN:   -I%S/Inputs/warning-mismatch %t.m -fsyntax-only
+// RUN: %clang_cc1 -Wsystem-headers -fdisable-module-hash \
+// RUN:   -fmodules-cache-path=%t.cache -fmodules -fimplicit-module-maps \
+// RUN:   -I%S/Inputs/warning-mismatch %s -fsyntax-only
+
+// This testcase triggers a warning flag mismatch in an already validated
+// header.
+@import Mismatch;
+@import System;
diff --git a/test/PCH/cxx-dependent-sized-ext-vector.cpp b/test/PCH/cxx-dependent-sized-ext-vector.cpp
new file mode 100644
index 0000000..29c06f7
--- /dev/null
+++ b/test/PCH/cxx-dependent-sized-ext-vector.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++11 -emit-pch %s -o %t
+// RUN: %clang_cc1 -std=c++11 -include-pch %t -verify %s
+
+#ifndef HEADER_INCLUDED
+
+#define HEADER_INCLUDED
+
+template<typename T, int N>
+using vec = T __attribute__((ext_vector_type(N)));
+
+#else
+
+void test() {
+  vec<float, 2> a;  // expected-error@-5 {{zero vector size}}
+  vec<float, 0> b; // expected-note {{in instantiation of template type alias 'vec' requested here}}
+}
+
+#endif
diff --git a/test/PCH/emit-dependencies.c b/test/PCH/emit-dependencies.c
new file mode 100644
index 0000000..c719b9e
--- /dev/null
+++ b/test/PCH/emit-dependencies.c
@@ -0,0 +1,9 @@
+// RUN: rm -f %t.pch
+// RUN: %clang_cc1 -emit-pch -o %t.pch %S/Inputs/chain-decls1.h
+// RUN: %clang_cc1 -include-pch %t.pch -fsyntax-only -MT %s.o -dependency-file - %s | FileCheck %s
+// CHECK: Inputs/chain-decls1.h
+
+int main() {
+  f();
+  return 0;
+}
diff --git a/test/PCH/pragma-pack.c b/test/PCH/pragma-pack.c
new file mode 100644
index 0000000..47a5570
--- /dev/null
+++ b/test/PCH/pragma-pack.c
@@ -0,0 +1,90 @@
+// Test this without pch.
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DSET
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DRESET
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DPUSH
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DPUSH_POP
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -include %s -verify -fsyntax-only -DPUSH_POP_LABEL
+
+// Test with pch.
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DSET -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DSET -verify -include-pch %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DRESET -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DRESET -verify -include-pch %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH -verify -include-pch %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP -verify -include-pch %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP_LABEL -emit-pch -o %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 %s -DPUSH_POP_LABEL -verify -include-pch %t
+
+#ifndef HEADER
+#define HEADER
+
+#ifdef SET
+#pragma pack(1)
+#endif
+
+#ifdef RESET
+#pragma pack(2)
+#pragma pack ()
+#endif
+
+#ifdef PUSH
+#pragma pack(1)
+#pragma pack (push, 2)
+#endif
+
+#ifdef PUSH_POP
+#pragma pack (push, 4)
+#pragma pack (push, 2)
+#pragma pack (pop)
+#endif
+
+#ifdef PUSH_POP_LABEL
+#pragma pack (push, a, 4)
+#pragma pack (push, b, 1)
+#pragma pack (push, c, 2)
+#pragma pack (pop, b)
+#endif
+
+#else
+
+#ifdef SET
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 1}}
+#pragma pack(pop) // expected-warning {{#pragma pack(pop, ...) failed: stack empty}}
+#endif
+
+#ifdef RESET
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 8}}
+#pragma ()
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 8}}
+#endif
+
+#ifdef PUSH
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 2}}
+#pragma pack(pop)
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 1}}
+#pragma pack ()
+#pragma pack (show) // expected-warning {{value of #pragma pack(show) == 8}}
+#pragma pack(pop) // expected-warning {{#pragma pack(pop, ...) failed: stack empty}}
+#endif
+
+#ifdef PUSH_POP
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 4}}
+#pragma pack(pop)
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 8}}
+#pragma pack(pop) // expected-warning {{#pragma pack(pop, ...) failed: stack empty}}
+#endif
+
+#ifdef PUSH_POP_LABEL
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 4}}
+#pragma pack(pop, c)
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 4}}
+#pragma pack(pop, a)
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 8}}
+#pragma pack(pop)  // expected-warning {{#pragma pack(pop, ...) failed: stack empty}}
+#pragma pack(pop, b) // expected-warning {{#pragma pack(pop, ...) failed: stack empty}}
+#pragma pack(show) // expected-warning {{value of #pragma pack(show) == 8}}
+#endif
+
+#endif
diff --git a/test/Parser/attr-external-source-symbol-cxx11.cpp b/test/Parser/attr-external-source-symbol-cxx11.cpp
new file mode 100644
index 0000000..3457c6a
--- /dev/null
+++ b/test/Parser/attr-external-source-symbol-cxx11.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// expected-no-diagnostics
+
+[[clang::external_source_symbol(language="Swift", defined_in="module")]]
+void function() { }
diff --git a/test/Parser/attr-external-source-symbol.m b/test/Parser/attr-external-source-symbol.m
new file mode 100644
index 0000000..772fde0
--- /dev/null
+++ b/test/Parser/attr-external-source-symbol.m
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void function() __attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration)));
+
+__attribute__((external_source_symbol(language="Swift", defined_in="module")))
+@interface I
+
+- (void)method __attribute__((external_source_symbol(defined_in= "module")));
+
+@end
+
+enum E {
+  CaseA __attribute__((external_source_symbol(generated_declaration))),
+  CaseB __attribute__((external_source_symbol(generated_declaration, language="Swift")))
+} __attribute__((external_source_symbol(language = "Swift")));
+
+void f2()
+__attribute__((external_source_symbol())); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+void f3()
+__attribute__((external_source_symbol(invalid))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+void f4()
+__attribute__((external_source_symbol(language))); // expected-error {{expected '=' after language}}
+void f5()
+__attribute__((external_source_symbol(language=))); // expected-error {{expected string literal for language name in 'external_source_symbol' attribute}}
+void f6()
+__attribute__((external_source_symbol(defined_in=20))); // expected-error {{expected string literal for source container name in 'external_source_symbol' attribute}}
+
+void f7()
+__attribute__((external_source_symbol(generated_declaration, generated_declaration))); // expected-error {{duplicate 'generated_declaration' clause in an 'external_source_symbol' attribute}}
+void f8()
+__attribute__((external_source_symbol(language="Swift", language="Swift"))); // expected-error {{duplicate 'language' clause in an 'external_source_symbol' attribute}}
+void f9()
+__attribute__((external_source_symbol(defined_in="module", language="Swift", defined_in="foo"))); // expected-error {{duplicate 'defined_in' clause in an 'external_source_symbol' attribute}}
+
+void f10()
+__attribute__((external_source_symbol(generated_declaration, language="Swift", defined_in="foo", generated_declaration, generated_declaration, language="Swift"))); // expected-error {{duplicate 'generated_declaration' clause in an 'external_source_symbol' attribute}}
+
+void f11()
+__attribute__((external_source_symbol(language="Objective-C++", defined_in="Some file with spaces")));
+
+void f12()
+__attribute__((external_source_symbol(language="C Sharp", defined_in="file:////Hello world with spaces. cs")));
+
+void f13()
+__attribute__((external_source_symbol(language=Swift))); // expected-error {{expected string literal for language name in 'external_source_symbol' attribute}}
+
+void f14()
+__attribute__((external_source_symbol(=))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+
+void f15()
+__attribute__((external_source_symbol(="Swift"))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+
+void f16()
+__attribute__((external_source_symbol("Swift", "module", generated_declaration))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+
+void f17()
+__attribute__((external_source_symbol(language="Swift", "generated_declaration"))); // expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
+
+void f18()
+__attribute__((external_source_symbol(language= =))); // expected-error {{expected string literal for language name in 'external_source_symbol' attribute}}
+
+void f19()
+__attribute__((external_source_symbol(defined_in="module" language="swift"))); // expected-error {{expected ')'}} expected-note {{to match this '('}}
+
+void f20()
+__attribute__((external_source_symbol(defined_in="module" language="swift" generated_declaration))); // expected-error {{expected ')'}} expected-note {{to match this '('}}
+
+void f21()
+__attribute__((external_source_symbol(defined_in= language="swift"))); // expected-error {{expected string literal for source container name in 'external_source_symbol' attribute}}
+
+void f22()
+__attribute__((external_source_symbol)); // expected-error {{'external_source_symbol' attribute takes at least 1 argument}}
+
+void f23()
+__attribute__((external_source_symbol(defined_in=, language="swift" generated_declaration))); // expected-error {{expected string literal for source container name in 'external_source_symbol' attribute}} expected-error{{expected ')'}} expected-note{{to match this '('}}
+
+void f24()
+__attribute__((external_source_symbol(language = generated_declaration))); // expected-error {{expected string literal for language name in 'external_source_symbol' attribute}}
+
+void f25()
+__attribute__((external_source_symbol(defined_in=123, defined_in="module"))); // expected-error {{expected string literal for source container name in 'external_source_symbol'}} expected-error {{duplicate 'defined_in' clause in an 'external_source_symbol' attribute}}
+
+void f26()
+__attribute__((external_source_symbol(language=Swift, language="Swift", error))); // expected-error {{expected string literal for language name in 'external_source_symbol'}} expected-error {{duplicate 'language' clause in an 'external_source_symbol' attribute}} expected-error {{expected 'language', 'defined_in', or 'generated_declaration'}}
diff --git a/test/Parser/cxx11-stmt-attributes.cpp b/test/Parser/cxx11-stmt-attributes.cpp
index 9374b58..75fb37e 100644
--- a/test/Parser/cxx11-stmt-attributes.cpp
+++ b/test/Parser/cxx11-stmt-attributes.cpp
@@ -80,5 +80,6 @@
   {
     [[ ]] // expected-error {{an attribute list cannot appear here}}
 #pragma STDC FP_CONTRACT ON // expected-error {{can only appear at file scope or at the start of a compound statement}}
+#pragma clang fp contract(fast) // expected-error {{can only appear at file scope or at the start of a compound statement}}
   }
 }
diff --git a/test/Parser/editor-placeholder-recovery.cpp b/test/Parser/editor-placeholder-recovery.cpp
new file mode 100644
index 0000000..48c290e
--- /dev/null
+++ b/test/Parser/editor-placeholder-recovery.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -fallow-editor-placeholders -DSUPPRESS -verify %s
+
+struct Struct {
+public:
+    void method(Struct &x);
+};
+
+struct <#struct name#> {
+  int <#field-name#>;
+#ifndef SUPPRESS
+  // expected-error@-3 {{editor placeholder in source file}}
+  // expected-error@-3 {{editor placeholder in source file}}
+#endif
+};
+
+typename <#typename#>::<#name#>;
+decltype(<#expression#>) foobar;
+typedef <#type#> <#name#>;
+#ifndef SUPPRESS
+  // expected-error@-4 2 {{editor placeholder in source file}}
+  // expected-error@-4 {{editor placeholder in source file}}
+  // expected-error@-4 2 {{editor placeholder in source file}}
+#endif
+
+namespace <#identifier#> {
+  <#declarations#>
+#ifndef SUPPRESS
+  // expected-error@-3 {{editor placeholder in source file}}
+  // expected-error@-3 {{editor placeholder in source file}}
+#endif
+
+}
+
+using <#qualifier#>::<#name#>;
+#ifndef SUPPRESS
+  // expected-error@-2 2 {{editor placeholder in source file}}
+#endif
+
+void avoidPlaceholderErrors(Struct &obj) {
+    static_cast< <#type#> >(<#expression#>);
+    while (<#condition#>) {
+        <#statements#>
+    }
+    obj.method(<#Struct &x#>);
+#ifndef SUPPRESS
+  // expected-error@-6 2 {{editor placeholder in source file}}
+  // expected-error@-6 {{editor placeholder in source file}}
+  // expected-error@-6 {{editor placeholder in source file}}
+  // expected-error@-5 {{editor placeholder in source file}}
+#endif
+    switch (<#expression#>) {
+        case <#constant#>:
+            <#statements#>
+#ifndef SUPPRESS
+  // expected-error@-4 {{editor placeholder in source file}}
+  // expected-error@-4 {{editor placeholder in source file}}
+  // expected-error@-4 {{editor placeholder in source file}}
+#endif
+            break;
+
+        default:
+            break;
+    }
+}
+
+void Struct::method(<#Struct &x#>, noSupressionHere) { // expected-error {{unknown type name 'noSupressionHere'}} expected-error {{C++ requires a type specifier for all declarations}}
+#ifndef SUPPRESS
+  // expected-error@-2 {{editor placeholder in source file}}
+#endif
+}
diff --git a/test/Parser/objc-available.m b/test/Parser/objc-available.m
index d18ac1f..01d59f8 100644
--- a/test/Parser/objc-available.m
+++ b/test/Parser/objc-available.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wunguarded-availability -triple x86_64-apple-macosx10.10.0 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -Wunguarded-availability -Wno-unsupported-availability-guard -triple x86_64-apple-macosx10.10.0 -verify %s
 
 void f() {
 
@@ -20,3 +20,14 @@
   (void)@available(macos); // expected-error{{expected a version}}
   (void)@available; // expected-error{{expected '('}}
 }
+
+void prettyPlatformNames() {
+  (void)@available(iOS 8, tvOS 10, watchOS 3, macOS 10.11, *);
+  (void)__builtin_available(iOSApplicationExtension 8, tvOSApplicationExtension 10,
+                   watchOSApplicationExtension 3, macOSApplicationExtension 10.11, *);
+}
+
+#if __has_builtin(__builtin_available)
+#error expected
+// expected-error@-1 {{expected}}
+#endif
diff --git a/test/Parser/objc-cxx-keyword-identifiers.mm b/test/Parser/objc-cxx-keyword-identifiers.mm
new file mode 100644
index 0000000..6791f0d
--- /dev/null
+++ b/test/Parser/objc-cxx-keyword-identifiers.mm
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wno-objc-root-class -Wno-incomplete-implementation -triple x86_64-apple-macosx10.10.0 -verify %s
+
+// rdar://20626062
+
+struct S {
+  int throw; // expected-error {{expected member name or ';' after declaration specifiers; 'throw' is a keyword in Objective-C++}}
+};
+
+@interface class // expected-error {{expected identifier; 'class' is a keyword in Objective-C++}}
+@end
+
+@interface Bar: class // expected-error {{expected identifier; 'class' is a keyword in Objective-C++}}
+@end
+
+@protocol P // ok
+@end
+
+@protocol new // expected-error {{expected identifier; 'new' is a keyword in Objective-C++}}
+@end
+
+@protocol P2, delete; // expected-error {{expected identifier; 'delete' is a keyword in Objective-C++}}
+
+@class Foo, try; // expected-error {{expected identifier; 'try' is a keyword in Objective-C++}}
+
+@interface Foo
+
+@property (readwrite, nonatomic) int a, b, throw; // expected-error {{expected member name or ';' after declaration specifiers; 'throw' is a keyword in Objective-C++}}
+
+-foo:(int)class; // expected-error {{expected identifier; 'class' is a keyword in Objective-C++}}
++foo:(int)constexpr; // expected-error {{expected identifier; 'constexpr' is a keyword in Objective-C++}}
+
+@end
+
+@interface Foo () <P, new> // expected-error {{expected identifier; 'new' is a keyword in Objective-C++}}
+@end
+
+@implementation Foo
+
+@synthesize a = _a; // ok
+@synthesize b = virtual; // expected-error {{expected identifier; 'virtual' is a keyword in Objective-C++}}
+
+@dynamic throw; // expected-error {{expected identifier; 'throw' is a keyword in Objective-C++}}
+
+-foo:(int)class { // expected-error {{expected identifier; 'class' is a keyword in Objective-C++}}
+}
+
+@end
+
+@implementation class // expected-error {{expected identifier; 'class' is a keyword in Objective-C++}}
+@end
+
+@implementation Bar: class // expected-error {{expected identifier; 'class' is a keyword in Objective-C++}}
+@end
+
+@compatibility_alias C Foo; // ok
+@compatibility_alias const_cast Bar; // expected-error {{expected identifier; 'const_cast' is a keyword in Objective-C++}}
+@compatibility_alias C2 class; // expected-error {{expected identifier; 'class' is a keyword in Objective-C++}}
+
+void func() {
+  (void)@protocol(P); // ok
+  (void)@protocol(delete); // expected-error {{expected identifier; 'delete' is a keyword in Objective-C++}}
+}
diff --git a/test/Parser/placeholder-recovery.m b/test/Parser/placeholder-recovery.m
index b43b0e4..4f22ea7 100644
--- a/test/Parser/placeholder-recovery.m
+++ b/test/Parser/placeholder-recovery.m
@@ -1,11 +1,14 @@
 // RUN: %clang_cc1 -fsyntax-only -verify %s
 
+@protocol NSObject
+@end
+
+@protocol <#protocol name#> <NSObject> // expected-error {{editor placeholder in source file}}
+// expected-note@-1 {{protocol started here}}
+
 // FIXME: We could do much better with this, if we recognized
 // placeholders somehow. However, we're content with not generating
 // bogus 'archaic' warnings with bad location info.
-@protocol <#protocol name#> <NSObject> // expected-error {{expected identifier or '('}} \
-// expected-error 2{{expected identifier}} \
-// expected-warning{{protocol has no object type specified; defaults to qualified 'id'}}
-<#methods#>
+<#methods#> // expected-error {{editor placeholder in source file}}
 
-@end
+@end // expected-error {{prefix attribute must be followed by an interface or protocol}} expected-error {{missing '@end'}}
diff --git a/test/Parser/pragma-attribute-declspec.cpp b/test/Parser/pragma-attribute-declspec.cpp
new file mode 100644
index 0000000..28785ba
--- /dev/null
+++ b/test/Parser/pragma-attribute-declspec.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i386-pc-win32 -std=c++11  -verify -Wno-pragma-clang-attribute -fms-extensions -fms-compatibility %s
+
+#pragma clang attribute push(__declspec(dllexport), apply_to = function)
+
+void function();
+
+#pragma clang attribute pop
+
+#pragma clang attribute push(__declspec(dllexport, dllimport), apply_to = function) // expected-error {{more than one attribute specified in '#pragma clang attribute push'}}
+
+#pragma clang attribute push(__declspec(align), apply_to = variable) // expected-error {{attribute 'align' is not supported by '#pragma clang attribute'}}
+
+#pragma clang attribute push(__declspec(), apply_to = variable) // A noop
diff --git a/test/Parser/pragma-attribute.cpp b/test/Parser/pragma-attribute.cpp
new file mode 100644
index 0000000..f0ebca2
--- /dev/null
+++ b/test/Parser/pragma-attribute.cpp
@@ -0,0 +1,181 @@
+// RUN: %clang_cc1 -Wno-pragma-clang-attribute -verify -std=c++11 %s
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = function)
+
+void function();
+
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(variable(is_parameter), function))
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = variable(unless(is_parameter)))
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(variable(unless(is_parameter))))
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a")))) // expected-error {{expected ','}}
+#pragma clang attribute push (__attribute__((abi_tag("a"))) apply_to=function) // expected-error {{expected ','}}
+#pragma clang attribute push (__attribute__((abi_tag("a"))) = function) // expected-error {{expected ','}}
+#pragma clang attribute push (__attribute__((abi_tag("a"))) any(function)) // expected-error {{expected ','}}
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))) 22) // expected-error {{expected ','}}
+#pragma clang attribute push (__attribute__((abi_tag("a"))) function) // expected-error {{expected ','}}
+#pragma clang attribute push (__attribute__((abi_tag("a"))) (function)) // expected-error {{expected ','}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), ) // expected-error {{expected attribute subject set specifier 'apply_to'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), = any(function)) // expected-error {{expected attribute subject set specifier 'apply_to'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), = function) // expected-error {{expected attribute subject set specifier 'apply_to'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), any(function)) // expected-error {{expected attribute subject set specifier 'apply_to'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), function) // expected-error {{expected attribute subject set specifier 'apply_to'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply = any(function )) // expected-error {{expected attribute subject set specifier 'apply_to'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), to = function) // expected-error {{expected attribute subject set specifier 'apply_to'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_only_to = function) // expected-error {{expected attribute subject set specifier 'apply_to'}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to any(function)) // expected-error {{expected '='}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to function) // expected-error {{expected '='}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to) // expected-error {{expected '='}}
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to 41 (22)) // expected-error {{expected '='}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any) // expected-error {{expected '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any {) // expected-error {{expected '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any function) // expected-error {{expected '('}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = { function, enum }) // expected-error {{expected an identifier that corresponds to an attribute subject rule}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(function ) // expected-error {{expected ')'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(function, )) // expected-error {{expected an identifier that corresponds to an attribute subject rule}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, enum ) // expected-error {{expected ')'}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = () ) // expected-error {{expected an identifier that corresponds to an attribute subject rule}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( + ) ) // expected-error {{expected an identifier that corresponds to an attribute subject rule}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any()) // expected-error {{expected an identifier that corresponds to an attribute subject rule}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, 42 )) // expected-error {{expected an identifier that corresponds to an attribute subject rule}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( diag )) // expected-error {{unknown attribute subject rule 'diag'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( a )) // expected-error {{unknown attribute subject rule 'a'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, for)) // expected-error {{unknown attribute subject rule 'for'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function42, for )) // expected-error {{unknown attribute subject rule 'function42'}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(hasType)) // expected-error {{expected '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = hasType) // expected-error {{expected '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = hasType(functionType)) // OK
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable( )) // expected-error {{expected ')'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable( ) )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(is ) )) // expected-error {{unknown attribute subject matcher sub-rule 'is'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(is_parameter, not) )) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable is_parameter )) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable ( ) // expected-error {{expected ')'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = variable (  // expected-error {{expected ')'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable (is ()) )) // expected-error {{unknown attribute subject matcher sub-rule 'is'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable (42) )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, namespace("test") )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'namespace' matcher does not support sub-rules}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable ("test" )) // expected-error {{expected ')'}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = enum(is_parameter)) // expected-error {{invalid use of attribute subject matcher sub-rule 'is_parameter'; 'enum' matcher does not support sub-rules}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any(enum(is_parameter))) // expected-error {{invalid use of attribute subject matcher sub-rule 'is_parameter'; 'enum' matcher does not support sub-rules}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any (function, variable (unless) )) // expected-error {{expected '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any (function, variable (unless() )) // expected-error {{expected ')'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any ( function, variable (unless(is)) )) // expected-error {{unknown attribute subject matcher sub-rule 'unless(is)'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless(is_parameter, not)) )) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless(is_parameter), not) ) // expected-error {{expected ')'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable unless is_parameter )) // expected-error {{expected ')'}} expected-note {{to match this '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless is_parameter) )) // expected-error {{expected '('}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable (unless(42)) )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, enum(unless("test")) )) // expected-error {{expected an identifier that corresponds to an attribute subject matcher sub-rule; 'enum' matcher does not support sub-rules}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, variable (unless(is_global)) )) // expected-error {{unknown attribute subject matcher sub-rule 'unless(is_global)'; 'variable' matcher supports the following sub-rules: 'is_thread_local', 'is_global', 'is_parameter', 'unless(is_parameter)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( enum(unless(is_parameter)) )) // expected-error {{invalid use of attribute subject matcher sub-rule 'unless(is_parameter)'; 'enum' matcher does not support sub-rules}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, function )) // expected-error {{duplicate attribute subject matcher 'function'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, function, function )) // expected-error 2 {{duplicate attribute subject matcher 'function'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( function, enum, function )) // expected-error {{duplicate attribute subject matcher 'function'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( enum, enum, function )) // expected-error {{duplicate attribute subject matcher 'enum'}}
+
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(is_global), variable(is_global) )) // expected-error {{duplicate attribute subject matcher 'variable(is_global)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(is_global), function, variable(is_global), variable(is_global) )) // expected-error 2 {{duplicate attribute subject matcher 'variable(is_global)'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless(is_parameter)), variable(unless(is_parameter)) )) // expected-error {{duplicate attribute subject matcher 'variable(unless(is_parameter))'}}
+#pragma clang attribute push(__attribute__((annotate("test"))), apply_to = any( variable(unless(is_parameter)), variable(unless(is_parameter)), enum, variable(unless(is_parameter)) )) // expected-error 2 {{duplicate attribute subject matcher 'variable(unless(is_parameter))'}}
+
+#pragma clang attribute // expected-error {{expected 'push' or 'pop' after '#pragma clang attribute'}}
+#pragma clang attribute 42 // expected-error {{expected 'push' or 'pop' after '#pragma clang attribute'}}
+#pragma clang attribute pushpop // expected-error {{unexpected argument 'pushpop' to '#pragma clang attribute'; expected 'push' or 'pop'}}
+
+#pragma clang attribute push // expected-error {{expected '('}}
+#pragma clang attribute push ( // expected-error {{expected an attribute after '('}}
+#pragma clang attribute push (__attribute__((annotate)) // expected-error {{expected ')'}}
+#pragma clang attribute push () // expected-error {{expected an attribute after '('}}
+
+#pragma clang attribute push (__attribute__((annotate("test"))), apply_to = function) () // expected-warning {{extra tokens at end of '#pragma clang attribute'}}
+// expected-error@-1 {{expected unqualified-id}}
+// expected-error@-2 {{unterminated '#pragma clang attribute push' at end of file}}
+
+#pragma clang attribute pop () // expected-warning {{extra tokens at end of '#pragma clang attribute'}}
+
+;
+
+#pragma clang attribute push (__attribute__((42))) // expected-error {{expected identifier that represents an attribute name}}
+
+#pragma clang attribute push (__attribute__((annotate)) foo) // expected-error {{expected ','}}
+#pragma clang attribute push (__attribute__((annotate)), apply_to=function foo) // expected-error {{extra tokens after attribute in a '#pragma clang attribute push'}}
+
+#pragma clang attribute push (__attribute__((objc_bridge_related)), apply_to=function)
+// expected-error@-1 {{attribute 'objc_bridge_related' is not supported by '#pragma clang attribute'}}
+#pragma clang attribute push (__attribute__((objc_bridge_related(1))), apply_to=function) // expected-error {{expected a related ObjectiveC class name, e.g., 'NSColor'}}
+
+#pragma clang attribute push (__attribute__((used)), apply_to=function) // expected-error {{attribute 'used' is not supported by '#pragma clang attribute'}}
+
+void statementPragmasAndPragmaExpression() {
+#pragma clang attribute push (__attribute__((annotate("hello"))), apply_to=variable)
+#pragma clang attribute pop
+int x = 0;
+_Pragma("clang attribute push (__attribute__((annotate(\"hi\"))), apply_to = function)");
+
+_Pragma("clang attribute push (__attribute__((annotate(\"hi\"))), apply_to = any(function(is_method ))"); // expected-error {{expected ')'}}
+}
+
+_Pragma("clang attribute pop");
+
+#pragma clang attribute push (__attribute__((address_space(0))), apply_to=variable) // expected-error {{attribute 'address_space' is not supported by '#pragma clang attribute'}}
+
+// Check support for CXX11 style attributes
+#pragma clang attribute push ([[noreturn]], apply_to = any(function))
+#pragma clang attribute pop
+
+#pragma clang attribute push ([[clang::disable_tail_calls]], apply_to = function)
+#pragma clang attribute pop
+
+#pragma clang attribute push ([[gnu::abi_tag]], apply_to=any(function))
+#pragma clang attribute pop
+
+#pragma clang attribute push ([[clang::disable_tail_calls, noreturn]], apply_to = function) // expected-error {{more than one attribute specified in '#pragma clang attribute push'}}
+#pragma clang attribute push ([[clang::disable_tail_calls, noreturn]]) // expected-error {{more than one attribute specified in '#pragma clang attribute push'}}
+
+#pragma clang attribute push ([[gnu::abi_tag]], apply_to=namespace)
+#pragma clang attribute pop
+
+#pragma clang attribute push ([[fallthrough]], apply_to=function) // expected-error {{attribute 'fallthrough' is not supported by '#pragma clang attribute'}}
+#pragma clang attribute push ([[clang::fallthrough]], apply_to=function) // expected-error {{attribute 'fallthrough' is not supported by '#pragma clang attribute'}}
+
+#pragma clang attribute push ([[]], apply_to = function) // A noop
+
+#pragma clang attribute push ([[noreturn ""]], apply_to=function) // expected-error {{expected ']'}}
+#pragma clang attribute pop
+#pragma clang attribute push ([[noreturn 42]]) // expected-error {{expected ']'}} expected-error {{expected ','}}
+
+#pragma clang attribute push(__attribute__, apply_to=function) // expected-error {{expected '(' after 'attribute'}}
+#pragma clang attribute push(__attribute__(), apply_to=function) // expected-error {{expected '(' after '('}}
+#pragma clang attribute push(__attribute__(()), apply_to=function) // expected-error {{expected identifier that represents an attribute name}}
+#pragma clang attribute push(__attribute__((annotate, apply_to=function))) // expected-error {{expected ')'}}
+#pragma clang attribute push(__attribute__((annotate("test"), apply_to=function))) // expected-error {{expected ')'}}
+#pragma clang attribute push(__attribute__((annotate), apply_to=function)) // expected-error {{expected ')'}}
+
+#pragma clang attribute push (42) // expected-error {{expected an attribute that is specified using the GNU, C++11 or '__declspec' syntax}}
+#pragma clang attribute push (test) // expected-error {{expected an attribute that is specified using the GNU, C++11 or '__declspec' syntax}}
+#pragma clang attribute push (annotate) // expected-error {{expected an attribute that is specified using the GNU, C++11 or '__declspec' syntax}}
+// expected-note@-1 {{use the GNU '__attribute__' syntax}}
+#pragma clang attribute push (annotate("test")) // expected-error {{expected an attribute that is specified using the GNU, C++11 or '__declspec' syntax}}
+// expected-note@-1 {{use the GNU '__attribute__' syntax}}
diff --git a/test/Parser/pragma-fp.cpp b/test/Parser/pragma-fp.cpp
new file mode 100644
index 0000000..00547bf
--- /dev/null
+++ b/test/Parser/pragma-fp.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+void test_0(int *List, int Length) {
+/* expected-error@+1 {{missing option; expected contract}} */
+#pragma clang fp
+  for (int i = 0; i < Length; i++) {
+    List[i] = i;
+  }
+}
+void test_1(int *List, int Length) {
+/* expected-error@+1 {{invalid option 'blah'; expected contract}} */
+#pragma clang fp blah
+  for (int i = 0; i < Length; i++) {
+    List[i] = i;
+  }
+}
+
+void test_3(int *List, int Length) {
+/* expected-error@+1 {{expected '('}} */
+#pragma clang fp contract on
+  for (int i = 0; i < Length; i++) {
+    List[i] = i;
+  }
+}
+
+void test_4(int *List, int Length) {
+/* expected-error@+1 {{unexpected argument 'while' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+#pragma clang fp contract(while)
+  for (int i = 0; i < Length; i++) {
+    List[i] = i;
+  }
+}
+
+void test_5(int *List, int Length) {
+/* expected-error@+1 {{unexpected argument 'maybe' to '#pragma clang fp contract'; expected 'on', 'fast' or 'off'}} */
+#pragma clang fp contract(maybe)
+  for (int i = 0; i < Length; i++) {
+    List[i] = i;
+  }
+}
+
+void test_6(int *List, int Length) {
+/* expected-error@+1 {{expected ')'}} */
+#pragma clang fp contract(fast
+  for (int i = 0; i < Length; i++) {
+    List[i] = i;
+  }
+}
+
+void test_7(int *List, int Length) {
+/* expected-warning@+1 {{extra tokens at end of '#pragma clang fp' - ignored}} */
+#pragma clang fp contract(fast) *
+  for (int i = 0; i < Length; i++) {
+    List[i] = i;
+  }
+}
+
+void test_8(int *List, int Length) {
+  for (int i = 0; i < Length; i++) {
+    List[i] = i;
+/* expected-error@+1 {{'#pragma clang fp' can only appear at file scope or at the start of a compound statement}} */
+#pragma clang fp contract(fast)
+  }
+}
diff --git a/test/Preprocessor/Inputs/nonportable-hmaps/foo.hmap b/test/Preprocessor/Inputs/nonportable-hmaps/foo.hmap
new file mode 100644
index 0000000..9036f20
--- /dev/null
+++ b/test/Preprocessor/Inputs/nonportable-hmaps/foo.hmap
Binary files differ
diff --git a/test/Preprocessor/Inputs/nonportable-hmaps/headers/foo/Foo.h b/test/Preprocessor/Inputs/nonportable-hmaps/headers/foo/Foo.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Preprocessor/Inputs/nonportable-hmaps/headers/foo/Foo.h
diff --git a/test/Preprocessor/expr_define_expansion.c b/test/Preprocessor/expr_define_expansion.c
index 23cb435..3e5a2c4 100644
--- a/test/Preprocessor/expr_define_expansion.c
+++ b/test/Preprocessor/expr_define_expansion.c
@@ -1,28 +1,6 @@
-// RUN: %clang_cc1 %s -E -CC -verify
-// RUN: %clang_cc1 %s -E -CC -DPEDANTIC -pedantic -verify
+// RUN: %clang_cc1 %s -E -CC -pedantic -verify
+// expected-no-diagnostics
 
 #define FOO && 1
 #if defined FOO FOO
 #endif
-
-#define A
-#define B defined(A)
-#if B // expected-warning{{macro expansion producing 'defined' has undefined behavior}}
-#endif
-
-#define m_foo
-#define TEST(a) (defined(m_##a) && a)
-
-#if defined(PEDANTIC)
-// expected-warning@+4{{macro expansion producing 'defined' has undefined behavior}}
-#endif
-
-// This shouldn't warn by default, only with pedantic:
-#if TEST(foo)
-#endif
-
-
-// Only one diagnostic for this case:
-#define INVALID defined(
-#if INVALID // expected-error{{macro name missing}}
-#endif
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index df7a8a8..0a81828 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -8900,6 +8900,7 @@
 // WEBASSEMBLY32-NEXT:#define __LONG_MAX__ 2147483647L
 // WEBASSEMBLY32-NOT:#define __LP64__
 // WEBASSEMBLY32-NEXT:#define __NO_INLINE__ 1
+// WEBASSEMBLY32-NEXT:#define __OBJC_BOOL_IS_BOOL 0
 // WEBASSEMBLY32-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
 // WEBASSEMBLY32-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
 // WEBASSEMBLY32-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
@@ -9215,6 +9216,7 @@
 // WEBASSEMBLY64-NEXT:#define __LONG_MAX__ 9223372036854775807L
 // WEBASSEMBLY64-NEXT:#define __LP64__ 1
 // WEBASSEMBLY64-NEXT:#define __NO_INLINE__ 1
+// WEBASSEMBLY64-NEXT:#define __OBJC_BOOL_IS_BOOL 0
 // WEBASSEMBLY64-NEXT:#define __ORDER_BIG_ENDIAN__ 4321
 // WEBASSEMBLY64-NEXT:#define __ORDER_LITTLE_ENDIAN__ 1234
 // WEBASSEMBLY64-NEXT:#define __ORDER_PDP_ENDIAN__ 3412
@@ -9555,3 +9557,12 @@
 // AVR:#define __WCHAR_MAX__ 32767
 // AVR:#define __WCHAR_TYPE__ int
 // AVR:#define __WINT_TYPE__ int
+
+// RUN: %clang_cc1 -E -dM -ffreestanding                \
+// RUN:   -triple=aarch64-apple-ios9 < /dev/null        \
+// RUN: | FileCheck -check-prefix=DARWIN %s
+// RUN: %clang_cc1 -E -dM -ffreestanding                \
+// RUN:   -triple=aarch64-apple-macosx10.12 < /dev/null \
+// RUN: | FileCheck -check-prefix=DARWIN %s
+
+// DARWIN:#define __STDC_NO_THREADS__ 1
diff --git a/test/Preprocessor/nonportable-include-with-hmap.c b/test/Preprocessor/nonportable-include-with-hmap.c
new file mode 100644
index 0000000..fc958e7
--- /dev/null
+++ b/test/Preprocessor/nonportable-include-with-hmap.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -Eonly                        \
+// RUN:   -I%S/Inputs/nonportable-hmaps/foo.hmap \
+// RUN:   -I%S/Inputs/nonportable-hmaps          \
+// RUN:   %s -verify
+//
+// foo.hmap contains: Foo/Foo.h -> headers/foo/Foo.h
+//
+// Header search of "Foo/Foo.h" follows this path:
+//  1. Look for "Foo/Foo.h".
+//  2. Find "Foo/Foo.h" in "nonportable-hmaps/foo.hmap".
+//  3. Look for "headers/foo/Foo.h".
+//  4. Find "headers/foo/Foo.h" in "nonportable-hmaps".
+//  5. Return.
+//
+// There is nothing nonportable; -Wnonportable-include-path should not fire.
+#include "Foo/Foo.h" // expected-no-diagnostics
diff --git a/test/Preprocessor/pragma_diagnostic.c b/test/Preprocessor/pragma_diagnostic.c
index 3970dbb..63d5907 100644
--- a/test/Preprocessor/pragma_diagnostic.c
+++ b/test/Preprocessor/pragma_diagnostic.c
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wno-undef %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-undef -Wno-unknown-warning-option -DAVOID_UNKNOWN_WARNING %s
 // rdar://2362963
 
 #if FOO    // ok.
@@ -28,8 +29,10 @@
 #pragma GCC diagnostic error "-Wundef" 42  // expected-warning {{unexpected token in pragma diagnostic}}
 #pragma GCC diagnostic error "invalid-name"  // expected-warning {{pragma diagnostic expected option name (e.g. "-Wundef")}}
 
-#pragma GCC diagnostic error "-Winvalid-name"  // expected-warning {{unknown warning group '-Winvalid-name', ignored}}
-
+#pragma GCC diagnostic error "-Winvalid-name"
+#ifndef AVOID_UNKNOWN_WARNING
+// expected-warning@-2 {{unknown warning group '-Winvalid-name', ignored}}
+#endif
 
 // Testing pragma clang diagnostic with -Weverything
 void ppo(){} // First test that we do not diagnose on this.
diff --git a/test/Profile/Inputs/cxx-class.proftext b/test/Profile/Inputs/cxx-class.proftext
index b4645ed..77645fb 100644
--- a/test/Profile/Inputs/cxx-class.proftext
+++ b/test/Profile/Inputs/cxx-class.proftext
@@ -39,3 +39,14 @@
 100
 99
 
+_ZN7DerivedC1Ev
+10
+2
+100
+99
+
+_ZN7DerivedD2Ev
+10
+2
+100
+99
diff --git a/test/Profile/c-generate.c b/test/Profile/c-generate.c
index 5e5b22e..1e7a739 100644
--- a/test/Profile/c-generate.c
+++ b/test/Profile/c-generate.c
@@ -5,7 +5,8 @@
 //
 // PROF-INSTR-PATH: constant [24 x i8] c"c-generate-test.profraw\00"
 //
-// PROF-INSTR-NONE-NOT: @__profn_main
+// PROF-INSTR-NONE-NOT: __llvm_prf
+//
 // PROF-INSTR-GARBAGE: invalid PGO instrumentor in argument '-fprofile-instrument=garbage'
 
 int main(void) {
diff --git a/test/Profile/c-outdated-data.c b/test/Profile/c-outdated-data.c
index e61ad02..b686f94 100644
--- a/test/Profile/c-outdated-data.c
+++ b/test/Profile/c-outdated-data.c
@@ -4,23 +4,23 @@
 // doesn't play well with warnings that have no line number.
 
 // RUN: llvm-profdata merge %S/Inputs/c-outdated-data.proftext -o %t.profdata
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-outdated-data.c %s -o /dev/null -emit-llvm -fprofile-instrument-use-path=%t.profdata -Wprofile-instr-dropped 2>&1 | FileCheck %s
-// CHECK: warning: profile data may be out of date: of 3 functions, 1 has no data and 1 has mismatched data that will be ignored
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-outdated-data.c %s -o /dev/null -emit-llvm -fprofile-instrument-use-path=%t.profdata 2>&1 | FileCheck %s -check-prefix=NO_MISSING
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-outdated-data.c %s -o /dev/null -emit-llvm -Wprofile-instr-missing -fprofile-instrument-use-path=%t.profdata 2>&1 | FileCheck %s -check-prefix=WITH_MISSING
+
+// NO_MISSING: warning: profile data may be out of date: of 3 functions, 1 has mismatched data that will be ignored
+// NO_MISSING-NOT: 1 has no data
+
+// WITH_MISSING: warning: profile data may be out of date: of 3 functions, 1 has mismatched data that will be ignored
+// WITH_MISSING: warning: profile data may be incomplete: of 3 functions, 1 has no data
 
 void no_usable_data() {
   int i = 0;
 
   if (i) {}
-
-#ifdef GENERATE_OUTDATED_DATA
-  if (i) {}
-#endif
 }
 
-#ifndef GENERATE_OUTDATED_DATA
 void no_data() {
 }
-#endif
 
 int main(int argc, const char *argv[]) {
   no_usable_data();
diff --git a/test/Profile/c-ternary.c b/test/Profile/c-ternary.c
new file mode 100644
index 0000000..af7922f
--- /dev/null
+++ b/test/Profile/c-ternary.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11.0 -x c %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck %s
+
+// PR32019: Clang can lower some ternary operator expressions to select
+// instructions. Make sure we only increment the profile counter for the
+// condition when the condition evaluates to true.
+// CHECK-LABEL: define i32 @f1
+int f1(int x) {
+// CHECK: [[TOBOOL:%.*]] = icmp ne i32 %{{.*}}, 0
+// CHECK-NEXT: [[STEP:%.*]] = zext i1 [[TOBOOL]] to i64
+// CHECK-NEXT: [[COUNTER:%.*]] = load i64, i64* getelementptr inbounds ([2 x i64], [2 x i64]* @__profc_f1, i64 0, i64 1)
+// CHECK-NEXT: add i64 [[COUNTER]], [[STEP]]
+// CHECK: [[COND:%.*]] = select i1 [[TOBOOL]], i32 0, i32 1
+  return x ? 0 : 1;
+// CHECK: ret i32 [[COND]]
+}
diff --git a/test/Profile/cxx-class.cpp b/test/Profile/cxx-class.cpp
index dbc93377..ab90d19 100644
--- a/test/Profile/cxx-class.cpp
+++ b/test/Profile/cxx-class.cpp
@@ -5,6 +5,8 @@
 // RUN: FileCheck --input-file=%tgen -check-prefix=DTRGEN %s
 // RUN: FileCheck --input-file=%tgen -check-prefix=MTHGEN %s
 // RUN: FileCheck --input-file=%tgen -check-prefix=WRPGEN %s
+// RUN: FileCheck --input-file=%tgen -check-prefix=VCTRGEN %s
+// RUN: FileCheck --input-file=%tgen -check-prefix=VDTRGEN %s
 
 // RUN: llvm-profdata merge %S/Inputs/cxx-class.proftext -o %t.profdata
 // RUN: %clang_cc1 %s -o - -emit-llvm -fprofile-instrument-use-path=%t.profdata -triple %itanium_abi_triple > %tuse
@@ -12,10 +14,12 @@
 // RUN: FileCheck --input-file=%tuse -check-prefix=DTRUSE %s
 // RUN: FileCheck --input-file=%tuse -check-prefix=MTHUSE %s
 // RUN: FileCheck --input-file=%tuse -check-prefix=WRPUSE %s
+// RUN: FileCheck --input-file=%tuse -check-prefix=VCTRUSE %s
+// RUN: FileCheck --input-file=%tuse -check-prefix=VDTRUSE %s
 
 class Simple {
-  int Member;
 public:
+  int Member;
   // CTRGEN-LABEL: define {{.*}} @_ZN6SimpleC2Ei(
   // CTRUSE-LABEL: define {{.*}} @_ZN6SimpleC2Ei(
   // CTRGEN: store {{.*}} @[[SCC:__profc__ZN6SimpleC2Ei]], i64 0, i64 0
@@ -56,6 +60,35 @@
   // MTHUSE: ![[SM1]] = !{!"branch_weights", i32 100, i32 2}
 };
 
+class Derived : virtual public Simple {
+public:
+  // VCTRGEN-LABEL: define {{.*}} @_ZN7DerivedC1Ev(
+  // VCTRUSE-LABEL: define {{.*}} @_ZN7DerivedC1Ev(
+  // VCTRGEN: store {{.*}} @[[SCC:__profc__ZN7DerivedC1Ev]], i64 0, i64 0
+  Derived() : Simple(0) {
+    // VCTRGEN: store {{.*}} @[[SCC]], i64 0, i64 1
+    // VCTRUSE: br {{.*}} !prof ![[SC1:[0-9]+]]
+    if (Member) {}
+    // VCTRGEN-NOT: store {{.*}} @[[SCC]],
+    // VCTRUSE-NOT: br {{.*}} !prof ![0-9]+
+    // VCTRUSE: ret
+  }
+  // VCTRUSE: ![[SC1]] = !{!"branch_weights", i32 100, i32 2}
+
+  // VDTRGEN-LABEL: define {{.*}} @_ZN7DerivedD2Ev(
+  // VDTRUSE-LABEL: define {{.*}} @_ZN7DerivedD2Ev(
+  // VDTRGEN: store {{.*}} @[[SDC:__profc__ZN7DerivedD2Ev]], i64 0, i64 0
+  ~Derived() {
+    // VDTRGEN: store {{.*}} @[[SDC]], i64 0, i64 1
+    // VDTRUSE: br {{.*}} !prof ![[SD1:[0-9]+]]
+    if (Member) {}
+    // VDTRGEN-NOT: store {{.*}} @[[SDC]],
+    // VDTRUSE-NOT: br {{.*}} !prof ![0-9]+
+    // VDTRUSE: ret
+  }
+  // VDTRUSE: ![[SD1]] = !{!"branch_weights", i32 100, i32 2}
+};
+
 // WRPGEN-LABEL: define {{.*}} @_Z14simple_wrapperv(
 // WRPUSE-LABEL: define {{.*}} @_Z14simple_wrapperv(
 // WRPGEN: store {{.*}} @[[SWC:__profc__Z14simple_wrapperv]], i64 0, i64 0
@@ -63,6 +96,7 @@
   // WRPGEN: store {{.*}} @[[SWC]], i64 0, i64 1
   // WRPUSE: br {{.*}} !prof ![[SW1:[0-9]+]]
   for (int I = 0; I < 100; ++I) {
+    Derived d;
     Simple S(I);
     S.method();
   }
diff --git a/test/Profile/cxx-structors.cpp b/test/Profile/cxx-structors.cpp
index 73562d3..8e0fac1 100644
--- a/test/Profile/cxx-structors.cpp
+++ b/test/Profile/cxx-structors.cpp
@@ -1,6 +1,8 @@
 // Tests for instrumentation of C++ constructors and destructors.
 //
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11.0 -x c++ %s -o - -emit-llvm -fprofile-instrument=clang | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11.0 -x c++ %s -o %t -emit-llvm -fprofile-instrument=clang
+// RUN: FileCheck %s -input-file=%t -check-prefix=INSTR
+// RUN: FileCheck %s -input-file=%t -check-prefix=NOINSTR
 
 struct Foo {
   Foo() {}
@@ -14,19 +16,40 @@
   ~Bar();
 };
 
+struct Baz : virtual public Foo {
+  Baz() {}
+  Baz(int x) : Foo(x) {}
+  ~Baz();
+};
+
+struct Quux : public Foo {
+  Quux(const char *y, ...) : Foo(0) {}
+};
+
 Foo foo;
 Foo foo2(1);
 Bar bar;
+Baz baz;
+Baz baz2(1);
+Quux qux("fi", "fo", "fum");
 
 // Profile data for complete constructors and destructors must absent.
 
-// CHECK-NOT: @__profn__ZN3FooC1Ev
-// CHECK-NOT: @__profn__ZN3FooC1Ei
-// CHECK-NOT: @__profn__ZN3FooD1Ev
-// CHECK-NOT: @__profn__ZN3BarC1Ev
-// CHECK-NOT: @__profn__ZN3BarD1Ev
-// CHECK-NOT: @__profc__ZN3FooD1Ev
-// CHECK-NOT: @__profd__ZN3FooD1Ev
+// INSTR: @__profc__ZN3BazC1Ev =
+// INSTR: @__profc__ZN3BazC1Ei =
+// INSTR: @__profc__ZN4QuuxC1EPKcz =
+// INSTR: @__profc_main =
+// INSTR: @__profc__ZN3FooC2Ev =
+// INSTR: @__profc__ZN3FooD2Ev =
+// INSTR: @__profc__ZN3FooC2Ei =
+// INSTR: @__profc__ZN3BarC2Ev =
+
+// NOINSTR-NOT: @__profc__ZN3FooC1Ev
+// NOINSTR-NOT: @__profc__ZN3FooC1Ei
+// NOINSTR-NOT: @__profc__ZN3FooD1Ev
+// NOINSTR-NOT: @__profc__ZN3BarC1Ev
+// NOINSTR-NOT: @__profc__ZN3BarD1Ev
+// NOINSTR-NOT: @__profc__ZN3FooD1Ev
 
 int main() {
 }
diff --git a/test/Profile/cxx-virtual-destructor-calls.cpp b/test/Profile/cxx-virtual-destructor-calls.cpp
index cc3df68..c60fc92 100644
--- a/test/Profile/cxx-virtual-destructor-calls.cpp
+++ b/test/Profile/cxx-virtual-destructor-calls.cpp
@@ -13,15 +13,6 @@
   virtual ~B();
 };
 
-// Base dtor
-// CHECK: @__profn__ZN1BD2Ev = private constant [9 x i8] c"_ZN1BD2Ev"
-
-// Complete dtor must not be instrumented
-// CHECK-NOT: @__profn__ZN1BD1Ev = private constant [9 x i8] c"_ZN1BD1Ev"
-
-// Deleting dtor must not be instrumented
-// CHECK-NOT: @__profn__ZN1BD0Ev = private constant [9 x i8] c"_ZN1BD0Ev"
-
 // Base dtor counters and profile data
 // CHECK: @__profc__ZN1BD2Ev = private global [1 x i64] zeroinitializer
 // CHECK: @__profd__ZN1BD2Ev =
diff --git a/test/Sema/attr-availability-swift.c b/test/Sema/attr-availability-swift.c
new file mode 100644
index 0000000..42e7524
--- /dev/null
+++ b/test/Sema/attr-availability-swift.c
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -verify %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -ast-dump %s | FileCheck %s
+//
+
+#if !__has_feature(attribute_availability_with_message)
+# error "Missing __has_feature"
+#endif
+
+#if __has_feature(attribute_availability_swift)
+# warning "okay"
+// expected-warning@-1{{okay}}
+#else
+# error "Missing __has_feature"
+#endif
+
+extern int noSwiftGlobal1 __attribute__((availability(swift, unavailable)));
+// CHECK: AvailabilityAttr {{.*}}swift 0 0 0 Unavailable "" ""
+extern int noSwiftGlobal1 __attribute__((availability(macosx, introduced=10.1))); // okay
+// CHECK: AvailabilityAttr {{.*}}macos 10.1 0 0 "" ""
+// CHECK: AvailabilityAttr {{.*}}Inherited swift 0 0 0 Unavailable "" ""
+extern int noSwiftGlobal1 __attribute__((availability(swift, unavailable, message="and this one has a message"))); // okay
+// CHECK: AvailabilityAttr {{.*}}swift 0 0 0 Unavailable "and this one has a message" ""
+// CHECK: AvailabilityAttr {{.*}}Inherited macos 10.1 0 0 "" ""
+extern int noSwiftGlobal2 __attribute__((availability(swift, introduced=5))); // expected-warning{{only 'unavailable' and 'deprecated' are supported for Swift availability}}
+// CHECK: VarDecl
+// CHECK-NOT: AvailabilityAttr
+extern int noSwiftGlobal3 __attribute__((availability(swift, deprecated, message="t")));
+// CHECK: VarDecl
+// CHECK: AvailabilityAttr {{.*}}swift 0 1 0 "t" ""
diff --git a/test/Sema/attr-availability.c b/test/Sema/attr-availability.c
index a4b40ff..9736098 100644
--- a/test/Sema/attr-availability.c
+++ b/test/Sema/attr-availability.c
@@ -30,7 +30,7 @@
   ATSFontGetPostScriptName(100); // expected-error {{'ATSFontGetPostScriptName' is unavailable: obsoleted in macOS 9.0 - use ATSFontGetFullPostScriptName}}
 
 #if defined(WARN_PARTIAL)
-  // expected-warning@+2 {{is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'PartiallyAvailable' in an @available check to silence this warning}}
+  // expected-warning@+2 {{is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'PartiallyAvailable' in a __builtin_available check to silence this warning}}
 #endif
   PartiallyAvailable();
 }
@@ -74,13 +74,12 @@
 
 void f8() {
   int (^b)(int);
-  b = ^ (int i) __attribute__((availability(macosx,introduced=10.2))) { return 1; }; // expected-warning {{'availability' attribute ignored}}
+  b = ^ (int i) __attribute__((availability(macosx,introduced=10.2))) { return 1; }; // expected-warning {{'availability' attribute only applies to named declarations}}
 }
 
 extern int x2 __attribute__((availability(macosx,introduced=10.2))); // expected-note {{previous attribute is here}}
 extern int x2 __attribute__((availability(macosx,introduced=10.5))); // expected-warning {{availability does not match previous declaration}}
 
-
 enum Original {
   OriginalDeprecated __attribute__((availability(macosx, deprecated=10.2))), // expected-note + {{'OriginalDeprecated' has been explicitly marked deprecated here}}
   OriginalUnavailable __attribute__((availability(macosx, unavailable))) // expected-note + {{'OriginalUnavailable' has been explicitly marked unavailable here}}
diff --git a/test/Sema/attr-deprecated.c b/test/Sema/attr-deprecated.c
index 8566a0e..89c0686 100644
--- a/test/Sema/attr-deprecated.c
+++ b/test/Sema/attr-deprecated.c
@@ -1,10 +1,12 @@
 // RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -std=c89 -verify -fsyntax-only
+// RUN: %clang_cc1 %s -std=c99 -verify -fsyntax-only
 
 int f() __attribute__((deprecated)); // expected-note 2 {{'f' has been explicitly marked deprecated here}}
-void g() __attribute__((deprecated));
-void g(); // expected-note {{'g' has been explicitly marked deprecated here}}
+void g() __attribute__((deprecated));// expected-note {{'g' has been explicitly marked deprecated here}}
+void g(); 
 
-extern int var __attribute__((deprecated)); // expected-note {{'var' has been explicitly marked deprecated here}}
+extern int var __attribute__((deprecated)); // expected-note 2 {{'var' has been explicitly marked deprecated here}}
 
 int a() {
   int (*ptr)() = f; // expected-warning {{'f' is deprecated}}
@@ -17,13 +19,13 @@
 }
 
 // test if attributes propagate to variables
-extern int var; // expected-note {{'var' has been explicitly marked deprecated here}}
+extern int var; 
 int w() {
   return var; // expected-warning {{'var' is deprecated}}
 }
 
-int old_fn() __attribute__ ((deprecated));
-int old_fn(); // expected-note {{'old_fn' has been explicitly marked deprecated here}}
+int old_fn() __attribute__ ((deprecated));// expected-note {{'old_fn' has been explicitly marked deprecated here}}
+int old_fn(); 
 int (*fn_ptr)() = old_fn; // expected-warning {{'old_fn' is deprecated}}
 
 int old_fn() {
@@ -44,8 +46,8 @@
 typedef struct foo foo_dep __attribute__((deprecated)); // expected-note 12 {{'foo_dep' has been explicitly marked deprecated here}}
 foo_dep *test2;    // expected-warning {{'foo_dep' is deprecated}}
 
-struct __attribute__((deprecated, 
-                      invalid_attribute)) bar_dep ;  // expected-warning {{unknown attribute 'invalid_attribute' ignored}} expected-note 2 {{'bar_dep' has been explicitly marked deprecated here}}
+struct __attribute__((deprecated, // expected-note 2 {{'bar_dep' has been explicitly marked deprecated here}}
+                      invalid_attribute)) bar_dep ;  // expected-warning {{unknown attribute 'invalid_attribute' ignored}} 
 
 struct bar_dep *test3;   // expected-warning {{'bar_dep' is deprecated}}
 
@@ -121,11 +123,12 @@
   __attribute((deprecated)) foo_dep e, f;
 };
 
-typedef int test23_ty __attribute((deprecated));
+typedef int test23_ty __attribute((deprecated)); 
 // Redefining a typedef is a C11 feature.
 #if __STDC_VERSION__ <= 199901L
 // expected-note@-3 {{'test23_ty' has been explicitly marked deprecated here}}
 #else
-typedef int test23_ty; // expected-note {{'test23_ty' has been explicitly marked deprecated here}}
+// expected-note@-5 {{'test23_ty' has been explicitly marked deprecated here}}
+typedef int test23_ty; 
 #endif
 test23_ty test23_v; // expected-warning {{'test23_ty' is deprecated}}
diff --git a/test/Sema/attr-external-source-symbol.c b/test/Sema/attr-external-source-symbol.c
new file mode 100644
index 0000000..af6e6bc
--- /dev/null
+++ b/test/Sema/attr-external-source-symbol.c
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
+
+void threeClauses() __attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration)));
+
+void twoClauses() __attribute__((external_source_symbol(language="Swift", defined_in="module")));
+
+void fourClauses() __attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration, generated_declaration))); // expected-error {{duplicate 'generated_declaration' clause in an 'external_source_symbol' attribute}}
+
+void oneClause() __attribute__((external_source_symbol(generated_declaration)));
+
+void noArguments()
+__attribute__((external_source_symbol)); // expected-error {{'external_source_symbol' attribute takes at least 1 argument}}
+
+void namedDeclsOnly() {
+  int (^block)(void) = ^ (void)
+    __attribute__((external_source_symbol(language="Swift"))) { // expected-warning {{'external_source_symbol' attribute only applies to named declarations}}
+      return 1;
+  };
+}
diff --git a/test/Sema/attr-noescape.c b/test/Sema/attr-noescape.c
new file mode 100644
index 0000000..ec367b6
--- /dev/null
+++ b/test/Sema/attr-noescape.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -fblocks -verify -fsyntax-only
+
+#if !__has_attribute(noescape)
+#  error "missing noescape attribute"
+#endif
+
+int *global_var __attribute((noescape)); // expected-warning{{'noescape' attribute only applies to parameters}}
+
+void foo(__attribute__((noescape)) int *int_ptr,
+         __attribute__((noescape)) int (^block)(int),
+         __attribute((noescape)) int integer) { // expected-warning{{'noescape' attribute ignored on parameter of non-pointer type 'int'}}
+}
diff --git a/test/Sema/designated-initializers.c b/test/Sema/designated-initializers.c
index a4582de..43f3318 100644
--- a/test/Sema/designated-initializers.c
+++ b/test/Sema/designated-initializers.c
@@ -351,3 +351,20 @@
   { { 'f', 'o', 'o' }, 1 },
   [0].L[4] = 'x' // no-warning
 };
+
+struct {
+  struct { } s1;
+  union {
+    int a;
+    int b;
+  } u1;
+} s = {
+  .s1 = {
+    .x = 0, // expected-error{{field designator}}
+  },
+
+  .u1 = {
+    .a = 0,
+    .b = 0,
+  },
+};
diff --git a/test/Sema/enum-attr.c b/test/Sema/enum-attr.c
new file mode 100644
index 0000000..933d8cc
--- /dev/null
+++ b/test/Sema/enum-attr.c
@@ -0,0 +1,130 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wassign-enum -Wswitch-enum -Wcovered-switch-default %s
+
+enum Enum {
+  A0 = 1, A1 = 10
+};
+
+enum __attribute__((enum_extensibility(closed))) EnumClosed {
+  B0 = 1, B1 = 10
+};
+
+enum __attribute__((enum_extensibility(open))) EnumOpen {
+  C0 = 1, C1 = 10
+};
+
+enum __attribute__((flag_enum)) EnumFlag {
+  D0 = 1, D1 = 8
+};
+
+enum __attribute__((flag_enum,enum_extensibility(closed))) EnumFlagClosed {
+  E0 = 1, E1 = 8
+};
+
+enum __attribute__((flag_enum,enum_extensibility(open))) EnumFlagOpen {
+  F0 = 1, F1 = 8
+};
+
+enum __attribute__((enum_extensibility(arg1))) EnumInvalidArg { // expected-warning{{'enum_extensibility' attribute argument not supported: 'arg1'}}
+  X0
+};
+
+// FIXME: The warning should mention that enum_extensibility takes only one argument.
+enum __attribute__((enum_extensibility(closed,open))) EnumTooManyArgs { // expected-error{{use of undeclared identifier 'open'}}
+  X1
+};
+
+enum __attribute__((enum_extensibility())) EnumTooFewArgs { // expected-error{{'enum_extensibility' attribute takes one argument}}
+  X2
+};
+
+struct __attribute__((enum_extensibility(open))) S { // expected-warning{{'enum_extensibility' attribute only applies to enums}}{
+};
+
+void test() {
+  enum Enum t0 = 100; // expected-warning{{integer constant not in range of enumerated type}}
+  t0 = 1;
+
+  switch (t0) { // expected-warning{{enumeration value 'A1' not handled in switch}}
+  case A0: break;
+  case 16: break; // expected-warning{{case value not in enumerated type}}
+  }
+
+  switch (t0) {
+  case A0: break;
+  case A1: break;
+  default: break; // expected-warning{{default label in switch which covers all enumeration}}
+  }
+
+  enum EnumClosed t1 = 100; // expected-warning{{integer constant not in range of enumerated type}}
+  t1 = 1;
+
+  switch (t1) { // expected-warning{{enumeration value 'B1' not handled in switch}}
+  case B0: break;
+  case 16: break; // expected-warning{{case value not in enumerated type}}
+  }
+
+  switch (t1) {
+  case B0: break;
+  case B1: break;
+  default: break; // expected-warning{{default label in switch which covers all enumeration}}
+  }
+
+  enum EnumOpen t2 = 100;
+  t2 = 1;
+
+  switch (t2) { // expected-warning{{enumeration value 'C1' not handled in switch}}
+  case C0: break;
+  case 16: break;
+  }
+
+  switch (t2) {
+  case C0: break;
+  case C1: break;
+  default: break;
+  }
+
+  enum EnumFlag t3 = 5; // expected-warning{{integer constant not in range of enumerated type}}
+  t3 = 9;
+
+  switch (t3) { // expected-warning{{enumeration value 'D1' not handled in switch}}
+  case D0: break;
+  case 9: break;
+  case 16: break; // expected-warning{{case value not in enumerated type}}
+  }
+
+  switch (t3) {
+  case D0: break;
+  case D1: break;
+  default: break;
+  }
+
+  enum EnumFlagClosed t4 = 5; // expected-warning{{integer constant not in range of enumerated type}}
+  t4 = 9;
+
+  switch (t4) { // expected-warning{{enumeration value 'E1' not handled in switch}}
+  case E0: break;
+  case 9: break;
+  case 16: break; // expected-warning{{case value not in enumerated type}}
+  }
+
+  switch (t4) {
+  case E0: break;
+  case E1: break;
+  default: break;
+  }
+
+  enum EnumFlagOpen t5 = 5;
+  t5 = 9;
+
+  switch (t5) { // expected-warning{{enumeration value 'F1' not handled in switch}}
+  case F0: break;
+  case 9: break;
+  case 16: break;
+  }
+
+  switch (t5) {
+  case F0: break;
+  case F1: break;
+  default: break;
+  }
+}
diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c
index 5465122..ca3132e 100644
--- a/test/Sema/format-strings.c
+++ b/test/Sema/format-strings.c
@@ -653,6 +653,33 @@
 }
 #pragma GCC diagnostic warning "-Wformat-nonliteral"
 
+void test_os_log_format(char c, const char *pc, int i, int *pi, void *p, void *buf) {
+  __builtin_os_log_format(buf, "");
+  __builtin_os_log_format(buf, "%d"); // expected-warning {{more '%' conversions than data arguments}}
+  __builtin_os_log_format(buf, "%d", i);
+  __builtin_os_log_format(buf, "%P", p); // expected-warning {{using '%P' format specifier without precision}}
+  __builtin_os_log_format(buf, "%.10P", p);
+  __builtin_os_log_format(buf, "%.*P", p); // expected-warning {{field precision should have type 'int', but argument has type 'void *'}}
+  __builtin_os_log_format(buf, "%.*P", i, p);
+  __builtin_os_log_format(buf, "%.*P", i, i); // expected-warning {{format specifies type 'void *' but the argument has type 'int'}}
+  __builtin_os_log_format(buf, pc); // expected-error {{os_log() format argument is not a string constant}}
+
+  printf("%{private}s", pc); // expected-warning {{using 'private' format specifier annotation outside of os_log()/os_trace()}}
+  __builtin_os_log_format(buf, "%{private}s", pc);
+
+  // <rdar://problem/23835805>
+  __builtin_os_log_format_buffer_size("no-args");
+  __builtin_os_log_format(buf, "%s", "hi");
+
+  // <rdar://problem/24828090>
+  wchar_t wc = 'a';
+  __builtin_os_log_format(buf, "%C", wc);
+  printf("%C", wc);
+  wchar_t wcs[] = {'a', 0};
+  __builtin_os_log_format(buf, "%S", wcs);
+  printf("%S", wcs);
+}
+
 void test_char_pointer_arithmetic(int b) {
   const char s1[] = "string";
   const char s2[] = "%s string";
diff --git a/test/Sema/knr-def-call.c b/test/Sema/knr-def-call.c
index 80ad0d8..2bd4a79 100644
--- a/test/Sema/knr-def-call.c
+++ b/test/Sema/knr-def-call.c
@@ -1,13 +1,13 @@
-// RUN: %clang_cc1 -Wconversion -Wliteral-conversion -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-pc-unknown -Wconversion -Wliteral-conversion -fsyntax-only -verify %s
 
 // C DR #316, PR 3626.
 void f0(a, b, c, d) int a,b,c,d; {}
-void t0(void) { 
+void t0(void) {
   f0(1);  // expected-warning{{too few arguments}}
 }
 
 void f1(a, b) int a, b; {}
-void t1(void) { 
+void t1(void) {
   f1(1, 2, 3); // expected-warning{{too many arguments}}
 }
 
@@ -30,7 +30,7 @@
 
 // PR8314
 void proto(int);
-void proto(x) 
+void proto(x)
      int x;
 {
 }
@@ -39,3 +39,9 @@
   proto(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}}
   (&proto)(42.1); // expected-warning{{implicit conversion from 'double' to 'int' changes value from 42.1 to 42}}
 }
+
+// PR31020
+void func(short d) __attribute__((cdecl)); // expected-note{{previous declaration is here}}
+void __attribute__((cdecl)) func(d)
+  short d; // expected-warning{{promoted type 'int' of K&R function parameter is not compatible with the parameter type 'short' declared in a previous prototype}}
+{}
diff --git a/test/Sema/pragma-attribute-strict-subjects.c b/test/Sema/pragma-attribute-strict-subjects.c
new file mode 100644
index 0000000..a84e2bd
--- /dev/null
+++ b/test/Sema/pragma-attribute-strict-subjects.c
@@ -0,0 +1,153 @@
+// RUN: %clang_cc1 -fsyntax-only -Wno-pragmas -verify %s
+
+#pragma clang attribute push (__attribute__((annotate("test"))), apply_to = any(function, variable))
+
+#pragma clang attribute pop
+
+// Check for contradictions in rules for attribute without a strict subject set:
+
+#pragma clang attribute push (__attribute__((annotate("subRuleContradictions"))), apply_to = any(variable, variable(is_parameter), function(is_member), variable(is_global)))
+// expected-error@-1 {{redundant attribute subject matcher sub-rule 'variable(is_parameter)'; 'variable' already matches those declarations}}
+// expected-error@-2 {{redundant attribute subject matcher sub-rule 'variable(is_global)'; 'variable' already matches those declarations}}
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((annotate("subRuleContradictions2"))), apply_to = any(function(is_member), function))
+// expected-error@-1 {{redundant attribute subject matcher sub-rule 'function(is_member)'; 'function' already matches those declarations}}
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((annotate("subRuleContradictions3"))), apply_to = any(variable, variable(unless(is_parameter))))
+// expected-error@-1 {{redundant attribute subject matcher sub-rule 'variable(unless(is_parameter))'; 'variable' already matches those declarations}}
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((annotate("negatedSubRuleContradictions1"))), apply_to = any(variable(is_parameter), variable(unless(is_parameter))))
+// expected-error@-1 {{negated attribute subject matcher sub-rule 'variable(unless(is_parameter))' contradicts sub-rule 'variable(is_parameter)'}}
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((annotate("negatedSubRuleContradictions2"))), apply_to = any(variable(unless(is_parameter)), variable(is_thread_local), function, variable(is_global)))
+// expected-error@-1 {{negated attribute subject matcher sub-rule 'variable(unless(is_parameter))' contradicts sub-rule 'variable(is_global)'}}
+// We have just one error, don't error on 'variable(is_global)'
+
+#pragma clang attribute pop
+
+// Verify the strict subject set verification.
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function))
+// No error
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable))
+// No error
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, variable, record(unless(is_union))))
+// No error
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(variable, record(unless(is_union)), function))
+// No error
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, record(unless(is_union)), variable, enum))
+// expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum'}}
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(enum_constant, function, record(unless(is_union)), variable, variable(is_parameter)))
+// expected-error@-1 {{attribute 'abi_tag' can't be applied to 'variable(is_parameter)', and 'enum_constant'}}
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, record(unless(is_union)), enum))
+// expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum'}}
+#pragma clang attribute pop
+
+// Verify the non-strict subject set verification.
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function))
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = variable)
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union))))
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(function, variable))
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(variable, record(unless(is_union))))
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function))
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable))
+
+#pragma clang attribute pop
+
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = any(record(unless(is_union)), function, variable, enum, enum_constant))
+// expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum_constant', and 'enum'}}
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((abi_tag("a"))), apply_to = enum)
+// expected-error@-1 {{attribute 'abi_tag' can't be applied to 'enum'}}
+
+#pragma clang attribute pop
+
+// Handle attributes whose subjects are supported only in other language modes:
+
+#pragma clang attribute push(__attribute__((abi_tag("b"))), apply_to = any(namespace, record(unless(is_union)), variable, function))
+// 'namespace' is accepted!
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((abi_tag("b"))), apply_to = any(namespace))
+// 'namespace' is accepted!
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((objc_subclassing_restricted)), apply_to = objc_interface)
+// No error!
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((objc_subclassing_restricted)), apply_to = objc_interface)
+// No error!
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((objc_subclassing_restricted)), apply_to = any(objc_interface, objc_protocol))
+// expected-error@-1 {{attribute 'objc_subclassing_restricted' can't be applied to 'objc_protocol'}}
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((objc_subclassing_restricted)), apply_to = any(objc_protocol))
+// expected-error@-1 {{attribute 'objc_subclassing_restricted' can't be applied to 'objc_protocol'}}
+// Don't report an error about missing 'objc_interface' as we aren't parsing
+// Objective-C.
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((objc_subclassing_restricted)), apply_to = any(objc_interface, objc_protocol))
+// expected-error@-1 {{attribute 'objc_subclassing_restricted' can't be applied to 'objc_protocol'}}
+#pragma clang attribute pop
+
+#pragma clang attribute push(__attribute__((objc_subclassing_restricted)), apply_to = any(objc_protocol))
+// expected-error@-1 {{attribute 'objc_subclassing_restricted' can't be applied to 'objc_protocol'}}
+// Don't report an error about missing 'objc_interface' as we aren't parsing
+// Objective-C.
+#pragma clang attribute pop
+
+// Use of matchers from other language modes should not cause for attributes
+// without subject list:
+#pragma clang attribute push (__attribute__((annotate("test"))), apply_to = objc_method)
+
+#pragma clang attribute pop
+
+#pragma clang attribute push (__attribute__((annotate("test"))), apply_to = any(objc_interface, objc_protocol))
+
+#pragma clang attribute pop
diff --git a/test/Sema/pragma-attribute.c b/test/Sema/pragma-attribute.c
new file mode 100644
index 0000000..6ed69c4
--- /dev/null
+++ b/test/Sema/pragma-attribute.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#pragma clang attribute pop // expected-error {{'#pragma clang attribute pop' with no matching '#pragma clang attribute push'}}
+
+// Don't verify unused attributes.
+#pragma clang attribute push (__attribute__((annotate)), apply_to = function) // expected-warning {{unused attribute 'annotate' in '#pragma clang attribute push' region}}
+#pragma clang attribute pop // expected-note {{'#pragma clang attribute push' regions ends here}}
+
+// Ensure we only report any errors once.
+#pragma clang attribute push (__attribute__((annotate)), apply_to = function) // expected-error 4 {{'annotate' attribute takes one argument}}
+
+void test5_begin(); // expected-note {{when applied to this declaration}}
+void test5_1(); // expected-note {{when applied to this declaration}}
+
+#pragma clang attribute push (__attribute__((annotate())), apply_to = function) // expected-error 2 {{'annotate' attribute takes one argument}}
+
+void test5_2(); // expected-note 2 {{when applied to this declaration}}
+
+#pragma clang attribute push (__attribute__((annotate("hello", "world"))), apply_to = function) // expected-error {{'annotate' attribute takes one argument}}
+
+void test5_3(); // expected-note 3 {{when applied to this declaration}}
+
+#pragma clang attribute pop
+#pragma clang attribute pop
+#pragma clang attribute pop
+
+// Verify that the warnings are reported for each receiver declaration
+
+#pragma clang attribute push (__attribute__((optnone)), apply_to = function) // expected-note 2 {{conflicting attribute is here}}
+
+__attribute__((always_inline)) void optnone1() { } // expected-warning {{'always_inline' attribute ignored}}
+// expected-note@-1 2 {{when applied to this declaration}}
+
+void optnone2() { }
+
+__attribute__((always_inline)) void optnone3() { } // expected-warning {{'always_inline' attribute ignored}}
+// expected-note@-1 2 {{when applied to this declaration}}
+
+#pragma clang attribute pop
+
+#pragma clang attribute push ([[]], apply_to = function) // A noop
+
+#pragma clang attribute pop // expected-error {{'#pragma clang attribute pop' with no matching '#pragma clang attribute push'}}
+
+#pragma clang attribute push (__attribute__((annotate("func"))), apply_to = function) // expected-error {{unterminated '#pragma clang attribute push' at end of file}}
+
+void function();
diff --git a/test/Sema/redefinition-same-header.c b/test/Sema/redefinition-same-header.c
new file mode 100644
index 0000000..d523edb
--- /dev/null
+++ b/test/Sema/redefinition-same-header.c
@@ -0,0 +1,14 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo 'int yyy = 42;' > %t/a.h
+// RUN: %clang_cc1 -fsyntax-only %s -I%t  -verify
+
+// expected-error@a.h:1 {{redefinition of 'yyy'}}
+// expected-note@a.h:1 {{unguarded header; consider using #ifdef guards or #pragma once}}
+// expected-note-re@redefinition-same-header.c:11 {{'{{.*}}/a.h' included multiple times, additional include site here}}
+// expected-note-re@redefinition-same-header.c:12 {{'{{.*}}/a.h' included multiple times, additional include site here}}
+
+#include "a.h"
+#include "a.h"
+
+int foo() { return yyy; }
diff --git a/test/Sema/vector-cast.c b/test/Sema/vector-cast.c
index ea4acfa..03db540 100644
--- a/test/Sema/vector-cast.c
+++ b/test/Sema/vector-cast.c
@@ -45,24 +45,12 @@
 }
 
 typedef float float2 __attribute__ ((vector_size (8)));
-typedef __attribute__((vector_size(8))) double float64x1_t;
-typedef __attribute__((vector_size(16))) double float64x2_t;
-float64x1_t vget_low_f64(float64x2_t __p0);
 
 void f4() {
   float2 f2;
-  double d, a, b, c;
-  float64x2_t v = {0.0, 1.0};
-  // FIXME: These diagnostics are inaccurate: should complain that 'double' to vector 'float2' involves truncation
-  f2 += d; // expected-error {{cannot convert between vector values of different size ('float2' (vector of 2 'float' values) and 'double')}}
-  d += f2; // expected-error {{cannot convert between vector values of different size}}
-  a = 3.0 + vget_low_f64(v);
-  b = vget_low_f64(v) + 3.0;
-  c = vget_low_f64(v);
-  c -= vget_low_f64(v);
-  // LAX conversions between scalar and vector types require same size and one element sized vectors.
-  d = f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}}
-  d = d + f2; // expected-error {{assigning to 'double' from incompatible type 'float2'}}
+  double d;
+  f2 += d;
+  d += f2;
 }
 
 // rdar://15931426
diff --git a/test/Sema/vector-compound-assign-lax.cpp b/test/Sema/vector-compound-assign-lax.cpp
new file mode 100644
index 0000000..296cfb7
--- /dev/null
+++ b/test/Sema/vector-compound-assign-lax.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -ffreestanding -triple armv7 -target-feature +neon -fsyntax-only %s -verify -Wvector-conversion -DNEON
+// RUN: %clang_cc1 -ffreestanding -triple=x86_64-apple-darwin -target-feature +sse2 -fsyntax-only %s -verify -Wvector-conversion -DSSE2
+
+// Test that there are no diagnostics for vector compound assignments where we
+// support lax conversions from the RHS type to the LHS type. For context, see:
+//
+//   <rdar://problem/30112602> cannot convert between vector values ...
+//   <rdar://problem/28639522> Cannot create binary operator with two ...
+//   <rdar://problem/30110333> Invalid conversion from int64x2 to uint32x4 ...
+
+// expected-no-diagnostics
+
+#include <stdint.h>
+
+typedef int v_int32x4_t __attribute__((__vector_size__(16)));
+typedef unsigned v_uint32x4_t __attribute__((__vector_size__(16)));
+
+#ifdef NEON
+typedef __attribute__((neon_vector_type(8))) int16_t n_int16x8_t;
+typedef __attribute__((neon_vector_type(8))) uint16_t n_uint16x8_t;
+
+void fn1() {
+  n_int16x8_t i;
+  n_uint16x8_t u;
+  i += u;
+}
+#endif
+
+void fn2() {
+  v_int32x4_t i;
+  v_uint32x4_t u;
+  i += u;
+}
+
+#ifdef SSE2
+#include <x86intrin.h>
+
+typedef __attribute__((__ext_vector_type__(4))) unsigned int ev_uint32x4_t;
+
+void fn3() {
+  __m128i i;
+  ev_uint32x4_t u;
+  i += u; // FIXME: Converting uint32x4 to int64x2 should *not* be allowed.
+}
+#endif
diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp
index 34d8f5f..0c92b2a 100644
--- a/test/Sema/warn-documentation.cpp
+++ b/test/Sema/warn-documentation.cpp
@@ -1210,3 +1210,75 @@
 /*!     @function test_function<int>
 */
 template <> int test_function<int> (int arg);
+
+namespace AllowParamAndReturnsOnFunctionPointerVars {
+
+/**
+ * functionPointerVariable
+ *
+ * @param i is integer.
+ * @returns integer.
+ */
+int (*functionPointerVariable)(int i);
+
+struct HasFields {
+  /**
+   * functionPointerField
+   *
+   * @param i is integer.
+   * @returns integer.
+   */
+  int (*functionPointerField)(int i);
+};
+
+// expected-warning@+5 {{'\returns' command used in a comment that is attached to a function returning void}}
+/**
+ * functionPointerVariable
+ *
+ * \param p not here.
+ * \returns integer.
+ */
+void (*functionPointerVariableThatLeadsNowhere)();
+
+// Still warn about param/returns commands for variables that don't specify
+// the type directly:
+
+/**
+ * FunctionPointerTypedef
+ *
+ * \param i is integer.
+ * \returns integer.
+ */
+typedef int (*FunctionPointerTypedef)(int i);
+
+/**
+ * FunctionPointerTypealias
+ *
+ * \param i is integer.
+ * \returns integer.
+ */
+using FunctionPointerTypealias = int (*)(int i);
+
+// expected-warning@+5 {{'@param' command used in a comment that is not attached to a function declaration}}
+// expected-warning@+5 {{'@returns' command used in a comment that is not attached to a function or method declaration}}
+/**
+ * functionPointerVariable
+ *
+ * @param i is integer.
+ * @returns integer.
+ */
+FunctionPointerTypedef functionPointerTypedefVariable;
+
+struct HasMoreFields {
+  // expected-warning@+5 {{'\param' command used in a comment that is not attached to a function declaration}}
+  // expected-warning@+5 {{'\returns' command used in a comment that is not attached to a function or method declaration}}
+  /**
+   * functionPointerTypealiasField
+   *
+   * \param i is integer.
+   * \returns integer.
+   */
+  FunctionPointerTypealias functionPointerTypealiasField;
+};
+
+}
diff --git a/test/Sema/warn-documentation.m b/test/Sema/warn-documentation.m
index 5e95e2a..3c1a369 100644
--- a/test/Sema/warn-documentation.m
+++ b/test/Sema/warn-documentation.m
@@ -229,3 +229,73 @@
 - (void) VarArgMeth : (id)arg, ... {}
 @end
 
+/**
+ * blockPointerVariable
+ *
+ * @param i is integer.
+ * @returns integer.
+ */
+int (^blockPointerVariable)(int i);
+
+struct HasFields {
+  /**
+   * blockPointerField
+   *
+   * \param i is integer.
+   * \returns integer.
+   */
+  int (^blockPointerFields)(int i);
+};
+
+// expected-warning@+5 {{'\returns' command used in a comment that is attached to a function returning void}}
+/**
+ * functionPointerVariable
+ *
+ * \param p not here.
+ * \returns integer.
+ */
+void (^_Nullable blockPointerVariableThatLeadsNowhere)();
+
+@interface CheckFunctionBlockPointerVars {
+  /**
+   * functionPointerIVar
+   *
+   * @param i is integer.
+   * @returns integer.
+   */
+  int (*functionPointerIVar)(int i);
+
+  /**
+   * blockPointerIVar
+   *
+   * \param i is integer.
+   * \returns integer.
+   */
+  int (^blockPointerIVar)(int i);
+}
+
+/**
+ * functionPointerProperty
+ *
+ * @param i is integer.
+ * @returns integer.
+ */
+@property int (*functionPointerProperty)(int i);
+
+/**
+ * blockPointerProperty
+ *
+ * \param i is integer.
+ * \returns integer.
+ */
+@property int (^blockPointerProperty)(int i);
+
+/**
+ * blockReturnsNothing
+ *
+ * \returns Nothing, but can allow this as this pattern is used to document the
+ * value that the property getter returns.
+ */
+@property void (^blockReturnsNothing)();
+
+@end
diff --git a/test/Sema/warn-strict-prototypes.c b/test/Sema/warn-strict-prototypes.c
index 496579c..a28f57d 100644
--- a/test/Sema/warn-strict-prototypes.c
+++ b/test/Sema/warn-strict-prototypes.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -Wstrict-prototypes -verify %s
-// RUN: %clang_cc1 -fsyntax-only -Wstrict-prototypes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -Wstrict-prototypes -verify %s
+// RUN: %clang_cc1 -triple i386-pc-unknown -fsyntax-only -Wstrict-prototypes -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 // function declaration with unspecified params
 void foo1(); // expected-warning {{this function declaration is not a prototype}}
@@ -60,3 +60,8 @@
 // K&R function definition with previous prototype declared is not diagnosed.
 void foo11(int p, int p2);
 void foo11(p, p2) int p; int p2; {}
+
+// PR31020
+void __attribute__((cdecl)) foo12(d) // expected-warning {{this old-style function definition is not preceded by a prototype}}
+  short d;
+{}
diff --git a/test/Sema/warn-unreachable.c b/test/Sema/warn-unreachable.c
index 34e0296..440aa0a 100644
--- a/test/Sema/warn-unreachable.c
+++ b/test/Sema/warn-unreachable.c
@@ -451,3 +451,50 @@
             // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:15-[[@LINE-2]]:15}:")"
   unaryOpFixitCastSubExpr(x); // expected-warning {{code will never be executed}}
 }
+
+#define false 0
+#define true 1
+
+void testTrueFalseMacros() {
+  if (false) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    testTrueFalseMacros(); // expected-warning {{code will never be executed}}
+  if (!true) // expected-note {{silence by adding parentheses to mark code as explicitly dead}}
+    testTrueFalseMacros(); // expected-warning {{code will never be executed}}
+}
+
+int pr13910_foo(int x) {
+  if (x == 1)
+    return 0;
+  else
+    return x;
+  __builtin_unreachable(); // expected no warning
+}
+
+int pr13910_bar(int x) {
+  switch (x) {
+  default:
+    return x + 1;
+  }
+  pr13910_foo(x); // expected-warning {{code will never be executed}}
+}
+
+int pr13910_bar2(int x) {
+  if (x == 1)
+    return 0;
+  else
+    return x;
+  pr13910_foo(x);          // expected-warning {{code will never be executed}}
+  __builtin_unreachable(); // expected no warning
+  pr13910_foo(x);          // expected-warning {{code will never be executed}}
+}
+
+void pr13910_noreturn() {
+  raze();
+  __builtin_unreachable(); // expected no warning
+}
+
+void pr13910_assert() {
+  myassert(0 && "unreachable");
+  return;
+  __builtin_unreachable(); // expected no warning
+}
diff --git a/test/SemaCXX/MicrosoftExtensions.cpp b/test/SemaCXX/MicrosoftExtensions.cpp
index e12dea1..6d8cc1f 100644
--- a/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/test/SemaCXX/MicrosoftExtensions.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fms-extensions -fexceptions -fcxx-exceptions -DTEST1
 // RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -Wmicrosoft -Wc++11-extensions -Wno-long-long -verify -fexceptions -fcxx-exceptions -DTEST2
+// RUN: %clang_cc1 %s -triple i686-pc-win32 -fsyntax-only -std=c++11 -fms-compatibility -verify -DTEST3
 
 #if TEST1
 
@@ -491,6 +492,13 @@
 // Check that __unaligned is not recognized if MS extensions are not enabled
 typedef char __unaligned *aligned_type; // expected-error {{expected ';' after top level declarator}}
 
+#elif TEST3
+
+namespace PR32750 {
+template<typename T> struct A {};
+template<typename T> struct B : A<A<T>> { A<T>::C::D d; }; // expected-error {{missing 'typename' prior to dependent type name 'A<T>::C::D'}}
+}
+
 #else
 
 #error Unknown test mode
diff --git a/test/SemaCXX/attr-deprecated.cpp b/test/SemaCXX/attr-deprecated.cpp
index eab5a1c..1680c5c 100644
--- a/test/SemaCXX/attr-deprecated.cpp
+++ b/test/SemaCXX/attr-deprecated.cpp
@@ -56,14 +56,14 @@
 }
 
 struct D {
-  virtual void f() __attribute__((deprecated));
-  virtual void f(int) __attribute__((deprecated));
-  virtual void f(int, int) __attribute__((deprecated));
+  virtual void f() __attribute__((deprecated));// expected-note{{'f' has been explicitly marked deprecated here}}
+  virtual void f(int) __attribute__((deprecated));// expected-note{{'f' has been explicitly marked deprecated here}}
+  virtual void f(int, int) __attribute__((deprecated));// expected-note{{'f' has been explicitly marked deprecated here}}
 };
 
-void D::f() { } // expected-note{{'f' has been explicitly marked deprecated here}}
-void D::f(int v) { } // expected-note{{'f' has been explicitly marked deprecated here}}
-void D::f(int v1, int v2) { } // expected-note{{'f' has been explicitly marked deprecated here}}
+void D::f() { } 
+void D::f(int v) { } 
+void D::f(int v1, int v2) { } 
 
 void f(D* d) {
   d->f(); // expected-warning{{'f' is deprecated}}
diff --git a/test/SemaCXX/attr-flag-enum-reject.cpp b/test/SemaCXX/attr-flag-enum-reject.cpp
deleted file mode 100644
index f28d60c..0000000
--- a/test/SemaCXX/attr-flag-enum-reject.cpp
+++ /dev/null
@@ -1,4 +0,0 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -x c++ -Wassign-enum %s
-
-enum __attribute__((flag_enum)) flag { // expected-warning {{ignored}}
-};
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 0668324..5bc30b9 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1280,6 +1280,15 @@
     constexpr TestVar testVar{-1};
     static_assert(testVar.value == -1, "");
   }
+
+  namespace PR32034 {
+    struct A {};
+    struct B { _Atomic(A) a; };
+    constexpr int n = (B(), B(), 0);
+
+    struct C { constexpr C() {} void *self = this; };
+    constexpr _Atomic(C) c = C();
+  }
 }
 
 namespace InstantiateCaseStmt {
diff --git a/test/SemaCXX/designated-initializers-base-class.cpp b/test/SemaCXX/designated-initializers-base-class.cpp
new file mode 100644
index 0000000..9c2e61e
--- /dev/null
+++ b/test/SemaCXX/designated-initializers-base-class.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -std=c++1z -fsyntax-only -verify -Winitializer-overrides
+// expected-no-diagnostics
+
+struct B {
+  int x;
+};
+
+struct D : B {
+  int y;
+};
+
+void test() { D d = {1, .y = 2}; }
diff --git a/test/SemaCXX/enum-attr.cpp b/test/SemaCXX/enum-attr.cpp
new file mode 100644
index 0000000..7726aff
--- /dev/null
+++ b/test/SemaCXX/enum-attr.cpp
@@ -0,0 +1,108 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wassign-enum -Wswitch-enum -Wcovered-switch-default -std=c++11 %s
+
+enum Enum {
+  A0 = 1, A1 = 10
+};
+
+enum __attribute__((enum_extensibility(closed))) EnumClosed {
+  B0 = 1, B1 = 10
+};
+
+enum [[clang::enum_extensibility(open)]] EnumOpen {
+  C0 = 1, C1 = 10
+};
+
+enum __attribute__((flag_enum)) EnumFlag {
+  D0 = 1, D1 = 8
+};
+
+enum __attribute__((flag_enum,enum_extensibility(closed))) EnumFlagClosed {
+  E0 = 1, E1 = 8
+};
+
+enum __attribute__((flag_enum,enum_extensibility(open))) EnumFlagOpen {
+  F0 = 1, F1 = 8
+};
+
+void test() {
+  enum Enum t0;
+
+  switch (t0) { // expected-warning{{enumeration value 'A1' not handled in switch}}
+  case A0: break;
+  case 16: break; // expected-warning{{case value not in enumerated type}}
+  }
+
+  switch (t0) {
+  case A0: break;
+  case A1: break;
+  default: break; // expected-warning{{default label in switch which covers all enumeration}}
+  }
+
+  enum EnumClosed t1;
+
+  switch (t1) { // expected-warning{{enumeration value 'B1' not handled in switch}}
+  case B0: break;
+  case 16: break; // expected-warning{{case value not in enumerated type}}
+  }
+
+  switch (t1) {
+  case B0: break;
+  case B1: break;
+  default: break; // expected-warning{{default label in switch which covers all enumeration}}
+  }
+
+  enum EnumOpen t2;
+
+  switch (t2) { // expected-warning{{enumeration value 'C1' not handled in switch}}
+  case C0: break;
+  case 16: break;
+  }
+
+  switch (t2) {
+  case C0: break;
+  case C1: break;
+  default: break;
+  }
+
+  enum EnumFlag t3;
+
+  switch (t3) { // expected-warning{{enumeration value 'D1' not handled in switch}}
+  case D0: break;
+  case 9: break;
+  case 16: break; // expected-warning{{case value not in enumerated type}}
+  }
+
+  switch (t3) {
+  case D0: break;
+  case D1: break;
+  default: break;
+  }
+
+  enum EnumFlagClosed t4;
+
+  switch (t4) { // expected-warning{{enumeration value 'E1' not handled in switch}}
+  case E0: break;
+  case 9: break;
+  case 16: break; // expected-warning{{case value not in enumerated type}}
+  }
+
+  switch (t4) {
+  case E0: break;
+  case E1: break;
+  default: break;
+  }
+
+  enum EnumFlagOpen t5;
+
+  switch (t5) { // expected-warning{{enumeration value 'F1' not handled in switch}}
+  case F0: break;
+  case 9: break;
+  case 16: break;
+  }
+
+  switch (t5) {
+  case F0: break;
+  case F1: break;
+  default: break;
+  }
+}
diff --git a/test/SemaCXX/modules-ts.cppm b/test/SemaCXX/modules-ts.cppm
index 71c09d3..b4ee673 100644
--- a/test/SemaCXX/modules-ts.cppm
+++ b/test/SemaCXX/modules-ts.cppm
@@ -18,7 +18,8 @@
 int n;
 #if TEST == 3
 // expected-error@-2 {{redefinition of '}}
-// expected-note@-3 {{previous}}
+// expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}}
+// expected-note@modules-ts.cppm:1 {{included multiple times, additional include site here}}
 #endif
 
 #if TEST == 0
diff --git a/test/SemaCXX/pseudo-destructors.cpp b/test/SemaCXX/pseudo-destructors.cpp
index 45f1eaf..bc0d7b2 100644
--- a/test/SemaCXX/pseudo-destructors.cpp
+++ b/test/SemaCXX/pseudo-destructors.cpp
@@ -89,3 +89,26 @@
 void AliasTemplate(int *p) {
   p->~Id<int>();
 }
+
+namespace dotPointerAccess {
+struct Base {
+  virtual ~Base() {}
+};
+
+struct Derived : Base {
+  ~Derived() {}
+};
+
+void test() {
+  Derived d;
+  static_cast<Base *>(&d).~Base(); // expected-error {{member reference type 'dotPointerAccess::Base *' is a pointer; did you mean to use '->'}}
+  d->~Derived(); // expected-error {{member reference type 'dotPointerAccess::Derived' is not a pointer; did you mean to use '.'}}
+}
+
+typedef Derived *Foo;
+
+void test2(Foo d) {
+  d.~Foo(); // This is ok
+  d.~Derived(); // expected-error {{member reference type 'Foo' (aka 'dotPointerAccess::Derived *') is a pointer; did you mean to use '->'}}
+}
+}
diff --git a/test/SemaCXX/template-multiple-attr-propagation.cpp b/test/SemaCXX/template-multiple-attr-propagation.cpp
new file mode 100644
index 0000000..8e7f457
--- /dev/null
+++ b/test/SemaCXX/template-multiple-attr-propagation.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 %s -Wthread-safety-analysis -verify -fexceptions
+// expected-no-diagnostics
+
+class Mutex {
+public:
+  void Lock() __attribute__((exclusive_lock_function()));
+  void Unlock() __attribute__((unlock_function()));
+};
+
+class A {
+public:
+  Mutex mu1, mu2;
+
+  void foo() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {}
+
+  template <class T>
+  void bar() __attribute__((exclusive_locks_required(mu1))) __attribute__((exclusive_locks_required(mu2))) {
+    foo();
+  }
+};
+
+void f() {
+  A a;
+  a.mu1.Lock();
+  a.mu2.Lock();
+  a.bar<int>();
+  a.mu2.Unlock();
+  a.mu1.Unlock();
+}
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 48597de..c59ee61 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -679,3 +679,30 @@
       sizeof(c0is0)]; // expected-error {{use of undeclared identifier}}
 };
 }
+
+namespace avoidRedundantRedefinitionErrors {
+class Class {
+  void function(int pid); // expected-note {{'function' declared here}}
+};
+
+void Class::function2(int pid) { // expected-error {{out-of-line definition of 'function2' does not match any declaration in 'avoidRedundantRedefinitionErrors::Class'; did you mean 'function'?}}
+}
+
+// Expected no redefinition error here.
+void Class::function(int pid) { // expected-note {{previous definition is here}}
+}
+
+void Class::function(int pid) { // expected-error {{redefinition of 'function'}}
+}
+
+namespace ns {
+void create_test(); // expected-note {{'create_test' declared here}}
+}
+
+void ns::create_test2() { // expected-error {{out-of-line definition of 'create_test2' does not match any declaration in namespace 'avoidRedundantRedefinitionErrors::ns'; did you mean 'create_test'?}}
+}
+
+// Expected no redefinition error here.
+void ns::create_test() {
+}
+}
diff --git a/test/SemaObjC/arc-peformselector.m b/test/SemaObjC/arc-peformselector.m
index dec09e3..a7e5d3e 100644
--- a/test/SemaObjC/arc-peformselector.m
+++ b/test/SemaObjC/arc-peformselector.m
@@ -8,6 +8,7 @@
 - (id) init __attribute__((ns_returns_not_retained));
 - (id)PlusZero;
 - (id)PlusOne __attribute__((ns_returns_retained)); // expected-note {{method 'PlusOne' declared here}}
+- (id)self;
 @end
 
 @interface I : NSObject
@@ -17,6 +18,9 @@
 - (id)performSelector:(SEL)aSelector;
 - (id)performSelector:(SEL)aSelector withObject:(id)object;
 - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
+
+- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(double)delay inModes:(I *)modes;
+
 @end
 
 @implementation I
@@ -27,12 +31,20 @@
   return [self performSelector : @selector(init)];
   return [self performSelector : sel1]; // expected-warning {{performSelector may cause a leak because its selector is unknown}} \
 					// expected-note {{used here}}
+  return [self performSelector: (@selector(PlusZero))];
 
   return [self performSelector : @selector(PlusZero)];
   return [self performSelector : @selector(PlusOne)]; // expected-error {{performSelector names a selector which retains the object}}
+
+  // Avoid the unkown selector warning for more complicated performSelector
+  // variations because it produces too many false positives.
+  [self performSelector: sel1 withObject:0 afterDelay:0 inModes:0];
+
+  return [self performSelector: @selector(self)]; // No error, -self is not +1!
 }
 
 - (id)performSelector:(SEL)aSelector { return 0; }
 - (id)performSelector:(SEL)aSelector withObject:(id)object { return 0; }
 - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2 { return 0; }
+- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(double)delay inModes:(I *)modes { }
 @end
diff --git a/test/SemaObjC/arc-repeated-weak.mm b/test/SemaObjC/arc-repeated-weak.mm
index 11161a0..37b2123 100644
--- a/test/SemaObjC/arc-repeated-weak.mm
+++ b/test/SemaObjC/arc-repeated-weak.mm
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
 
 @interface Test {
 @public
@@ -445,8 +446,8 @@
 @class NSString;
 @interface NSBundle
 +(NSBundle *)foo;
-@property (class) NSBundle *foo2;
-@property NSString *prop;
+@property (class, strong) NSBundle *foo2;
+@property (strong) NSString *prop;
 @property(weak) NSString *weakProp;
 @end
 
@@ -462,3 +463,19 @@
   use(NSBundle.foo2.weakProp); // expected-warning{{weak property 'weakProp' may be accessed multiple times}}
   use(NSBundle2.foo2.weakProp); // expected-note{{also accessed here}}
 }
+
+// This used to crash in the constructor of WeakObjectProfileTy when a
+// DeclRefExpr was passed that didn't reference a VarDecl.
+
+typedef INTF * INTFPtrTy;
+
+enum E {
+  e1
+};
+
+void foo1() {
+  INTFPtrTy tmp = (INTFPtrTy)e1;
+#if __has_feature(objc_arc)
+// expected-error@-2{{cast of 'E' to 'INTFPtrTy' (aka 'INTF *') is disallowed with ARC}}
+#endif
+}
diff --git a/test/SemaObjC/arc-unavailable-for-weakref.m b/test/SemaObjC/arc-unavailable-for-weakref.m
index 8274802..c596168 100644
--- a/test/SemaObjC/arc-unavailable-for-weakref.m
+++ b/test/SemaObjC/arc-unavailable-for-weakref.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-weak -verify -Wno-objc-root-class %s
 // rdar://9693477
 
 __attribute__((objc_arc_weak_reference_unavailable))
diff --git a/test/SemaObjC/arc.m b/test/SemaObjC/arc.m
index f463bb0..e90d0a8 100644
--- a/test/SemaObjC/arc.m
+++ b/test/SemaObjC/arc.m
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class -Wblock-capture-autoreleasing %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -verify -Wno-objc-root-class %s
+// RUN: not %clang_cc1 -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -fblocks -Wno-objc-root-class -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 typedef unsigned long NSUInteger;
 typedef const void * CFTypeRef;
@@ -809,9 +810,36 @@
   TKAssertEqual(object, (id)nil);
 }
 
-void block_capture_autoreleasing(A * __autoreleasing *a, A **b) { // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+void block_capture_autoreleasing(A * __autoreleasing *a,
+                                 A **b, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 A * _Nullable *c, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 A * _Nullable __autoreleasing *d,
+                                 A ** _Nullable e, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 A * __autoreleasing * _Nullable f,
+                                 id __autoreleasing *g,
+                                 id *h, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 id _Nullable *i, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 id _Nullable __autoreleasing *j,
+                                 id * _Nullable k, // expected-note {{declare the parameter __autoreleasing explicitly to suppress this warning}} expected-note {{declare the parameter __strong or capture a __block __strong variable to keep values alive across autorelease pools}}
+                                 id __autoreleasing * _Nullable l) {
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:37-[[@LINE-11]]:37}:" __autoreleasing "
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-11]]:47-[[@LINE-11]]:47}:" __autoreleasing"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-10]]:37-[[@LINE-10]]:37}:" __autoreleasing "
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:36-[[@LINE-8]]:36}:" __autoreleasing"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-8]]:46-[[@LINE-8]]:46}:" __autoreleasing"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-7]]:36-[[@LINE-7]]:36}:" __autoreleasing"
   ^{
     (void)*a;
     (void)*b; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*c; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*d;
+    (void)*e; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*f;
+    (void)*g;
+    (void)*h; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*i; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*j;
+    (void)*k; // expected-warning {{block captures an autoreleasing out-parameter, which may result in use-after-free bugs}}
+    (void)*l;
   }();
 }
diff --git a/test/SemaObjC/attr-deprecated.m b/test/SemaObjC/attr-deprecated.m
index 59087bd..b061385 100644
--- a/test/SemaObjC/attr-deprecated.m
+++ b/test/SemaObjC/attr-deprecated.m
@@ -83,8 +83,8 @@
 }
 
 
-__attribute ((deprecated))  
-@interface DEPRECATED { // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}}
+__attribute ((deprecated)) // expected-note 2 {{'DEPRECATED' has been explicitly marked deprecated here}}
+@interface DEPRECATED { 
   @public int ivar; 
   DEPRECATED *ivar2; // no warning.
 } 
@@ -121,9 +121,15 @@
 }
 
 __attribute__((deprecated))
-@interface A(Blah) // expected-error{{attributes may not be specified on a category}}
+@interface A(Blah) // no warning
+- (A*)getA;
 @end
 
+@implementation A(Blah) // Don't warn by default
+- (A*)getA {
+  return self;
+}
+@end
 
 typedef struct {
 	int x;
diff --git a/test/SemaObjC/attr-swift.m b/test/SemaObjC/attr-swift.m
new file mode 100644
index 0000000..bdcbbd0
--- /dev/null
+++ b/test/SemaObjC/attr-swift.m
@@ -0,0 +1,217 @@
+// RUN: %clang_cc1 -verify -fsyntax-only -fobjc-arc -fblocks %s
+
+// --- swift_private ---
+
+__attribute__((swift_private))
+@protocol FooProto
+@end
+
+__attribute__((swift_private))
+@interface Foo
+@end
+
+@interface Bar
+@property id prop __attribute__((swift_private));
+- (void)instMethod __attribute__((swift_private));
++ (instancetype)bar __attribute__((swift_private));
+@end
+
+void function(id) __attribute__((swift_private));
+
+struct __attribute__((swift_private)) Point {
+  int x;
+  int y;
+};
+
+enum __attribute__((swift_private)) Colors {
+  Red, Green, Blue
+};
+
+typedef struct {
+  float x, y, z;
+} Point3D __attribute__((swift_private));
+
+
+// --- swift_name ---
+
+__attribute__((swift_name("SNFooType")))
+@protocol SNFoo
+@end
+
+__attribute__((swift_name("SNFooClass")))
+@interface SNFoo <SNFoo>
+- (instancetype)init __attribute__((swift_name("init()")));
+- (instancetype)initWithValue:(int)value __attribute__((swift_name("fooWithValue(_:)")));
+
++ (void)refresh __attribute__((swift_name("refresh()")));
+
++ (instancetype)foo __attribute__((swift_name("foo()")));
++ (SNFoo *)fooWithValue:(int)value __attribute__((swift_name("foo(value:)")));
++ (SNFoo *)fooWithValue:(int)value value:(int)value2 __attribute__((swift_name("foo(value:extra:)")));
++ (SNFoo *)fooWithConvertingValue:(int)value value:(int)value2 __attribute__((swift_name("init(_:extra:)")));
+
++ (SNFoo *)fooWithOtherValue:(int)value __attribute__((swift_name("init"))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}}
++ (SNFoo *)fooWithAnotherValue:(int)value __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
++ (SNFoo *)fooWithYetAnotherValue:(int)value __attribute__((swift_name("foo(value:extra:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 1; got 2)}}
+
++ (SNFoo *)fooAndReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo()"))); // no-warning
++ (SNFoo *)fooWithValue:(int)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo(value:)"))); // no-warning
++ (SNFoo *)fooFromErrorCode:(const int *)errorCode __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
++ (SNFoo *)fooWithValue:(int)value fromErrorCode:(const int *)errorCode __attribute__((swift_name("foo(value:)"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 2; got 1)}}
++ (SNFoo *)fooWithPointerA:(int *)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo()"))); // no-warning
++ (SNFoo *)fooWithPointerB:(int *)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo(pointer:)"))); // no-warning
++ (SNFoo *)fooWithPointerC:(int *)value andReturnErrorCode:(int *)errorCode __attribute__((swift_name("foo(pointer:errorCode:)"))); // no-warning
++ (SNFoo *)fooWithOtherFoo:(SNFoo *)other __attribute__((swift_name("foo()"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
+
++ (instancetype)specialFoo __attribute__((swift_name("init(options:)")));
++ (instancetype)specialBar __attribute__((swift_name("init(options:extra:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 2)}}
++ (instancetype)specialBaz __attribute__((swift_name("init(_:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 1)}}
++ (instancetype)specialGarply __attribute__((swift_name("foo(options:)"))); // expected-warning {{too many parameters in 'swift_name' attribute (expected 0; got 1)}}
+
++ (instancetype)trailingParen __attribute__((swift_name("foo("))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}}
++ (instancetype)trailingColon:(int)value __attribute__((swift_name("foo(value)"))); // expected-warning {{parameter of 'swift_name' attribute must be a Swift function name string}}
++ (instancetype)initialIgnore:(int)value __attribute__((swift_name("_(value:)"))); // expected-warning {{'swift_name' attribute has invalid identifier for base name}}
++ (instancetype)middleOmitted:(int)value __attribute__((swift_name("foo(:)"))); // expected-warning {{'swift_name' attribute has invalid identifier for parameter name}}
+
+@property(strong) id someProp __attribute__((swift_name("prop")));
+@end
+
+enum __attribute__((swift_name("MoreColors"))) MoreColors {
+  Cyan,
+  Magenta,
+  Yellow __attribute__((swift_name("RoseGold"))),
+  Black __attribute__((swift_name("SpaceGrey()"))) // expected-warning {{'swift_name' attribute has invalid identifier for base name}}
+};
+
+struct __attribute__((swift_name("FooStruct"))) BarStruct {
+  int x, y, z __attribute__((swift_name("zed")));
+};
+
+int global_int __attribute__((swift_name("GlobalInt")));
+
+void foo1(int i) __attribute__((swift_name("foo"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+void foo2(int i) __attribute__((swift_name("foo()"))); // expected-warning{{too few parameters in 'swift_name' attribute (expected 1; got 0)}}
+void foo2(int i) __attribute__((swift_name("foo(a:b:)"))); // expected-warning{{too many parameters in 'swift_name' attribute (expected 1; got 2)}}
+void foo3(int i, int j) __attribute__((swift_name("fooWithX(_:y:)"))); // okay
+void foo4(int i, int *error) __attribute__((swift_name("fooWithA(_:)"))); // okay
+
+typedef int some_int_type __attribute__((swift_name("SomeInt")));
+
+struct Point3D createPoint3D(float x, float y, float z) __attribute__((swift_name("Point3D.init(x:y:z:)")));
+struct Point3D rotatePoint3D(Point3D point, float radians) __attribute__((swift_name("Point3D.rotate(self:radians:)")));
+struct Point3D badRotatePoint3D(Point3D point, float radians) __attribute__((swift_name("Point3D.rotate(radians:)"))); // expected-warning {{too few parameters in 'swift_name' attribute (expected 2; got 1)}}
+
+extern struct Point3D identityPoint __attribute__((swift_name("Point3D.identity")));
+
+// Getters and setters.
+float Point3DGetMagnitude(Point3D point) __attribute__((swift_name("getter:Point3D.magnitude(self:)")));
+
+float Point3DGetMagnitudeAndSomethingElse(Point3D point, float wat) __attribute__((swift_name("getter:Point3D.magnitude(self:wat:)"))); // expected-warning {{'swift_name' attribute for getter must not take any parameters besides 'self:'}}
+
+float Point3DGetRadius(Point3D point) __attribute__((swift_name("getter:Point3D.radius(self:)")));
+void Point3DSetRadius(Point3D point, float radius) __attribute__((swift_name("setter:Point3D.radius(self:newValue:)")));
+
+float Point3DPreGetRadius(Point3D point) __attribute__((swift_name("getter:Point3D.preRadius(self:)")));
+void Point3DPreSetRadius(float radius, Point3D point) __attribute__((swift_name("setter:Point3D.preRadius(newValue:self:)")));
+
+void Point3DSetRadiusAndSomethingElse(Point3D point, float radius, float wat) __attribute__((swift_name("setter:Point3D.radius(self:newValue:wat:)"))); // expected-warning {{'swift_name' attribute for setter must take one parameter for new value}}
+
+float Point3DGetComponent(Point3D point, unsigned index) __attribute__((swift_name("getter:Point3D.subscript(self:_:)")));
+float Point3DSetComponent(Point3D point, unsigned index, float value) __attribute__((swift_name("setter:Point3D.subscript(self:_:newValue:)")));
+
+float Point3DGetMatrixComponent(Point3D point, unsigned x, unsigned y) __attribute__((swift_name("getter:Point3D.subscript(self:x:y:)")));
+void Point3DSetMatrixComponent(Point3D point, unsigned x, float value, unsigned y) __attribute__((swift_name("setter:Point3D.subscript(self:x:newValue:y:)")));
+
+float Point3DSetWithoutNewValue(Point3D point, unsigned x, unsigned y) __attribute__((swift_name("setter:Point3D.subscript(self:x:y:)"))); // expected-warning {{'swift_name' attribute for 'subscript' setter must take a 'newValue:' parameter}}
+
+float Point3DSubscriptButNotGetterSetter(Point3D point, unsigned x) __attribute__((swift_name("Point3D.subscript(self:_:)"))); // expected-warning {{'swift_name' attribute for 'subscript' must be a getter or setter}}
+
+void Point3DSubscriptSetterTwoNewValues(Point3D point, unsigned x, float a, float b) __attribute__((swift_name("setter:Point3D.subscript(self:_:newValue:newValue:)"))); // expected-warning {{'swift_name' attribute for 'subscript' setter cannot take multiple 'newValue:' parameters}}
+float Point3DSubscriptGetterNewValue(Point3D point, unsigned x, float a, float b) __attribute__((swift_name("getter:Point3D.subscript(self:_:newValue:newValue:)"))); // expected-warning {{'swift_name' attribute for 'subscript' getter cannot take a 'newValue:' parameter}}
+
+void Point3DMethodWithNewValue(Point3D point, float newValue) __attribute__((swift_name("Point3D.method(self:newValue:)")));
+void Point3DMethodWithNewValues(Point3D point, float newValue, float newValueB) __attribute__((swift_name("Point3D.method(self:newValue:newValue:)")));
+
+float Point3DStaticSubscript(unsigned x) __attribute__((swift_name("getter:Point3D.subscript(_:)"))); // expected-warning {{'swift_name' attribute for 'subscript' must take a 'self:' parameter}}
+float Point3DStaticSubscriptNoArgs(void) __attribute__((swift_name("getter:Point3D.subscript()"))); // expected-warning {{'swift_name' attribute for 'subscript' must take at least one parameter}}
+
+float Point3DPreGetComponent(Point3D point, unsigned index) __attribute__((swift_name("getter:Point3D.subscript(self:_:)")));
+
+Point3D getCurrentPoint3D(void) __attribute__((swift_name("getter:currentPoint3D()")));
+
+void setCurrentPoint3D(Point3D point) __attribute__((swift_name("setter:currentPoint3D(newValue:)")));
+
+Point3D getLastPoint3D(void) __attribute__((swift_name("getter:lastPoint3D()")));
+
+void setLastPoint3D(Point3D point) __attribute__((swift_name("setter:lastPoint3D(newValue:)")));
+
+Point3D getZeroPoint(void) __attribute__((swift_name("getter:Point3D.zero()")));
+Point3D getZeroPointNoPrototype() __attribute__((swift_name("getter:Point3D.zeroNoPrototype()"))); // expected-warning{{'swift_name' attribute can only be applied to function declarations with prototypes}}
+void setZeroPoint(Point3D point) __attribute__((swift_name("setter:Point3D.zero(newValue:)")));
+
+Point3D badGetter1(int x) __attribute__((swift_name("getter:bad1(_:))"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+void badSetter1(void) __attribute__((swift_name("getter:bad1())"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+
+Point3D badGetter2(Point3D point) __attribute__((swift_name("getter:bad2(_:))"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+
+void badSetter2(Point3D point) __attribute__((swift_name("setter:bad2(self:))"))); // expected-warning{{parameter of 'swift_name' attribute must be a Swift function name string}}
+
+// --- swift_error ---
+
+@class NSError;
+
+typedef struct __attribute__((objc_bridge(NSError))) __CFError *CFErrorRef;
+
+@interface Erroneous
+- (_Bool) tom0: (NSError**) err __attribute__((swift_error(none)));
+- (_Bool) tom1: (NSError**) err __attribute__((swift_error(nonnull_error)));
+- (_Bool) tom2: (NSError**) err __attribute__((swift_error(null_result))); // expected-error {{'swift_error' attribute with 'null_result' convention can only be applied to a method returning a pointer}}
+- (_Bool) tom3: (NSError**) err __attribute__((swift_error(nonzero_result)));
+- (_Bool) tom4: (NSError**) err __attribute__((swift_error(zero_result)));
+
+- (Undeclared) richard0: (NSError**) err __attribute__((swift_error(none))); // expected-error {{expected a type}}
+- (Undeclared) richard1: (NSError**) err __attribute__((swift_error(nonnull_error))); // expected-error {{expected a type}}
+- (Undeclared) richard2: (NSError**) err __attribute__((swift_error(null_result))); // expected-error {{expected a type}}
+// FIXME: the follow-on warnings should really be suppressed, but apparently having an ill-formed return type doesn't mark anything as invalid
+- (Undeclared) richard3: (NSError**) err __attribute__((swift_error(nonzero_result))); // expected-error {{expected a type}} expected-error {{can only be applied}}
+- (Undeclared) richard4: (NSError**) err __attribute__((swift_error(zero_result))); // expected-error {{expected a type}} expected-error {{can only be applied}}
+
+- (instancetype) harry0: (NSError**) err __attribute__((swift_error(none)));
+- (instancetype) harry1: (NSError**) err __attribute__((swift_error(nonnull_error)));
+- (instancetype) harry2: (NSError**) err __attribute__((swift_error(null_result)));
+- (instancetype) harry3: (NSError**) err __attribute__((swift_error(nonzero_result))); // expected-error {{'swift_error' attribute with 'nonzero_result' convention can only be applied to a method returning an integral type}}
+- (instancetype) harry4: (NSError**) err __attribute__((swift_error(zero_result))); // expected-error {{'swift_error' attribute with 'zero_result' convention can only be applied to a method returning an integral type}}
+
+- (instancetype) harry0 __attribute__((swift_error(none)));
+- (instancetype) harry1 __attribute__((swift_error(nonnull_error))); // expected-error {{'swift_error' attribute can only be applied to a method with an error parameter}}
+- (instancetype) harry2 __attribute__((swift_error(null_result))); // expected-error {{'swift_error' attribute can only be applied to a method with an error parameter}}
+- (instancetype) harry3 __attribute__((swift_error(nonzero_result))); // expected-error {{'swift_error' attribute can only be applied to a method with an error parameter}}
+- (instancetype) harry4 __attribute__((swift_error(zero_result))); // expected-error {{'swift_error' attribute can only be applied to a method with an error parameter}}
+@end
+
+extern _Bool tom0(CFErrorRef *) __attribute__((swift_error(none)));
+extern _Bool tom1(CFErrorRef *) __attribute__((swift_error(nonnull_error)));
+extern _Bool tom2(CFErrorRef *) __attribute__((swift_error(null_result))); // expected-error {{'swift_error' attribute with 'null_result' convention can only be applied to a function returning a pointer}}
+extern _Bool tom3(CFErrorRef *) __attribute__((swift_error(nonzero_result)));
+extern _Bool tom4(CFErrorRef *) __attribute__((swift_error(zero_result)));
+
+extern Undeclared richard0(CFErrorRef *) __attribute__((swift_error(none))); // expected-error {{unknown type name 'Undeclared'}}
+extern Undeclared richard1(CFErrorRef *) __attribute__((swift_error(nonnull_error))); // expected-error {{unknown type name 'Undeclared'}}
+extern Undeclared richard2(CFErrorRef *) __attribute__((swift_error(null_result))); // expected-error {{unknown type name 'Undeclared'}}
+extern Undeclared richard3(CFErrorRef *) __attribute__((swift_error(nonzero_result))); // expected-error {{unknown type name 'Undeclared'}}
+extern Undeclared richard4(CFErrorRef *) __attribute__((swift_error(zero_result))); // expected-error {{unknown type name 'Undeclared'}}
+
+extern void *harry0(CFErrorRef *) __attribute__((swift_error(none)));
+extern void *harry1(CFErrorRef *) __attribute__((swift_error(nonnull_error)));
+extern void *harry2(CFErrorRef *) __attribute__((swift_error(null_result)));
+extern void *harry3(CFErrorRef *) __attribute__((swift_error(nonzero_result))); // expected-error {{'swift_error' attribute with 'nonzero_result' convention can only be applied to a function returning an integral type}}
+extern void *harry4(CFErrorRef *) __attribute__((swift_error(zero_result))); // expected-error {{'swift_error' attribute with 'zero_result' convention can only be applied to a function returning an integral type}}
+
+extern void *wilma0(void) __attribute__((swift_error(none)));
+extern void *wilma1(void) __attribute__((swift_error(nonnull_error))); // expected-error {{'swift_error' attribute can only be applied to a function with an error parameter}}
+extern void *wilma2(void) __attribute__((swift_error(null_result))); // expected-error {{'swift_error' attribute can only be applied to a function with an error parameter}}
+extern void *wilma3(void) __attribute__((swift_error(nonzero_result))); // expected-error {{'swift_error' attribute can only be applied to a function with an error parameter}}
+extern void *wilma4(void) __attribute__((swift_error(zero_result))); // expected-error {{'swift_error' attribute can only be applied to a function with an error parameter}}
+
+
+extern _Bool suzanne __attribute__((swift_error(none))); // expected-error {{'swift_error' attribute only applies to functions and methods}}
diff --git a/test/SemaObjC/attr-swift_newtype.c b/test/SemaObjC/attr-swift_newtype.c
new file mode 100644
index 0000000..61e4d89
--- /dev/null
+++ b/test/SemaObjC/attr-swift_newtype.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+typedef int T1 __attribute__((swift_newtype(struct)));
+typedef int T2 __attribute__((swift_newtype(enum)));
+
+typedef int T3 __attribute__((swift_wrapper(struct)));
+typedef int T4 __attribute__((swift_wrapper(enum)));
+
+
+typedef int Bad1 __attribute__((swift_newtype(bad))); // expected-warning{{'swift_newtype' attribute argument not supported: 'bad'}}
+typedef int Bad2 __attribute__((swift_newtype())); // expected-error{{argument required after attribute}}
+typedef int Bad3 __attribute__((swift_newtype(bad, badder)));
+  // expected-error@-1{{expected ')'}}
+  // expected-note@-2{{to match this '('}}
+  // expected-warning@-3{{'swift_newtype' attribute argument not supported: 'bad'}}
+
+
+// TODO: better error message below
+// FIXME: why is this a parse error, rather than Sema error triggering?
+struct Bad4 __attribute__((swift_newtype(struct))) { }; // expected-error{{expected identifier or '('}}
diff --git a/test/SemaObjC/attr-swift_objc_members.m b/test/SemaObjC/attr-swift_objc_members.m
new file mode 100644
index 0000000..c8781f8
--- /dev/null
+++ b/test/SemaObjC/attr-swift_objc_members.m
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+#if !__has_attribute(swift_objc_members)
+#  error Cannot query presence of swift_objc_members attribute.
+#endif
+
+__attribute__((swift_objc_members))
+__attribute__((objc_root_class))
+@interface A
+@end
+
+__attribute__((swift_objc_members)) // expected-error{{'swift_objc_members' attribute only applies to Objective-C interfaces}}
+@protocol P
+@end
+
+__attribute__((swift_objc_members)) // expected-error{{'swift_objc_members' attribute only applies to Objective-C interfaces}}
+extern void foo(void);
diff --git a/test/SemaObjC/category-attribute.m b/test/SemaObjC/category-attribute.m
new file mode 100644
index 0000000..7efe3df
--- /dev/null
+++ b/test/SemaObjC/category-attribute.m
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s
+// expected-no-diagnostics
+
+__attribute__ ((external_source_symbol(language= "Swift", defined_in="A")))
+@interface TestInterface
+@end
+// CHECK: ObjCInterfaceDecl {{.*}} TestInterface
+// CHECK-NEXT: ExternalSourceSymbolAttr
+
+__attribute__ ((external_source_symbol(language= "Swift", defined_in="B")))
+@interface TestInterface ()
+@end
+// CHECK: ObjCCategoryDecl
+// CHECK-NEXT: ObjCInterface
+// CHECK-NEXT: ExternalSourceSymbolAttr {{.*}} "Swift" "B"
+
+__attribute__ ((external_source_symbol(language= "Swift", defined_in="C")))
+@interface TestInterface (Category)
+@end
+// CHECK: ObjCCategoryDecl
+// CHECK-NEXT: ObjCInterface
+// CHECK-NEXT: ExternalSourceSymbolAttr {{.*}} "Swift" "C"
diff --git a/test/SemaObjC/class-message-protocol-lookup.m b/test/SemaObjC/class-message-protocol-lookup.m
index 37df7a6..d9f954d 100644
--- a/test/SemaObjC/class-message-protocol-lookup.m
+++ b/test/SemaObjC/class-message-protocol-lookup.m
@@ -32,3 +32,30 @@
     Class<Test2Protocol> c2 = [c2 alloc]; //  ok
     return 0;
 }
+
+// rdar://22812517
+
+@protocol NSObject
+
+- (int)respondsToSelector:(SEL)aSelector;
+
+@end
+
+__attribute__((objc_root_class))
+@interface NSObject <NSObject>
+
+@end
+
+@protocol OtherProto
+
+- (void)otherInstanceMethod; // expected-note {{method 'otherInstanceMethod' declared here}}
+
+@end
+
+@protocol MyProto <NSObject, OtherProto>
+@end
+
+void allowInstanceMethodsFromRootProtocols(Class<MyProto> c) {
+  [c respondsToSelector: @selector(instanceMethod)]; // no warning
+  [c otherInstanceMethod]; //  expected-warning {{instance method 'otherInstanceMethod' found instead of class method 'otherInstanceMethod'}}
+}
diff --git a/test/SemaObjC/default-synthesize-3.m b/test/SemaObjC/default-synthesize-3.m
index dce9eda..fe2b35f 100644
--- a/test/SemaObjC/default-synthesize-3.m
+++ b/test/SemaObjC/default-synthesize-3.m
@@ -33,8 +33,8 @@
 - (id) DeepMustSynthProperty { return 0; }
 @end
 
-__attribute ((objc_requires_property_definitions)) 
-@interface Deep(CAT)  // expected-error {{attributes may not be specified on a category}}
+__attribute ((objc_requires_property_definitions)) // expected-error {{'objc_requires_property_definitions' attribute only applies to Objective-C interfaces}}
+@interface Deep(CAT)
 @end
 
 __attribute ((objc_requires_property_definitions)) // expected-error {{'objc_requires_property_definitions' attribute only applies to Objective-C interfaces}}
diff --git a/test/SemaObjC/diagnose_if.m b/test/SemaObjC/diagnose_if.m
new file mode 100644
index 0000000..9f281e4
--- /dev/null
+++ b/test/SemaObjC/diagnose_if.m
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -verify -fno-builtin
+
+_Static_assert(__has_feature(attribute_diagnose_if_objc), "feature check failed?");
+
+#define _diagnose_if(...) __attribute__((diagnose_if(__VA_ARGS__)))
+
+@interface I
+-(void)meth _diagnose_if(1, "don't use this", "warning"); // expected-note 1{{from 'diagnose_if'}}
+@property (assign) id prop _diagnose_if(1, "don't use this", "warning"); // expected-note 2{{from 'diagnose_if'}}
+@end
+
+void test(I *i) {
+  [i meth]; // expected-warning {{don't use this}}
+  id o1 = i.prop; // expected-warning {{don't use this}}
+  id o2 = [i prop]; // expected-warning {{don't use this}}
+}
diff --git a/test/SemaObjC/foreach.m b/test/SemaObjC/foreach.m
index 91ea2ec..477c4fc 100644
--- a/test/SemaObjC/foreach.m
+++ b/test/SemaObjC/foreach.m
@@ -55,3 +55,27 @@
   for (obj.prop in collection) { /* expected-error {{selector element is not a valid lvalue}} */
   }
 }
+
+int cond();
+
+void test3(NSObject<NSFastEnumeration> *a0, NSObject<NSFastEnumeration> *a1) {
+  for (id i in a0) { /* expected-note 2 {{jump enters Objective-C fast enumeration loop}} */
+    for (id j in a1) { /* expected-note 2 {{jump enters Objective-C fast enumeration loop}} */
+      (void)i, (void)j;
+label0:
+      if (cond())
+        goto label1;
+    }
+label1:
+    if (cond())
+      goto label0; /* expected-error {{cannot jump from this goto statement to its label}} */
+    if (cond())
+      goto label2;
+  }
+
+label2:
+  if (cond())
+    goto label0; /* expected-error {{cannot jump from this goto statement to its label}} */
+  if (cond())
+    goto label1; /* expected-error{{cannot jump from this goto statement to its label}} */
+}
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index 767d5ac..d5e3220 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -265,40 +265,17 @@
   NSLog(@"%2$[tt]@ %1$[tt]s", @"Foo", @"Bar"); // expected-warning {{object format flags cannot be used with 's' conversion specifier}}
 }
 
-// rdar://23622446
-@interface RD23622446_Tester: NSObject
+// Test os_log_format primitive with ObjC string literal format argument.
+void test_os_log_format(char c, const char *pc, int i, int *pi, void *p, void *buf, NSString *nss) {
+  __builtin_os_log_format(buf, @"");
+  __builtin_os_log_format(buf, @"%d"); // expected-warning {{more '%' conversions than data arguments}}
+  __builtin_os_log_format(buf, @"%d", i);
+  __builtin_os_log_format(buf, @"%P", p); // expected-warning {{using '%P' format specifier without precision}}
+  __builtin_os_log_format(buf, @"%.10P", p);
+  __builtin_os_log_format(buf, @"%.*P", p); // expected-warning {{field precision should have type 'int', but argument has type 'void *'}}
+  __builtin_os_log_format(buf, @"%.*P", i, p);
+  __builtin_os_log_format(buf, @"%.*P", i, i); // expected-warning {{format specifies type 'void *' but the argument has type 'int'}}
 
-+ (void)stringWithFormat:(const char *)format, ... __attribute__((format(__printf__, 1, 2)));
-
-@end
-
-@implementation RD23622446_Tester
-
-__attribute__ ((format_arg(1)))
-const char *rd23622446(const char *format) {
-  return format;
+  __builtin_os_log_format(buf, @"%{private}s", pc);
+  __builtin_os_log_format(buf, @"%@", nss);
 }
-
-+ (void)stringWithFormat:(const char *)format, ... {
-  return;
-}
-
-- (const char *)test:(const char *)format __attribute__ ((format_arg(1))) {
-  return format;
-}
-
-- (NSString *)str:(NSString *)format __attribute__ ((format_arg(1))) {
-  return format;
-}
-
-- (void)foo {
-  [RD23622446_Tester stringWithFormat:rd23622446("%u"), 1, 2]; // expected-warning {{data argument not used by format string}}
-  [RD23622446_Tester stringWithFormat:[self test: "%u"], 1, 2]; // expected-warning {{data argument not used by format string}}
-  [RD23622446_Tester stringWithFormat:[self test: "%s %s"], "name"]; // expected-warning {{more '%' conversions than data arguments}}
-  NSLog([self str: @"%@ %@"], @"name"); // expected-warning {{more '%' conversions than data arguments}}
-  [RD23622446_Tester stringWithFormat:rd23622446("%d"), 1]; // ok
-  [RD23622446_Tester stringWithFormat:[self test: "%d %d"], 1, 2]; // ok
-  NSLog([self str: @"%@"], @"string"); // ok
-}
-
-@end
diff --git a/test/SemaObjC/kindof.m b/test/SemaObjC/kindof.m
index 9d758d3..63ba18f 100644
--- a/test/SemaObjC/kindof.m
+++ b/test/SemaObjC/kindof.m
@@ -385,7 +385,7 @@
 @end
 
 @interface NSGeneric<ObjectType> : NSObject
-- (void)test:(__kindof ObjectType)T; // expected-note{{passing argument to parameter 'T' here}}
+- (void)test:(__kindof ObjectType)T;
 - (void)mapUsingBlock:(id (^)(__kindof ObjectType))block;
 @end
 @implementation NSGeneric
@@ -395,14 +395,6 @@
 }
 @end
 
-void testGeneric(NSGeneric<NSString*> *generic) {
-  NSObject *NSObject_obj;
-  // Assign from NSObject_obj to __kindof NSString*.
-  [generic test:NSObject_obj]; // expected-warning{{incompatible pointer types sending 'NSObject *' to parameter of type '__kindof NSString *'}}
-  NSString *NSString_str;
-  [generic test:NSString_str];
-}
-
 // Check that clang doesn't crash when a type parameter is illegal.
 @interface Array1<T> : NSObject
 @end
diff --git a/test/SemaObjC/parameterized_classes_subst.m b/test/SemaObjC/parameterized_classes_subst.m
index da2d56f..f90ee90 100644
--- a/test/SemaObjC/parameterized_classes_subst.m
+++ b/test/SemaObjC/parameterized_classes_subst.m
@@ -426,36 +426,3 @@
 // warning about likely protocol/class name typos.
 // --------------------------------------------------------------------------
 typedef NSArray<NSObject> ArrayOfNSObjectWarning; // expected-warning{{parameterized class 'NSArray' already conforms to the protocols listed; did you forget a '*'?}}
-
-// rdar://25060179
-@interface MyMutableDictionary<KeyType, ObjectType> : NSObject
-- (void)setObject:(ObjectType)obj forKeyedSubscript:(KeyType <NSCopying>)key; // expected-note{{passing argument to parameter 'obj' here}} \
-    // expected-note{{passing argument to parameter 'key' here}}
-@end
-
-void bar(MyMutableDictionary<NSString *, NSString *> *stringsByString,
-                             NSNumber *n1, NSNumber *n2) {
-  // We warn here when the key types do not match.
-  stringsByString[n1] = n2; // expected-warning{{incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString *'}} \
-    // expected-warning{{incompatible pointer types sending 'NSNumber *' to parameter of type 'NSString<NSCopying> *'}}
-}
-
-@interface MyTest<K, V> : NSObject <NSCopying>
-- (V)test:(K)key;
-- (V)test2:(K)key; // expected-note{{previous definition is here}}
-- (void)mapUsingBlock:(id (^)(V))block;
-- (void)mapUsingBlock2:(id (^)(V))block; // expected-note{{previous definition is here}}
-@end
-
-@implementation MyTest
-- (id)test:(id)key {
-  return key;
-}
-- (int)test2:(id)key{ // expected-warning{{conflicting return type in implementation}}
-  return 0;
-}
-- (void)mapUsingBlock:(id (^)(id))block {
-}
-- (void)mapUsingBlock2:(id)block { // expected-warning{{conflicting parameter types in implementation}}
-}
-@end
diff --git a/test/SemaObjC/property-typecheck-1.m b/test/SemaObjC/property-typecheck-1.m
index 5fb05c8..85e8d46 100644
--- a/test/SemaObjC/property-typecheck-1.m
+++ b/test/SemaObjC/property-typecheck-1.m
@@ -78,6 +78,11 @@
 
 - (NSMutableArray*) pieces; // expected-note 2 {{declared here}}
 - (NSArray*) first;
+
+// Don't warn about setter-like methods for readonly properties.
+- (void)setFirst:(char)val;
+- (void)setPieces:(char)val;
+
 @end
 
 @interface Class2  {
diff --git a/test/SemaObjC/special-dep-unavail-warning.m b/test/SemaObjC/special-dep-unavail-warning.m
index 9e16b33..b667c3c 100644
--- a/test/SemaObjC/special-dep-unavail-warning.m
+++ b/test/SemaObjC/special-dep-unavail-warning.m
@@ -44,8 +44,8 @@
 }
 
 // rdar://10268422
-__attribute ((deprecated))
-@interface DEPRECATED // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}}
+__attribute ((deprecated)) // expected-note {{'DEPRECATED' has been explicitly marked deprecated here}}
+@interface DEPRECATED 
 +(id)new;
 @end
 
diff --git a/test/SemaObjC/unguarded-availability.m b/test/SemaObjC/unguarded-availability.m
index 4369a0e..5febee0 100644
--- a/test/SemaObjC/unguarded-availability.m
+++ b/test/SemaObjC/unguarded-availability.m
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx-10.9 -Wunguarded-availability -fblocks -fsyntax-only -verify %s
-// RUN: %clang_cc1 -xobjective-c++ -DOBJCPP -triple x86_64-apple-macosx-10.9 -Wunguarded-availability -fblocks -fsyntax-only -verify %s
+// RUN: %clang_cc1 -xobjective-c++ -std=c++11 -DOBJCPP -triple x86_64-apple-macosx-10.9 -Wunguarded-availability -fblocks -fsyntax-only -verify %s
 
 #define AVAILABLE_10_0  __attribute__((availability(macos, introduced = 10.0)))
 #define AVAILABLE_10_11 __attribute__((availability(macos, introduced = 10.11)))
@@ -8,9 +8,9 @@
 int func_10_11() AVAILABLE_10_11; // expected-note 4 {{'func_10_11' has been explicitly marked partial here}}
 
 #ifdef OBJCPP
-// expected-note@+2 {{marked partial here}}
+// expected-note@+2 6 {{marked partial here}}
 #endif
-int func_10_12() AVAILABLE_10_12; // expected-note 5 {{'func_10_12' has been explicitly marked partial here}}
+int func_10_12() AVAILABLE_10_12; // expected-note 7 {{'func_10_12' has been explicitly marked partial here}}
 
 int func_10_0() AVAILABLE_10_0;
 
@@ -48,7 +48,7 @@
   } else
     func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
 
-  if (@available(macos 10.11, *)) {
+  if (@available(macOS 10.11, *)) {
     if (@available(ios 8, *)) {
       func_10_11();
       func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{enclose}}
@@ -129,6 +129,42 @@
 
 void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn
 
+void (^topLevelBlockDecl)() = ^ {
+  func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  if (@available(macos 10.12, *))
+    func_10_12();
+};
+
+AVAILABLE_10_12
+__attribute__((objc_root_class))
+@interface InterWithProp // expected-note 2 {{marked partial here}}
+@property(class) int x;
++ (void) setX: (int)newX AVAILABLE_10_12; // expected-note{{marked partial here}}
+@end
+void test_property(void) {
+  int y = InterWithProp.x; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  InterWithProp.x = y; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}} expected-warning{{'setX:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
+__attribute__((objc_root_class))
+@interface Subscriptable
+- (id)objectAtIndexedSubscript:(int)sub AVAILABLE_10_12; // expected-note{{marked partial here}}
+@end
+
+void test_at(Subscriptable *x) {
+  id y = x[42]; // expected-warning{{'objectAtIndexedSubscript:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+}
+
+void uncheckAtAvailable() {
+  if (@available(macOS 10.12, *) || 0) // expected-warning {{@available does not guard availability here; use if (@available) instead}}
+    func_10_12(); // expected-warning {{'func_10_12' is only available on macOS 10.12 or newer}}
+  // expected-note@-1 {{enclose 'func_10_12' in an @available check to silence this warning}}
+}
+
+void justAtAvailable() {
+  int availability = @available(macOS 10.12, *); // expected-warning {{@available does not guard availability here; use if (@available) instead}}
+}
+
 #ifdef OBJCPP
 
 int f(char) AVAILABLE_10_12;
@@ -170,10 +206,31 @@
 }
 
 int instantiate_availability() {
-  if (@available(macos 10.12, *))
+  if (@available(macOS 10.12, *))
     with_availability_attr<int_10_12>();
   else
     with_availability_attr<int_10_12>(); // expected-warning{{'with_availability_attr<int>' is only available on macOS 10.11 or newer}} expected-warning{{'int_10_12' is only available on macOS 10.12 or newer}} expected-note 2 {{enclose}}
 }
 
+auto topLevelLambda = [] () {
+  func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  if (@available(macos 10.12, *))
+    func_10_12();
+};
+
+void functionInFunction() {
+  func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  struct DontWarnTwice {
+    void f() {
+      func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+    }
+  };
+  void([] () {
+    func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  });
+  (void)(^ {
+    func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+  });
+}
+
 #endif
diff --git a/test/SemaObjC/unsafe-perform-selector.m b/test/SemaObjC/unsafe-perform-selector.m
new file mode 100644
index 0000000..661ff36
--- /dev/null
+++ b/test/SemaObjC/unsafe-perform-selector.m
@@ -0,0 +1,127 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
+// rdar://12056271
+
+@class Thread;
+
+__attribute__((objc_root_class))
+@interface NSObject
+
+- (id)performSelector:(SEL)sel;
+- (void)performSelectorInBackground:(SEL)sel withObject:(id)arg;
+- (void)performSelectorOnMainThread:(SEL)sel;
+
+- (void)performSelectorOnMainThread:(SEL)aSelector
+                           onThread:(Thread *)thread
+                         withObject:(id)arg
+                      waitUntilDone:(int)wait
+                              modes:(id *)array;
+
+@end
+
+typedef struct { int x; int y; int width; int height; } Rectangle;
+
+struct Struct { Rectangle r; };
+
+typedef union { int x; float f; } Union;
+
+@interface Base : NSObject
+
+- (struct Struct)returnsStruct2; // expected-note {{method 'returnsStruct2' that returns 'struct Struct' declared here}}
+- (Union)returnsId;
+
+@end
+
+@protocol IP
+
+- (Union)returnsUnion; // expected-note 2 {{method 'returnsUnion' that returns 'Union' declared here}}
+
+@end
+
+typedef __attribute__((__ext_vector_type__(3))) float float3;
+typedef int int4 __attribute__ ((vector_size (16)));
+
+@interface I : Base<IP>
+
+- (Rectangle)returnsStruct; // expected-note 4 {{method 'returnsStruct' that returns 'Rectangle' declared here}}
+- (id)returnsId; // shadows base 'returnsId'
+- (int)returnsInt;
+- (I *)returnPtr;
+- (float3)returnsExtVector; // expected-note {{method 'returnsExtVector' that returns 'float3' (vector of 3 'float' values) declared here}}
+- (int4)returnsVector; // expected-note {{method 'returnsVector' that returns 'int4' (vector of 4 'int' values) declared here}}
+
++ (Rectangle)returnsStructClass; // expected-note 2 {{method 'returnsStructClass' that returns 'Rectangle' declared here}}
++ (void)returnsUnion; // Not really
+
+@end
+
+void foo(I *i) {
+  [i performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+  [i performSelectorInBackground: @selector(returnsStruct) withObject:0]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a struct type}}
+  [i performSelector: ((@selector(returnsUnion)))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a union type}}
+  [i performSelectorOnMainThread: @selector(returnsStruct2)]; // expected-warning {{'performSelectorOnMainThread:' is incompatible with selectors that return a struct type}}
+  [I performSelector: (@selector(returnsStructClass))]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+
+  [i performSelector: @selector(returnsId)];
+  [i performSelector: @selector(returnsInt)];
+  [i performSelector: @selector(returnsPtr)];
+  [I performSelector: @selector(returnsUnion)]; // No warning expected
+
+  id obj = i;
+  [obj performSelector: @selector(returnsId)];
+  [obj performSelector: @selector(returnsStruct)];
+}
+
+@interface SubClass: I
+
+@end
+
+@interface SubClass ()
+- (struct Struct)returnsSubStructExt; // expected-note {{method 'returnsSubStructExt' that returns 'struct Struct' declared here}} expected-note {{method 'returnsSubStructExt' declared here}}
+@end
+
+@implementation SubClass // expected-warning {{method definition for 'returnsSubStructExt' not found}}
+
+- (struct Struct)returnsSubStructImpl { // expected-note {{method 'returnsSubStructImpl' that returns 'struct Struct' declared here}}
+  struct Struct Result;
+  return Result;
+}
+
+- (void)checkPrivateCalls {
+  [self performSelector: @selector(returnsSubStructExt)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+  [self performSelector: @selector(returnsSubStructImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+}
+
+- (void)checkSuperCalls {
+  [super performSelector: @selector(returnsStruct)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+  [super performSelectorInBackground: @selector(returnsUnion) withObject: self]; // expected-warning {{'performSelectorInBackground:withObject:' is incompatible with selectors that return a union type}}
+  [super performSelector: @selector(returnsId)];
+}
+
++ (struct Struct)returnsSubStructClassImpl { // expected-note {{method 'returnsSubStructClassImpl' that returns 'struct Struct' declared here}}
+  struct Struct Result;
+  return Result;
+}
+
++ (void)checkClassPrivateCalls {
+  [self performSelector: @selector(returnsSubStructClassImpl)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+}
+
++ (void)checkClassSuperCalls {
+  [super performSelector: @selector(returnsStructClass)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a struct type}}
+  [super performSelector: @selector(returnsUnion)]; // No warning expected
+}
+
+@end
+
+@implementation I (LongPerformSelectors)
+
+- (void)checkLongCallsFromCategory {
+  [self performSelectorOnMainThread: @selector(returnsStruct) onThread:0 withObject:self waitUntilDone:1 modes:0]; // expected-warning {{'performSelectorOnMainThread:onThread:withObject:waitUntilDone:modes:' is incompatible with selectors that return a struct type}}
+}
+
+- (void)checkVectorReturn {
+  [self performSelector: @selector(returnsExtVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}}
+  [self performSelector: @selector(returnsVector)]; // expected-warning {{'performSelector:' is incompatible with selectors that return a vector type}}
+}
+
+@end
diff --git a/test/SemaObjC/warn-deprecated-implementations.m b/test/SemaObjC/warn-deprecated-implementations.m
index 6e208b5..0c34116 100644
--- a/test/SemaObjC/warn-deprecated-implementations.m
+++ b/test/SemaObjC/warn-deprecated-implementations.m
@@ -28,8 +28,8 @@
 - (void) G {} 	// No warning, implementing its own deprecated method
 @end
 
-__attribute__((deprecated))
-@interface CL // expected-note 2 {{class declared here}} // expected-note 2 {{'CL' has been explicitly marked deprecated here}}
+__attribute__((deprecated)) // expected-note 2 {{'CL' has been explicitly marked deprecated here}}
+@interface CL // expected-note 2 {{class declared here}} 
 @end
 
 @implementation CL // expected-warning {{Implementing deprecated class}}
@@ -65,3 +65,10 @@
   return (void *)0;
 }
 @end
+
+__attribute__((deprecated))
+@interface Test(DeprecatedCategory) // expected-note {{category declared here}}
+@end
+
+@implementation Test(DeprecatedCategory) // expected-warning {{Implementing deprecated category}}
+@end
diff --git a/test/SemaObjC/x86-method-vector-values.m b/test/SemaObjC/x86-method-vector-values.m
new file mode 100644
index 0000000..23d07b1
--- /dev/null
+++ b/test/SemaObjC/x86-method-vector-values.m
@@ -0,0 +1,125 @@
+// RUN: %clang_cc1 -verify -DMAC -triple=i686-apple-macosx10.10 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DMAC -triple=i686-apple-macosx10.4 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DMAC -triple=i686-apple-darwin14 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -triple=i686-apple-ios8 -Wno-objc-root-class %s
+
+// RUN: %clang_cc1 -verify -DALLOW -DMAC -triple=i686-apple-macosx10.11 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DALLOW -DMAC -triple=i686-apple-darwin15 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DALLOW -DIOS -triple=i686-apple-ios9 -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DALLOW -DOTHER -triple=i686-apple-watchos -Wno-objc-root-class %s
+// RUN: %clang_cc1 -verify -DALLOW -DOTHER -triple=i686-apple-tvos -Wno-objc-root-class %s
+
+// RUN: %clang_cc1 -verify -DALLOW -DOTHER -triple=x86_64-apple-macosx10.10 -Wno-objc-root-class %s
+
+// rdar://21662309
+
+typedef __attribute__((__ext_vector_type__(3))) float float3;
+
+typedef float __m128 __attribute__((__vector_size__(16)));
+
+struct Aggregate { __m128 v; };
+struct AggregateFloat { float v; };
+
+#define AVAILABLE_MACOS_10_10 __attribute__((availability(macos, introduced = 10.10)))
+#define AVAILABLE_MACOS_10_11 __attribute__((availability(macos, introduced = 10.11)))
+
+#define AVAILABLE_IOS_8 __attribute__((availability(ios, introduced = 8.0)))
+#define AVAILABLE_IOS_9 __attribute__((availability(ios, introduced = 9.0)))
+
+@interface VectorMethods
+
+-(void)takeVector:(float3)v; // there should be no diagnostic at declaration
+-(void)takeM128:(__m128)v;
+
+@end
+
+@implementation VectorMethods
+
+#ifndef ALLOW
+
+-(void)takeVector:(float3)v {
+#ifdef MAC
+  // expected-error@-2 {{'float3' (vector of 3 'float' values) parameter type is unsupported; support for vector types for this target is introduced in macOS 10.11}}
+#else
+  // expected-error@-4 {{'float3' (vector of 3 'float' values) parameter type is unsupported; support for vector types for this target is introduced in iOS 9}}
+#endif
+}
+
+-(float3)retVector { // expected-error {{'float3' (vector of 3 'float' values) return type is unsupported}}
+}
+
+-(void)takeVector2:(float3)v AVAILABLE_MACOS_10_10 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+}
+
+-(void)takeVector3:(float3)v AVAILABLE_MACOS_10_11 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+}
+
+-(void)takeVector4:(float3)v AVAILABLE_IOS_8 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+}
+
+-(void)takeVector5:(float3)v AVAILABLE_IOS_9 { // expected-error {{'float3' (vector of 3 'float' values) parameter type is unsupported}}
+}
+
+- (__m128)retM128 { // expected-error {{'__m128' (vector of 4 'float' values) return type is unsupported}}
+}
+
+- (void)takeM128:(__m128)v { // expected-error {{'__m128' (vector of 4 'float' values) parameter type is unsupported}}
+}
+
+#else
+
+// expected-no-diagnostics
+
+-(void)takeVector:(float3)v {
+}
+
+-(float3)retVector {
+  return 0;
+}
+
+- (__m128)retM128 {
+  __m128 value;
+  return value;
+}
+
+- (void)takeM128:(__m128)v {
+}
+
+-(void)takeVector2:(float3)v AVAILABLE_MACOS_10_10 {
+}
+
+- (__m128)retM128_2 AVAILABLE_MACOS_10_10 {
+  __m128 value;
+  return value;
+}
+
+-(void)takeVector3:(float3)v AVAILABLE_MACOS_10_11 { // no error
+}
+
+-(void)takeVector4:(float3)v AVAILABLE_IOS_8 {
+}
+
+-(void)takeVector5:(float3)v AVAILABLE_IOS_9 { // no error
+}
+
+#ifdef OTHER
+// expected-no-diagnostics
+#endif
+
+#endif
+
+-(void)doStuff:(int)m { // no error
+}
+
+-(struct Aggregate)takesAndRetVectorInAggregate:(struct Aggregate)f { // no error
+  struct Aggregate result;
+  return result;
+}
+
+-(struct AggregateFloat)takesAndRetFloatInAggregate:(struct AggregateFloat)f { // no error
+  struct AggregateFloat result;
+  return result;
+}
+
+
+@end
diff --git a/test/SemaObjCXX/arc-bridged-cast.mm b/test/SemaObjCXX/arc-bridged-cast.mm
index 55cdd3f..b5d5774 100644
--- a/test/SemaObjCXX/arc-bridged-cast.mm
+++ b/test/SemaObjCXX/arc-bridged-cast.mm
@@ -52,3 +52,19 @@
   ref = (__bridge_retained CFAnnotatedObjectRef) CreateSomething();
   ref = (__bridge_retained CFAnnotatedObjectRef) CreateNSString();
 }
+
+struct __CFAnnotatedObject {
+} cf0;
+
+extern const CFAnnotatedObjectRef r0;
+extern const CFAnnotatedObjectRef r1 = &cf0;
+extern "C" const CFAnnotatedObjectRef r2;
+extern "C" const CFAnnotatedObjectRef r3 = &cf0;
+
+void testExternC() {
+  id obj;
+  obj = (id)r0;
+  obj = (id)r1; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}}
+  obj = (id)r2;
+  obj = (id)r3; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}}
+}
diff --git a/test/SemaObjCXX/arc-ptr-comparison.mm b/test/SemaObjCXX/arc-ptr-comparison.mm
new file mode 100644
index 0000000..8571a81
--- /dev/null
+++ b/test/SemaObjCXX/arc-ptr-comparison.mm
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin11 -fsyntax-only -fobjc-arc -verify %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin11 -fsyntax-only -verify -DNOARC %s
+#ifdef NOARC
+// expected-no-diagnostics
+#endif
+
+int testObjCComparisonRules(void *v, id x, id y) {
+  return v == x;
+#ifndef NOARC
+// expected-error@-2 {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}}
+// expected-note@-3 {{use __bridge to convert directly (no change in ownership)}}
+// expected-note@-4 {{use __bridge_retained to make an ARC object available as a +1 'void *'}}
+#endif
+  return v >= x;
+#ifndef NOARC
+// expected-error@-2 {{implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast}}
+// expected-note@-3 {{use __bridge to convert directly (no change in ownership)}}
+// expected-note@-4 {{use __bridge_retained to make an ARC object available as a +1 'void *'}}
+#endif
+  return v == (id)(void *)0; // OK
+  return v == nullptr; // OK
+  return v == (void *)0;
+  return x == y;
+}
diff --git a/test/SemaObjCXX/arc-unavailable-for-weakref.mm b/test/SemaObjCXX/arc-unavailable-for-weakref.mm
index 2a80aeb..6528748 100644
--- a/test/SemaObjCXX/arc-unavailable-for-weakref.mm
+++ b/test/SemaObjCXX/arc-unavailable-for-weakref.mm
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-arc -verify %s
+// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin11 -fobjc-runtime-has-weak -fsyntax-only -fobjc-weak -verify %s
 // rdar://9693477
 
 __attribute__((objc_arc_weak_reference_unavailable))
diff --git a/test/SemaObjCXX/blocks.mm b/test/SemaObjCXX/blocks.mm
index 3f901cc..bdd5538 100644
--- a/test/SemaObjCXX/blocks.mm
+++ b/test/SemaObjCXX/blocks.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -fblocks -Wno-objc-root-class -std=c++14 %s
 @protocol NSObject;
 
 void bar(id(^)(void));
@@ -145,6 +145,17 @@
   template void f<X>(X);
 }
 
+namespace GenericLambdaCapture {
+int test(int outerp) {
+  auto lambda =[&](auto p) {
+    return ^{
+      return p + outerp;
+    }();
+  };
+  return lambda(1);
+}
+}
+
 namespace MoveBlockVariable {
 struct B0 {
 };
diff --git a/test/SemaObjCXX/objc-weak-type-traits.mm b/test/SemaObjCXX/objc-weak-type-traits.mm
new file mode 100644
index 0000000..f425f47
--- /dev/null
+++ b/test/SemaObjCXX/objc-weak-type-traits.mm
@@ -0,0 +1,210 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-weak -fobjc-runtime-has-weak -verify -std=c++11 %s
+// expected-no-diagnostics
+
+// Check the results of the various type-trait query functions on
+// lifetime-qualified types in ObjC Weak.
+
+#define TRAIT_IS_TRUE(Trait, Type) static_assert(Trait(Type), "")
+#define TRAIT_IS_FALSE(Trait, Type) static_assert(!Trait(Type), "")
+#define TRAIT_IS_TRUE_2(Trait, Type1, Type2) static_assert(Trait(Type1, Type2), "")
+#define TRAIT_IS_FALSE_2(Trait, Type1, Type2) static_assert(!Trait(Type1, Type2), "")
+  
+struct HasStrong { id obj; };
+struct HasWeak { __weak id obj; };
+struct HasUnsafeUnretained { __unsafe_unretained id obj; };
+
+// __has_nothrow_assign
+TRAIT_IS_TRUE(__has_nothrow_assign, __strong id);
+TRAIT_IS_TRUE(__has_nothrow_assign, __weak id);
+TRAIT_IS_TRUE(__has_nothrow_assign, __autoreleasing id);
+TRAIT_IS_TRUE(__has_nothrow_assign, __unsafe_unretained id);
+TRAIT_IS_TRUE(__has_nothrow_assign, HasStrong);
+TRAIT_IS_TRUE(__has_nothrow_assign, HasWeak);
+TRAIT_IS_TRUE(__has_nothrow_assign, HasUnsafeUnretained);
+
+// __has_nothrow_copy
+TRAIT_IS_TRUE(__has_nothrow_copy, __strong id);
+TRAIT_IS_TRUE(__has_nothrow_copy, __weak id);
+TRAIT_IS_TRUE(__has_nothrow_copy, __autoreleasing id);
+TRAIT_IS_TRUE(__has_nothrow_copy, __unsafe_unretained id);
+TRAIT_IS_TRUE(__has_nothrow_copy, HasStrong);
+TRAIT_IS_TRUE(__has_nothrow_copy, HasWeak);
+TRAIT_IS_TRUE(__has_nothrow_copy, HasUnsafeUnretained);
+
+// __has_nothrow_constructor
+TRAIT_IS_TRUE(__has_nothrow_constructor, __strong id);
+TRAIT_IS_TRUE(__has_nothrow_constructor, __weak id);
+TRAIT_IS_TRUE(__has_nothrow_constructor, __autoreleasing id);
+TRAIT_IS_TRUE(__has_nothrow_constructor, __unsafe_unretained id);
+TRAIT_IS_TRUE(__has_nothrow_constructor, HasStrong);
+TRAIT_IS_TRUE(__has_nothrow_constructor, HasWeak);
+TRAIT_IS_TRUE(__has_nothrow_constructor, HasUnsafeUnretained);
+
+// __has_trivial_assign
+TRAIT_IS_TRUE(__has_trivial_assign, __strong id);
+TRAIT_IS_FALSE(__has_trivial_assign, __weak id);
+TRAIT_IS_TRUE(__has_trivial_assign, __autoreleasing id);
+TRAIT_IS_TRUE(__has_trivial_assign, __unsafe_unretained id);
+TRAIT_IS_TRUE(__has_trivial_assign, HasStrong);
+TRAIT_IS_FALSE(__has_trivial_assign, HasWeak);
+TRAIT_IS_TRUE(__has_trivial_assign, HasUnsafeUnretained);
+
+// __has_trivial_copy
+TRAIT_IS_TRUE(__has_trivial_copy, __strong id);
+TRAIT_IS_FALSE(__has_trivial_copy, __weak id);
+TRAIT_IS_TRUE(__has_trivial_copy, __autoreleasing id);
+TRAIT_IS_TRUE(__has_trivial_copy, __unsafe_unretained id);
+TRAIT_IS_TRUE(__has_trivial_copy, HasStrong);
+TRAIT_IS_FALSE(__has_trivial_copy, HasWeak);
+TRAIT_IS_TRUE(__has_trivial_copy, HasUnsafeUnretained);
+
+// __has_trivial_constructor
+TRAIT_IS_TRUE(__has_trivial_constructor, __strong id);
+TRAIT_IS_FALSE(__has_trivial_constructor, __weak id);
+TRAIT_IS_TRUE(__has_trivial_constructor, __autoreleasing id);
+TRAIT_IS_TRUE(__has_trivial_constructor, __unsafe_unretained id);
+TRAIT_IS_TRUE(__has_trivial_constructor, HasStrong);
+TRAIT_IS_FALSE(__has_trivial_constructor, HasWeak);
+TRAIT_IS_TRUE(__has_trivial_constructor, HasUnsafeUnretained);
+
+// __has_trivial_destructor
+TRAIT_IS_TRUE(__has_trivial_destructor, __strong id);
+TRAIT_IS_FALSE(__has_trivial_destructor, __weak id);
+TRAIT_IS_TRUE(__has_trivial_destructor, __autoreleasing id);
+TRAIT_IS_TRUE(__has_trivial_destructor, __unsafe_unretained id);
+TRAIT_IS_TRUE(__has_trivial_destructor, HasStrong);
+TRAIT_IS_FALSE(__has_trivial_destructor, HasWeak);
+TRAIT_IS_TRUE(__has_trivial_destructor, HasUnsafeUnretained);
+
+// __is_literal
+TRAIT_IS_TRUE(__is_literal, __strong id);
+TRAIT_IS_TRUE(__is_literal, __weak id);
+TRAIT_IS_TRUE(__is_literal, __autoreleasing id);
+TRAIT_IS_TRUE(__is_literal, __unsafe_unretained id);
+
+// __is_literal_type
+TRAIT_IS_TRUE(__is_literal_type, __strong id);
+TRAIT_IS_TRUE(__is_literal_type, __weak id);
+TRAIT_IS_TRUE(__is_literal_type, __autoreleasing id);
+TRAIT_IS_TRUE(__is_literal_type, __unsafe_unretained id);
+
+// __is_pod
+TRAIT_IS_TRUE(__is_pod, __strong id);
+TRAIT_IS_FALSE(__is_pod, __weak id);
+TRAIT_IS_TRUE(__is_pod, __autoreleasing id);
+TRAIT_IS_TRUE(__is_pod, __unsafe_unretained id);
+TRAIT_IS_TRUE(__is_pod, HasStrong);
+TRAIT_IS_FALSE(__is_pod, HasWeak);
+TRAIT_IS_TRUE(__is_pod, HasUnsafeUnretained);
+
+// __is_trivial
+TRAIT_IS_TRUE(__is_trivial, __strong id);
+TRAIT_IS_FALSE(__is_trivial, __weak id);
+TRAIT_IS_TRUE(__is_trivial, __autoreleasing id);
+TRAIT_IS_TRUE(__is_trivial, __unsafe_unretained id);
+TRAIT_IS_TRUE(__is_trivial, HasStrong);
+TRAIT_IS_FALSE(__is_trivial, HasWeak);
+TRAIT_IS_TRUE(__is_trivial, HasUnsafeUnretained);
+
+// __is_scalar
+TRAIT_IS_TRUE(__is_scalar, __strong id);
+TRAIT_IS_FALSE(__is_scalar, __weak id);
+TRAIT_IS_TRUE(__is_scalar, __autoreleasing id);
+TRAIT_IS_TRUE(__is_scalar, __unsafe_unretained id);
+
+// __is_standard_layout
+TRAIT_IS_TRUE(__is_standard_layout, __strong id);
+TRAIT_IS_TRUE(__is_standard_layout, __weak id);
+TRAIT_IS_TRUE(__is_standard_layout, __autoreleasing id);
+TRAIT_IS_TRUE(__is_standard_layout, __unsafe_unretained id);
+
+// __is_trivally_assignable
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __strong id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __weak id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __autoreleasing id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __unsafe_unretained id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __strong id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __weak id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __autoreleasing id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __strong id&, __unsafe_unretained id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __strong id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __weak id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __autoreleasing id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __unsafe_unretained id);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __strong id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __weak id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __autoreleasing id&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, __weak id&, __unsafe_unretained id&&);
+
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __strong id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __weak id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __autoreleasing id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __unsafe_unretained id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __strong id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __weak id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __autoreleasing id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __autoreleasing id&, __unsafe_unretained id&&);
+
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __strong id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __weak id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __autoreleasing id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __unsafe_unretained id);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __strong id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __weak id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __autoreleasing id&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, __unsafe_unretained id&, __unsafe_unretained id&&);
+
+TRAIT_IS_TRUE_2(__is_trivially_assignable, HasStrong&, HasStrong);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, HasStrong&, HasStrong&&);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, HasWeak&, HasWeak);
+TRAIT_IS_FALSE_2(__is_trivially_assignable, HasWeak&, HasWeak&&);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, HasUnsafeUnretained&, HasUnsafeUnretained);
+TRAIT_IS_TRUE_2(__is_trivially_assignable, HasUnsafeUnretained&, HasUnsafeUnretained&&);
+
+// __is_trivally_constructible
+TRAIT_IS_TRUE(__is_trivially_constructible, __strong id);
+TRAIT_IS_FALSE(__is_trivially_constructible, __weak id);
+TRAIT_IS_TRUE(__is_trivially_constructible, __autoreleasing id);
+TRAIT_IS_TRUE(__is_trivially_constructible, __unsafe_unretained id);
+
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __strong id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __weak id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __autoreleasing id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __unsafe_unretained id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __strong id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __weak id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __autoreleasing id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __strong id, __unsafe_unretained id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __strong id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __weak id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __autoreleasing id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __unsafe_unretained id);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __strong id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __weak id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __autoreleasing id&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, __weak id, __unsafe_unretained id&&);
+
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __strong id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __weak id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __autoreleasing id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __unsafe_unretained id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __strong id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __weak id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __autoreleasing id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __autoreleasing id, __unsafe_unretained id&&);
+
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __strong id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __weak id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __autoreleasing id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __unsafe_unretained id);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __strong id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __weak id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __autoreleasing id&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, __unsafe_unretained id, __unsafe_unretained id&&);
+
+TRAIT_IS_TRUE_2(__is_trivially_constructible, HasStrong, HasStrong);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, HasStrong, HasStrong&&);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, HasWeak, HasWeak);
+TRAIT_IS_FALSE_2(__is_trivially_constructible, HasWeak, HasWeak&&);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, HasUnsafeUnretained, HasUnsafeUnretained);
+TRAIT_IS_TRUE_2(__is_trivially_constructible, HasUnsafeUnretained, HasUnsafeUnretained&&);
diff --git a/test/SemaObjCXX/objc-weak.mm b/test/SemaObjCXX/objc-weak.mm
new file mode 100644
index 0000000..93c6af1
--- /dev/null
+++ b/test/SemaObjCXX/objc-weak.mm
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++98 -Wno-c++0x-extensions -verify %s
+
+@interface AnObject
+@property(weak) id value;
+@end
+
+__attribute__((objc_arc_weak_reference_unavailable))
+@interface NOWEAK : AnObject // expected-note 2 {{class is declared here}}
+@end
+
+struct S {
+  __weak id a; // expected-note {{because type 'S' has a member with __weak ownership}}
+};
+
+union U {
+  __weak id a; // expected-error {{ARC forbids Objective-C objects in union}}
+  S b;         // expected-error {{union member 'b' has a non-trivial copy constructor}}
+};
+
+void testCast(AnObject *o) {
+  __weak id a = reinterpret_cast<__weak NOWEAK *>(o); // expected-error {{class is incompatible with __weak references}} \
+                                                      // expected-error {{explicit ownership qualifier on cast result has no effect}} \
+                                                      // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+
+  __weak id b = static_cast<__weak NOWEAK *>(o); // expected-error {{class is incompatible with __weak references}} \
+                                                 // expected-error {{explicit ownership qualifier on cast result has no effect}} \
+                                                 // expected-error {{assignment of a weak-unavailable object to a __weak object}}
+}
diff --git a/test/SemaObjCXX/overload.mm b/test/SemaObjCXX/overload.mm
index bb94d9e..018afc9 100644
--- a/test/SemaObjCXX/overload.mm
+++ b/test/SemaObjCXX/overload.mm
@@ -174,3 +174,30 @@
   void f(Class) { }
   void f(id) { }
 }
+
+@interface NSDictionary<__covariant KeyType, __covariant ObjectType> : A
+@end
+
+@interface NSMutableDictionary<KeyType, ObjectType> : NSDictionary<KeyType, ObjectType>
+@end
+
+namespace rdar20124827 {
+
+int overload(NSDictionary *) { return 1; }
+
+__attribute__((deprecated))  // expected-note {{'overload' has been explicitly marked deprecated here}}
+int overload(NSMutableDictionary *) { return 0; }
+
+__attribute__((deprecated))
+void overload2(NSDictionary *); // expected-note {{candidate function}}
+void overload2(NSDictionary<A *, A *> *); // expected-note {{candidate function}}
+
+void test(NSDictionary *d1, NSDictionary<A *, A *> *d2, NSMutableDictionary<A *, A *> *m1) {
+  overload(d1);
+  overload(d2); // no warning
+  overload(m1); // expected-warning {{'overload' is deprecated}}
+  overload2(d2); // no warning
+  overload2(m1); // expected-error {{call to 'overload2' is ambiguous}}
+}
+
+}
diff --git a/test/lit.cfg b/test/lit.cfg
index 7d8bebf..35c280d 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -253,12 +253,14 @@
     if os == 'win32':
       # If the OS is win32, we're done.
       return triple
-    if isa.startswith('x86') or isa == 'amd64' or re.match(r'i\d86', isa): 
+    if isa.startswith('x86') or isa == 'amd64' or re.match(r'i\d86', isa):
       # For x86 ISAs, adjust the OS.
       return isa + '-' + vendor + '-win32'
     # -win32 is not supported for non-x86 targets; use a default.
     return 'i686-pc-win32'
 
+config.substitutions.append( ('%clang_analyze_cc1',
+                              '%clang_cc1 -analyze %analyze') )
 config.substitutions.append( ('%clang_cc1',
                               '%s -cc1 -internal-isystem %s -nostdsysteminc'
                               % (config.clang,
@@ -282,6 +284,8 @@
 else:
     config.substitutions.append( ('%target_itanium_abi_host_triple', '') )
 
+config.substitutions.append( ('%src_include_dir', config.clang_src_dir + '/include') )
+
 # FIXME: Find nicer way to prohibit this.
 config.substitutions.append(
     (' clang ', """*** Do not use 'clang' in tests, use '%clang'. ***""") )
@@ -291,6 +295,9 @@
     (' clang-cc ',
      """*** Do not use 'clang-cc' in tests, use '%clang_cc1'. ***""") )
 config.substitutions.append(
+    (' clang -cc1 -analyze ',
+     """*** Do not use 'clang -cc1 -analyze' in tests, use '%clang_analyze_cc1'. ***""") )
+config.substitutions.append(
     (' clang -cc1 ',
      """*** Do not use 'clang -cc1' in tests, use '%clang_cc1'. ***""") )
 config.substitutions.append(
@@ -356,6 +363,9 @@
 if config.clang_staticanalyzer != 0:
     config.available_features.add("staticanalyzer")
 
+    if config.clang_staticanalyzer_z3 == '1':
+        config.available_features.add("z3")
+
 # As of 2011.08, crash-recovery tests still do not pass on FreeBSD.
 if platform.system() not in ['FreeBSD']:
     config.available_features.add('crash-recovery')
diff --git a/test/lit.site.cfg.in b/test/lit.site.cfg.in
index 5e1471f..7469e6d 100644
--- a/test/lit.site.cfg.in
+++ b/test/lit.site.cfg.in
@@ -10,6 +10,7 @@
 config.llvm_plugin_ext = "@LLVM_PLUGIN_EXT@"
 config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
 config.clang_obj_root = "@CLANG_BINARY_DIR@"
+config.clang_src_dir = "@CLANG_SOURCE_DIR@"
 config.clang_tools_dir = "@CLANG_TOOLS_DIR@"
 config.host_triple = "@LLVM_HOST_TRIPLE@"
 config.target_triple = "@TARGET_TRIPLE@"
@@ -18,6 +19,7 @@
 config.clang_arcmt = @ENABLE_CLANG_ARCMT@
 config.clang_default_cxx_stdlib = "@CLANG_DEFAULT_CXX_STDLIB@"
 config.clang_staticanalyzer = @ENABLE_CLANG_STATIC_ANALYZER@
+config.clang_staticanalyzer_z3 = "@CLANG_ANALYZER_WITH_Z3@"
 config.clang_examples = @ENABLE_CLANG_EXAMPLES@
 config.enable_shared = @ENABLE_SHARED@
 config.enable_backtrace = "@ENABLE_BACKTRACES@"
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index e0df503..7244e2c 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -24,8 +24,10 @@
     libclang
     clangAST
     clangBasic
+    clangCodeGen
     clangFrontend
     clangIndex
+    clangSerialization
   )
 endif()
 
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index dfb4b27..b80d836 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -710,6 +710,16 @@
         clang_getSpellingLocation(Loc, 0, &line, &column, 0);
         printf(":%d:%d", line, column);
       }
+
+      if (clang_getCursorKind(Referenced) == CXCursor_TypedefDecl) {
+        CXType T = clang_getCursorType(Referenced);
+        if (clang_Type_isTransparentTagTypedef(T)) {
+          CXType Underlying = clang_getTypedefDeclUnderlyingType(Referenced);
+          CXString S = clang_getTypeSpelling(Underlying);
+          printf(" (Transparent: %s)", clang_getCString(S));
+          clang_disposeString(S);
+        }
+      }
     }
 
     if (clang_isCursorDefinition(Cursor))
@@ -799,6 +809,19 @@
     if (clang_Cursor_isObjCOptional(Cursor))
       printf(" (@optional)");
 
+    {
+      CXString language;
+      CXString definedIn;
+      unsigned generated;
+      if (clang_Cursor_isExternalSymbol(Cursor, &language, &definedIn,
+                                        &generated)) {
+        printf(" (external lang: %s, defined: %s, gen: %d)",
+            clang_getCString(language), clang_getCString(definedIn), generated);
+        clang_disposeString(language);
+        clang_disposeString(definedIn);
+      }
+    }
+
     if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
       CXType T =
         clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor));
@@ -2427,11 +2450,14 @@
            clang_Cursor_getObjCSelectorIndex(Cursor));
   if (clang_Cursor_isDynamicCall(Cursor))
     printf(" Dynamic-call");
-  if (Cursor.kind == CXCursor_ObjCMessageExpr) {
+  if (Cursor.kind == CXCursor_ObjCMessageExpr ||
+      Cursor.kind == CXCursor_MemberRefExpr) {
     CXType T = clang_Cursor_getReceiverType(Cursor);
-    CXString S = clang_getTypeKindSpelling(T.kind);
-    printf(" Receiver-type=%s", clang_getCString(S));
-    clang_disposeString(S);
+    if (T.kind != CXType_Invalid) {
+      CXString S = clang_getTypeKindSpelling(T.kind);
+      printf(" Receiver-type=%s", clang_getCString(S));
+      clang_disposeString(S);
+    }
   }
 
   {
@@ -3004,6 +3030,7 @@
   case CXIdxEntityLang_C: return "C";
   case CXIdxEntityLang_ObjC: return "ObjC";
   case CXIdxEntityLang_CXX: return "C++";
+  case CXIdxEntityLang_Swift: return "Swift";
   }
   assert(0 && "Garbage language kind");
   return 0;
@@ -4452,13 +4479,13 @@
   LIBXML_TEST_VERSION
 #endif
 
+  if (argc > 1 && strcmp(argv[1], "core") == 0)
+    return indextest_core_main(argc, argv);
+
   client_data.main_func = cindextest_main;
   client_data.argc = argc;
   client_data.argv = argv;
 
-  if (argc > 1 && strcmp(argv[1], "core") == 0)
-    client_data.main_func = indextest_core_main;
-
   if (getenv("CINDEXTEST_NOTHREADS"))
     return client_data.main_func(client_data.argc, client_data.argv);
 
diff --git a/tools/c-index-test/core_main.cpp b/tools/c-index-test/core_main.cpp
index 0ab24fb..4f2c3cb 100644
--- a/tools/c-index-test/core_main.cpp
+++ b/tools/c-index-test/core_main.cpp
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInvocation.h"
@@ -15,6 +16,7 @@
 #include "clang/Index/IndexDataConsumer.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Index/CodegenNameGenerator.h"
+#include "clang/Serialization/ASTReader.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/raw_ostream.h"
@@ -49,6 +51,20 @@
   "invocation\n"
 );
 
+static cl::opt<bool>
+DumpModuleImports("dump-imported-module-files",
+               cl::desc("Print symbols and input files from imported modules"));
+
+static cl::opt<bool>
+IncludeLocals("include-locals", cl::desc("Print local symbols"));
+
+static cl::opt<std::string>
+ModuleFilePath("module-file",
+               cl::desc("Path to module file to print symbols from"));
+static cl::opt<std::string>
+  ModuleFormat("fmodule-format", cl::init("raw"),
+        cl::desc("Container format for clang modules and PCH, 'raw' or 'obj'"));
+
 }
 } // anonymous namespace
 
@@ -134,7 +150,20 @@
 // Print Source Symbols
 //===----------------------------------------------------------------------===//
 
-static bool printSourceSymbols(ArrayRef<const char *> Args) {
+static void dumpModuleFileInputs(serialization::ModuleFile &Mod,
+                                 ASTReader &Reader,
+                                 raw_ostream &OS) {
+  OS << "---- Module Inputs ----\n";
+  Reader.visitInputFiles(Mod, /*IncludeSystem=*/true, /*Complain=*/false,
+                        [&](const serialization::InputFile &IF, bool isSystem) {
+    OS << (isSystem ? "system" : "user") << " | ";
+    OS << IF.getFile()->getName() << '\n';
+  });
+}
+
+static bool printSourceSymbols(ArrayRef<const char *> Args,
+                               bool dumpModuleImports,
+                               bool indexLocals) {
   SmallVector<const char *, 4> ArgsWithProgName;
   ArgsWithProgName.push_back("clang");
   ArgsWithProgName.append(Args.begin(), Args.end());
@@ -144,8 +173,10 @@
   if (!CInvok)
     return true;
 
-  auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(outs());
+  raw_ostream &OS = outs();
+  auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(OS);
   IndexingOptions IndexOpts;
+  IndexOpts.IndexFunctionLocals = indexLocals;
   std::unique_ptr<FrontendAction> IndexAction;
   IndexAction = createIndexingAction(DataConsumer, IndexOpts,
                                      /*WrappedAction=*/nullptr);
@@ -157,6 +188,50 @@
   if (!Unit)
     return true;
 
+  if (dumpModuleImports) {
+    if (auto Reader = Unit->getASTReader()) {
+      Reader->getModuleManager().visit([&](serialization::ModuleFile &Mod) -> bool {
+        OS << "==== Module " << Mod.ModuleName << " ====\n";
+        indexModuleFile(Mod, *Reader, DataConsumer, IndexOpts);
+        dumpModuleFileInputs(Mod, *Reader, OS);
+        return true; // skip module dependencies.
+      });
+    }
+  }
+
+  return false;
+}
+
+static bool printSourceSymbolsFromModule(StringRef modulePath,
+                                         StringRef format) {
+  FileSystemOptions FileSystemOpts;
+  auto pchContOps = std::make_shared<PCHContainerOperations>();
+  // Register the support for object-file-wrapped Clang modules.
+  pchContOps->registerReader(llvm::make_unique<ObjectFilePCHContainerReader>());
+  auto pchRdr = pchContOps->getReaderOrNull(format);
+  if (!pchRdr) {
+    errs() << "unknown module format: " << format << '\n';
+    return true;
+  }
+
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+      CompilerInstance::createDiagnostics(new DiagnosticOptions());
+  std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
+      modulePath, *pchRdr, Diags,
+      FileSystemOpts, /*UseDebugInfo=*/false,
+      /*OnlyLocalDecls=*/true, None,
+      /*CaptureDiagnostics=*/false,
+      /*AllowPCHWithCompilerErrors=*/true,
+      /*UserFilesAreVolatile=*/false);
+  if (!AU) {
+    errs() << "failed to create TU for: " << modulePath << '\n';
+    return true;
+  }
+
+  auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(outs());
+  IndexingOptions IndexOpts;
+  indexASTUnit(*AU, DataConsumer, IndexOpts);
+
   return false;
 }
 
@@ -219,11 +294,15 @@
   }
 
   if (options::Action == ActionType::PrintSourceSymbols) {
+    if (!options::ModuleFilePath.empty()) {
+      return printSourceSymbolsFromModule(options::ModuleFilePath,
+                                          options::ModuleFormat);
+    }
     if (CompArgs.empty()) {
       errs() << "error: missing compiler args; pass '-- <compiler arguments>'\n";
       return 1;
     }
-    return printSourceSymbols(CompArgs);
+    return printSourceSymbols(CompArgs, options::DumpModuleImports, options::IncludeLocals);
   }
 
   return 0;
diff --git a/tools/clang-check/CMakeLists.txt b/tools/clang-check/CMakeLists.txt
index 04151a8..233f981 100644
--- a/tools/clang-check/CMakeLists.txt
+++ b/tools/clang-check/CMakeLists.txt
@@ -9,6 +9,7 @@
   )
 
 target_link_libraries(clang-check
+  clangAPINotes
   clangAST
   clangBasic
   clangDriver
diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp
index 6c50daf..c097239 100644
--- a/tools/clang-format/ClangFormat.cpp
+++ b/tools/clang-format/ClangFormat.cpp
@@ -249,8 +249,7 @@
   if (fillRanges(Code.get(), Ranges))
     return true;
   StringRef AssumedFileName = (FileName == "-") ? AssumeFileName : FileName;
-  FormatStyle FormatStyle =
-      getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer());
+  FormatStyle FormatStyle = getStyle(Style, AssumedFileName, FallbackStyle);
   if (SortIncludes.getNumOccurrences() != 0)
     FormatStyle.SortIncludes = SortIncludes;
   unsigned CursorPosition = Cursor;
diff --git a/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/tools/clang-offload-bundler/ClangOffloadBundler.cpp
index 20988b4..f37868f 100644
--- a/tools/clang-offload-bundler/ClangOffloadBundler.cpp
+++ b/tools/clang-offload-bundler/ClangOffloadBundler.cpp
@@ -514,7 +514,10 @@
     // Dump the contents of the temporary file if that was requested.
     if (DumpTemporaryFiles) {
       errs() << ";\n; Object file bundler IR file.\n;\n";
-      AuxModule.get()->dump();
+      AuxModule.get()->print(errs(), nullptr,
+                             /*ShouldPreserveUseListOrder=*/false,
+                             /*IsForDebug=*/true);
+      errs() << '\n';
     }
 
     // Find clang in order to create the bundle binary.
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index f6e26fa..9dfe8cf 100644
--- a/tools/driver/CMakeLists.txt
+++ b/tools/driver/CMakeLists.txt
@@ -32,6 +32,7 @@
   driver.cpp
   cc1_main.cpp
   cc1as_main.cpp
+  apinotes_main.cpp
 
   DEPENDS
   ${tablegen_deps}
@@ -39,6 +40,7 @@
 
 target_link_libraries(clang
   clangBasic
+  clangAPINotes
   clangCodeGen
   clangDriver
   clangFrontend
diff --git a/tools/driver/apinotes_main.cpp b/tools/driver/apinotes_main.cpp
new file mode 100644
index 0000000..930dc39
--- /dev/null
+++ b/tools/driver/apinotes_main.cpp
@@ -0,0 +1,154 @@
+//===-- api_notes.cpp - API Notes Driver ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file 
+/// This file provides conversion between the YAML (source) and binary forms 
+/// of API notes.
+///
+//===----------------------------------------------------------------------===//
+#include "clang/APINotes/APINotesYAMLCompiler.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/Triple.h"
+
+using namespace llvm;
+namespace api_notes = clang::api_notes;
+
+int cc1apinotes_main(ArrayRef<const char *> Argv, const char *Argv0,
+                     void *MainAddr) {
+
+  // Mark all our options with this category, everything else (except for
+  // -version and -help) will be hidden.
+  static cl::OptionCategory APINotesCategory("API Notes options");
+
+  static cl::opt<api_notes::ActionType>
+  Action(cl::desc("Mode:"), cl::init(api_notes::ActionType::None),
+         cl::values(
+                    clEnumValN(api_notes::ActionType::YAMLToBinary,
+                               "yaml-to-binary", 
+                               "Convert YAML to binary format"),
+                    clEnumValN(api_notes::ActionType::BinaryToYAML,
+                               "binary-to-yaml",
+                               "Convert binary format to YAML"),
+                    clEnumValN(api_notes::ActionType::Dump,
+                               "dump", 
+                               "Parse and dump the output")),
+         cl::cat(APINotesCategory));
+
+  static cl::opt<std::string>
+  InputFilename(cl::Positional, cl::desc("<input file>"),
+                cl::Required, cl::cat(APINotesCategory));
+
+  static cl::opt<std::string>
+  Target("target", cl::desc("Generate binary format for the given target"),
+                   cl::cat(APINotesCategory));
+
+  static cl::opt<std::string>
+  OutputFilename("o", cl::desc("Output file name"), cl::cat(APINotesCategory));
+
+  cl::HideUnrelatedOptions(APINotesCategory);
+
+  SmallVector<const char *, 4> Args;
+  Args.push_back(Argv0);
+  Args.append(Argv.begin(), Argv.end());
+  cl::ParseCommandLineOptions(Args.size(),
+                              Args.data(),
+                              "Clang API Notes Tool\n");
+
+  if (Action == clang::api_notes::ActionType::None) {
+    errs() << "action required\n";
+    cl::PrintHelpMessage();
+    return 1;
+  }
+
+  auto fileBufOrErr = MemoryBuffer::getFile(InputFilename);
+  if (std::error_code EC = fileBufOrErr.getError()) {
+    llvm::errs() << "\n Could not open input file: " + EC.message() << '\n';
+    return true;
+  }
+  StringRef input = fileBufOrErr.get()->getBuffer();
+
+  switch (Action) {
+  case api_notes::ActionType::None:
+    llvm_unreachable("handled above");
+
+  case api_notes::ActionType::YAMLToBinary: {
+    if (OutputFilename.empty()) {
+      errs() << "output file is required\n";
+      cl::PrintHelpMessage();
+      return 1;
+    }
+
+    api_notes::OSType targetOS = api_notes::OSType::Absent;
+    // TODO: Check that we've specified the target.
+    if (!Target.empty()) {
+      llvm::Triple target(llvm::Triple::normalize(Target));
+      switch (target.getOS()) {
+        case llvm::Triple::Darwin:
+        case llvm::Triple::MacOSX:
+          targetOS = api_notes::OSType::OSX;
+          break;
+        case llvm::Triple::IOS:
+          targetOS = api_notes::OSType::IOS;
+          break;
+        case llvm::Triple::WatchOS:
+          targetOS = api_notes::OSType::WatchOS;
+          break;
+        case llvm::Triple::TvOS:
+          targetOS = api_notes::OSType::TvOS;
+          break;
+        default:
+          errs() << "target is not supported\n";
+          return 1;
+      }
+    }
+    std::error_code EC;
+    llvm::raw_fd_ostream os(OutputFilename, EC,
+                            llvm::sys::fs::OpenFlags::F_None);
+
+    if (api_notes::compileAPINotes(input, /*sourceFile=*/nullptr, os, targetOS))
+      return 1;
+    
+    os.flush();
+
+    return os.has_error();
+  }
+
+  case api_notes::ActionType::BinaryToYAML: {
+    if (OutputFilename.empty()) {
+      errs() << "output file required\n";
+      cl::PrintHelpMessage();
+      return 1;
+    }
+
+    std::error_code EC;
+    llvm::raw_fd_ostream os(OutputFilename, EC,
+                            llvm::sys::fs::OpenFlags::F_None);
+
+    if (api_notes::decompileAPINotes(std::move(fileBufOrErr.get()), os))
+      return 1;
+    
+    os.flush();
+
+    return os.has_error();
+  }
+
+  case api_notes::ActionType::Dump:
+    return api_notes::parseAndDumpAPINotes(input);
+  }
+
+  return 1;
+}
+
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 6161302..5c83c8b 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -198,6 +198,8 @@
                     void *MainAddr);
 extern int cc1as_main(ArrayRef<const char *> Argv, const char *Argv0,
                       void *MainAddr);
+extern int cc1apinotes_main(ArrayRef<const char *> Argv, const char *Argv0,
+                            void *MainAddr);
 
 static void insertTargetAndModeArgs(StringRef Target, StringRef Mode,
                                     SmallVectorImpl<const char *> &ArgVector,
@@ -299,6 +301,8 @@
     return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP);
   if (Tool == "as")
     return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP);
+  if (Tool == "apinotes")
+    return cc1apinotes_main(argv.slice(2), argv[0], GetExecutablePathVP);
 
   // Reject unknown tools.
   llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n";
@@ -460,8 +464,9 @@
     Res = TheDriver.ExecuteCompilation(*C, FailingCommands);
 
   // Force a crash to test the diagnostics.
-  if (::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH")) {
-    Diags.Report(diag::err_drv_force_crash) << "FORCE_CLANG_DIAGNOSTICS_CRASH";
+  if (TheDriver.GenReproducer) {
+    Diags.Report(diag::err_drv_force_crash)
+        << !::getenv("FORCE_CLANG_DIAGNOSTICS_CRASH");
 
     // Pretend that every command failed.
     FailingCommands.clear();
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 67fa2ae..4fd26a9 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -3358,7 +3358,10 @@
     Args->push_back("-Xclang");
     Args->push_back("-detailed-preprocessing-record");
   }
-  
+
+  // Suppress any editor placeholder diagnostics.
+  Args->push_back("-fallow-editor-placeholders");
+
   unsigned NumErrors = Diags->getClient()->getNumErrors();
   std::unique_ptr<ASTUnit> ErrUnit;
   // Unless the user specified that they want the preamble on the first parse
@@ -7417,6 +7420,26 @@
   return 0;
 }
 
+unsigned clang_Cursor_isExternalSymbol(CXCursor C,
+                                     CXString *language, CXString *definedIn,
+                                     unsigned *isGenerated) {
+  if (!clang_isDeclaration(C.kind))
+    return 0;
+
+  const Decl *D = getCursorDecl(C);
+
+  if (auto *attr = D->getExternalSourceSymbolAttr()) {
+    if (language)
+      *language = cxstring::createDup(attr->getLanguage());
+    if (definedIn)
+      *definedIn = cxstring::createDup(attr->getDefinedIn());
+    if (isGenerated)
+      *isGenerated = attr->getGeneratedDeclaration();
+    return 1;
+  }
+  return 0;
+}
+
 CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
   if (!clang_isDeclaration(C.kind))
     return clang_getNullRange();
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index 2dd6703..5cad9dc 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -35,6 +35,7 @@
 
 set(LIBS
   clangAST
+  clangAPINotes
   clangBasic
   clangFrontend
   clangIndex
diff --git a/tools/libclang/CXCursor.cpp b/tools/libclang/CXCursor.cpp
index 8731ca6..e48df9d 100644
--- a/tools/libclang/CXCursor.cpp
+++ b/tools/libclang/CXCursor.cpp
@@ -1522,6 +1522,10 @@
     return true;
   }
 
+  if (auto *PropRefE = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    return !PropRefE->isSuperReceiver();
+  }
+
   const MemberExpr *ME = nullptr;
   if (isa<MemberExpr>(E))
     ME = cast<MemberExpr>(E);
@@ -1531,7 +1535,9 @@
   if (ME) {
     if (const CXXMethodDecl *
           MD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
-      return MD->isVirtual() && !ME->hasQualifier();
+      return MD->isVirtual() &&
+             ME->performsVirtualDispatch(
+                 cxcursor::getCursorContext(C).getLangOpts());
   }
 
   return 0;
@@ -1546,5 +1552,23 @@
   if (const ObjCMessageExpr *MsgE = dyn_cast_or_null<ObjCMessageExpr>(E))
     return cxtype::MakeCXType(MsgE->getReceiverType(), TU);
 
+  if (auto *PropRefE = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    return cxtype::MakeCXType(
+        PropRefE->getReceiverType(cxcursor::getCursorContext(C)), TU);
+  }
+
+  const MemberExpr *ME = nullptr;
+  if (isa<MemberExpr>(E))
+    ME = cast<MemberExpr>(E);
+  else if (const CallExpr *CE = dyn_cast<CallExpr>(E))
+    ME = dyn_cast_or_null<MemberExpr>(CE->getCallee());
+
+  if (ME) {
+    if (dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl())) {
+      auto receiverTy = ME->getBase()->IgnoreImpCasts()->getType();
+      return cxtype::MakeCXType(receiverTy, TU);
+    }
+  }
+
   return cxtype::MakeCXType(QualType(), TU);
 }
diff --git a/tools/libclang/CXIndexDataConsumer.cpp b/tools/libclang/CXIndexDataConsumer.cpp
index cb8aebf..4a2957f 100644
--- a/tools/libclang/CXIndexDataConsumer.cpp
+++ b/tools/libclang/CXIndexDataConsumer.cpp
@@ -1256,6 +1256,7 @@
   case SymbolKind::Module:
   case SymbolKind::Macro:
   case SymbolKind::ClassProperty:
+  case SymbolKind::CommentTag:
     return CXIdxEntity_Unexposed;
 
   case SymbolKind::Enum: return CXIdxEntity_Enum;
@@ -1294,6 +1295,7 @@
   case SymbolKind::Constructor: return CXIdxEntity_CXXConstructor;
   case SymbolKind::Destructor: return CXIdxEntity_CXXDestructor;
   case SymbolKind::ConversionFunction: return CXIdxEntity_CXXConversionFunction;
+  case SymbolKind::Parameter: return CXIdxEntity_Variable;
   }
   llvm_unreachable("invalid symbol kind");
 }
@@ -1314,6 +1316,7 @@
   case SymbolLanguage::C: return CXIdxEntityLang_C;
   case SymbolLanguage::ObjC: return CXIdxEntityLang_ObjC;
   case SymbolLanguage::CXX: return CXIdxEntityLang_CXX;
+  case SymbolLanguage::Swift: return CXIdxEntityLang_Swift;
   }
   llvm_unreachable("invalid symbol language");
 }
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 66caf34..882929a 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -1036,3 +1036,12 @@
 
   return MakeCXType(QualType(), GetTU(CT));
 }
+
+unsigned clang_Type_isTransparentTagTypedef(CXType TT){
+  QualType T = GetQualType(TT);
+  if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) {
+    if (auto *D = TT->getDecl())
+      return D->isTransparentTag();
+  }
+  return false;
+}
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 222cb67..c979f16 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -35,6 +35,7 @@
 clang_Cursor_isAnonymous
 clang_Cursor_isBitField
 clang_Cursor_isDynamicCall
+clang_Cursor_isExternalSymbol
 clang_Cursor_isNull
 clang_Cursor_isObjCOptional
 clang_Cursor_isVariadic
@@ -88,6 +89,7 @@
 clang_Type_getCXXRefQualifier
 clang_Type_visitFields
 clang_Type_getNamedType
+clang_Type_isTransparentTagTypedef
 clang_VerbatimBlockLineComment_getText
 clang_VerbatimLineComment_getText
 clang_HTMLTagComment_getAsString
diff --git a/tools/scan-build/CMakeLists.txt b/tools/scan-build/CMakeLists.txt
index 78c243d..3803793 100644
--- a/tools/scan-build/CMakeLists.txt
+++ b/tools/scan-build/CMakeLists.txt
@@ -4,8 +4,11 @@
 
 if (WIN32 AND NOT CYGWIN)
   set(BinFiles
+        scan-build
         scan-build.bat)
   set(LibexecFiles
+        ccc-analyzer
+        c++-analyzer
         ccc-analyzer.bat
         c++-analyzer.bat)
 else()
diff --git a/unittests/AST/DeclTest.cpp b/unittests/AST/DeclTest.cpp
index 87aeef4..67b80ac 100644
--- a/unittests/AST/DeclTest.cpp
+++ b/unittests/AST/DeclTest.cpp
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "MatchVerifier.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
@@ -57,3 +58,53 @@
       "constexpr _Complex __uint128_t c = 0xffffffffffffffff;",
       Args));
 }
+
+TEST(Decl, Availability) {
+  const char *CodeStr = "int x __attribute__((availability(macosx, "
+        "introduced=10.2, deprecated=10.8, obsoleted=10.10)));";
+  auto Matcher = varDecl(hasName("x"));
+  std::vector<std::string> Args = {"-target", "x86_64-apple-macosx10.9"};
+
+  class AvailabilityVerifier : public MatchVerifier<clang::VarDecl> {
+  public:
+    void verify(const MatchFinder::MatchResult &Result,
+                const clang::VarDecl &Node) override {
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 1)) !=
+          clang::AR_NotYetIntroduced) {
+        setFailure("failed introduced");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 2)) !=
+          clang::AR_Available) {
+        setFailure("failed available (exact)");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 3)) !=
+          clang::AR_Available) {
+        setFailure("failed available");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 8)) !=
+          clang::AR_Deprecated) {
+        setFailure("failed deprecated (exact)");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 9)) !=
+          clang::AR_Deprecated) {
+        setFailure("failed deprecated");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 10)) !=
+          clang::AR_Unavailable) {
+        setFailure("failed obsoleted (exact)");
+      }
+      if (Node.getAvailability(nullptr, clang::VersionTuple(10, 11)) !=
+          clang::AR_Unavailable) {
+        setFailure("failed obsoleted");
+      }
+
+      if (Node.getAvailability() != clang::AR_Deprecated)
+        setFailure("did not default to target OS version");
+
+      setSuccess();
+    }
+  };
+
+  AvailabilityVerifier Verifier;
+  EXPECT_TRUE(Verifier.match(CodeStr, Matcher, Args, Lang_C));
+}
diff --git a/unittests/Analysis/CFGTest.cpp b/unittests/Analysis/CFGTest.cpp
index e691110..768705f 100644
--- a/unittests/Analysis/CFGTest.cpp
+++ b/unittests/Analysis/CFGTest.cpp
@@ -35,7 +35,9 @@
     if (!Body)
       return;
     TheBuildResult = SawFunctionBody;
-    if (CFG::buildCFG(nullptr, Body, Result.Context, CFG::BuildOptions()))
+    CFG::BuildOptions Options;
+    Options.AddImplicitDtors = true;
+    if (CFG::buildCFG(nullptr, Body, Result.Context, Options))
         TheBuildResult = BuiltCFG;
   }
 };
@@ -75,6 +77,16 @@
   EXPECT_EQ(BuiltCFG, BuildCFG(Code));
 }
 
+// Constructing a CFG on a function template with a variable of incomplete type
+// should not crash.
+TEST(CFG, VariableOfIncompleteType) {
+  const char *Code = "template<class T> void f() {\n"
+                     "  class Undefined;\n"
+                     "  Undefined u;\n"
+                     "}\n";
+  EXPECT_EQ(BuiltCFG, BuildCFG(Code));
+}
+
 } // namespace
 } // namespace analysis
 } // namespace clang
diff --git a/unittests/Analysis/CMakeLists.txt b/unittests/Analysis/CMakeLists.txt
index 926f586..62db8f6 100644
--- a/unittests/Analysis/CMakeLists.txt
+++ b/unittests/Analysis/CMakeLists.txt
@@ -2,11 +2,12 @@
   Support
   )
 
-add_clang_unittest(CFGTests
+add_clang_unittest(ClangAnalysisTests
   CFGTest.cpp
+  CloneDetectionTest.cpp
   )
 
-target_link_libraries(CFGTests
+target_link_libraries(ClangAnalysisTests
   clangAnalysis
   clangAST
   clangASTMatchers
diff --git a/unittests/Analysis/CloneDetectionTest.cpp b/unittests/Analysis/CloneDetectionTest.cpp
new file mode 100644
index 0000000..6d8ce34
--- /dev/null
+++ b/unittests/Analysis/CloneDetectionTest.cpp
@@ -0,0 +1,110 @@
+//===- unittests/Analysis/CloneDetectionTest.cpp - Clone detection tests --===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Analysis/CloneDetection.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace analysis {
+namespace {
+
+class CloneDetectionVisitor
+    : public RecursiveASTVisitor<CloneDetectionVisitor> {
+
+  CloneDetector &Detector;
+
+public:
+  explicit CloneDetectionVisitor(CloneDetector &D) : Detector(D) {}
+
+  bool VisitFunctionDecl(FunctionDecl *D) {
+    Detector.analyzeCodeBody(D);
+    return true;
+  }
+};
+
+/// Example constraint for testing purposes.
+/// Filters out all statements that are in a function which name starts with
+/// "bar".
+class NoBarFunctionConstraint {
+public:
+  void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
+    CloneConstraint::splitCloneGroups(
+        CloneGroups, [](const StmtSequence &A, const StmtSequence &B) {
+          // Check if one of the sequences is in a function which name starts
+          // with "bar".
+          for (const StmtSequence &Arg : {A, B}) {
+            if (const auto *D =
+                    dyn_cast<const FunctionDecl>(Arg.getContainingDecl())) {
+              if (D->getNameAsString().find("bar") == 0)
+                return false;
+            }
+          }
+          return true;
+        });
+  }
+};
+
+TEST(CloneDetector, FilterFunctionsByName) {
+  auto ASTUnit =
+      clang::tooling::buildASTFromCode("void foo1(int &a1) { a1++; }\n"
+                                       "void foo2(int &a2) { a2++; }\n"
+                                       "void bar1(int &a3) { a3++; }\n"
+                                       "void bar2(int &a4) { a4++; }\n");
+  auto TU = ASTUnit->getASTContext().getTranslationUnitDecl();
+
+  CloneDetector Detector;
+  // Push all the function bodies into the detector.
+  CloneDetectionVisitor Visitor(Detector);
+  Visitor.TraverseTranslationUnitDecl(TU);
+
+  // Find clones with the usual settings, but but we want to filter out
+  // all statements from functions which names start with "bar".
+  std::vector<CloneDetector::CloneGroup> CloneGroups;
+  Detector.findClones(CloneGroups, NoBarFunctionConstraint(),
+                      RecursiveCloneTypeIIConstraint(),
+                      MinComplexityConstraint(2), MinGroupSizeConstraint(2),
+                      OnlyLargestCloneConstraint());
+
+  ASSERT_EQ(CloneGroups.size(), 1u);
+  ASSERT_EQ(CloneGroups.front().size(), 2u);
+
+  for (auto &Clone : CloneGroups.front()) {
+    const auto ND = dyn_cast<const FunctionDecl>(Clone.getContainingDecl());
+    ASSERT_TRUE(ND != nullptr);
+    // Check that no function name starting with "bar" is in the results...
+    ASSERT_TRUE(ND->getNameAsString().find("bar") != 0);
+  }
+
+  // Retry above's example without the filter...
+  CloneGroups.clear();
+
+  Detector.findClones(CloneGroups, RecursiveCloneTypeIIConstraint(),
+                      MinComplexityConstraint(2), MinGroupSizeConstraint(2),
+                      OnlyLargestCloneConstraint());
+  ASSERT_EQ(CloneGroups.size(), 1u);
+  ASSERT_EQ(CloneGroups.front().size(), 4u);
+
+  // Count how many functions with the bar prefix we have in the results.
+  int FoundFunctionsWithBarPrefix = 0;
+  for (auto &Clone : CloneGroups.front()) {
+    const auto ND = dyn_cast<const FunctionDecl>(Clone.getContainingDecl());
+    ASSERT_TRUE(ND != nullptr);
+    // This time check that we picked up the bar functions from above
+    if (ND->getNameAsString().find("bar") == 0) {
+      FoundFunctionsWithBarPrefix++;
+    }
+  }
+  // We should have found the two functions bar1 and bar2.
+  ASSERT_EQ(FoundFunctionsWithBarPrefix, 2);
+}
+} // namespace
+} // namespace analysis
+} // namespace clang
diff --git a/unittests/Basic/CMakeLists.txt b/unittests/Basic/CMakeLists.txt
index 3cb3cb8..3a9f34f 100644
--- a/unittests/Basic/CMakeLists.txt
+++ b/unittests/Basic/CMakeLists.txt
@@ -6,6 +6,7 @@
   CharInfoTest.cpp
   DiagnosticTest.cpp
   FileManagerTest.cpp
+  MemoryBufferCacheTest.cpp
   SourceManagerTest.cpp
   VirtualFileSystemTest.cpp
   )
diff --git a/unittests/Basic/MemoryBufferCacheTest.cpp b/unittests/Basic/MemoryBufferCacheTest.cpp
new file mode 100644
index 0000000..be243c2
--- /dev/null
+++ b/unittests/Basic/MemoryBufferCacheTest.cpp
@@ -0,0 +1,94 @@
+//===- MemoryBufferCacheTest.cpp - MemoryBufferCache tests ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/MemoryBufferCache.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+
+std::unique_ptr<MemoryBuffer> getBuffer(int I) {
+  SmallVector<char, 8> Bytes;
+  raw_svector_ostream(Bytes) << "data:" << I;
+  return MemoryBuffer::getMemBuffer(StringRef(Bytes.data(), Bytes.size()));
+}
+
+TEST(MemoryBufferCacheTest, addBuffer) {
+  auto B1 = getBuffer(1);
+  auto B2 = getBuffer(2);
+  auto B3 = getBuffer(3);
+  auto *RawB1 = B1.get();
+  auto *RawB2 = B2.get();
+  auto *RawB3 = B3.get();
+
+  // Add a few buffers.
+  MemoryBufferCache Cache;
+  EXPECT_EQ(RawB1, &Cache.addBuffer("1", std::move(B1)));
+  EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));
+  EXPECT_EQ(RawB3, &Cache.addBuffer("3", std::move(B3)));
+  EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));
+  EXPECT_EQ(RawB2, Cache.lookupBuffer("2"));
+  EXPECT_EQ(RawB3, Cache.lookupBuffer("3"));
+  EXPECT_FALSE(Cache.isBufferFinal("1"));
+  EXPECT_FALSE(Cache.isBufferFinal("2"));
+  EXPECT_FALSE(Cache.isBufferFinal("3"));
+
+  // Remove the middle buffer.
+  EXPECT_FALSE(Cache.tryToRemoveBuffer("2"));
+  EXPECT_EQ(nullptr, Cache.lookupBuffer("2"));
+  EXPECT_FALSE(Cache.isBufferFinal("2"));
+
+  // Replace the middle buffer.
+  B2 = getBuffer(2);
+  ASSERT_NE(RawB2, B2.get());
+  RawB2 = B2.get();
+  EXPECT_EQ(RawB2, &Cache.addBuffer("2", std::move(B2)));
+
+  // Check that nothing is final.
+  EXPECT_FALSE(Cache.isBufferFinal("1"));
+  EXPECT_FALSE(Cache.isBufferFinal("2"));
+  EXPECT_FALSE(Cache.isBufferFinal("3"));
+}
+
+TEST(MemoryBufferCacheTest, finalizeCurrentBuffers) {
+  // Add a buffer.
+  MemoryBufferCache Cache;
+  auto B1 = getBuffer(1);
+  auto *RawB1 = B1.get();
+  Cache.addBuffer("1", std::move(B1));
+  ASSERT_FALSE(Cache.isBufferFinal("1"));
+
+  // Finalize it.
+  Cache.finalizeCurrentBuffers();
+  EXPECT_TRUE(Cache.isBufferFinal("1"));
+  EXPECT_TRUE(Cache.tryToRemoveBuffer("1"));
+  EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));
+  EXPECT_TRUE(Cache.isBufferFinal("1"));
+
+  // Repeat.
+  auto B2 = getBuffer(2);
+  auto *RawB2 = B2.get();
+  Cache.addBuffer("2", std::move(B2));
+  EXPECT_FALSE(Cache.isBufferFinal("2"));
+
+  Cache.finalizeCurrentBuffers();
+  EXPECT_TRUE(Cache.isBufferFinal("1"));
+  EXPECT_TRUE(Cache.isBufferFinal("2"));
+  EXPECT_TRUE(Cache.tryToRemoveBuffer("1"));
+  EXPECT_TRUE(Cache.tryToRemoveBuffer("2"));
+  EXPECT_EQ(RawB1, Cache.lookupBuffer("1"));
+  EXPECT_EQ(RawB2, Cache.lookupBuffer("2"));
+  EXPECT_TRUE(Cache.isBufferFinal("1"));
+  EXPECT_TRUE(Cache.isBufferFinal("2"));
+}
+
+} // namespace
diff --git a/unittests/Basic/SourceManagerTest.cpp b/unittests/Basic/SourceManagerTest.cpp
index a967b0e..dddc3f9 100644
--- a/unittests/Basic/SourceManagerTest.cpp
+++ b/unittests/Basic/SourceManagerTest.cpp
@@ -12,6 +12,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
 #include "clang/Lex/HeaderSearch.h"
@@ -78,10 +79,11 @@
   SourceMgr.setMainFileID(mainFileID);
 
   VoidModuleLoader ModLoader;
+  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, &*Target);
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, HeaderInfo, ModLoader,
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
@@ -198,10 +200,11 @@
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
 
   VoidModuleLoader ModLoader;
+  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, &*Target);
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, HeaderInfo, ModLoader,
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
@@ -298,10 +301,11 @@
   SourceMgr.overrideFileContents(headerFile, std::move(HeaderBuf));
 
   VoidModuleLoader ModLoader;
+  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, &*Target);
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, HeaderInfo, ModLoader,
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
diff --git a/unittests/Basic/VirtualFileSystemTest.cpp b/unittests/Basic/VirtualFileSystemTest.cpp
index 580343d..92e3663 100644
--- a/unittests/Basic/VirtualFileSystemTest.cpp
+++ b/unittests/Basic/VirtualFileSystemTest.cpp
@@ -305,6 +305,22 @@
   }
   operator StringRef() { return Path.str(); }
 };
+
+struct ScopedLink {
+  SmallString<128> Path;
+  ScopedLink(const Twine &To, const Twine &From) {
+    Path = From.str();
+    std::error_code EC = sys::fs::create_link(To, From);
+    if (EC)
+      Path = "";
+    EXPECT_FALSE(EC);
+  }
+  ~ScopedLink() {
+    if (Path != "")
+      EXPECT_FALSE(llvm::sys::fs::remove(Path.str()));
+  }
+  operator StringRef() { return Path.str(); }
+};
 } // end anonymous namespace
 
 TEST(VirtualFileSystemTest, BasicRealFSIteration) {
@@ -334,6 +350,36 @@
   EXPECT_EQ(vfs::directory_iterator(), I);
 }
 
+#ifdef LLVM_ON_UNIX
+TEST(VirtualFileSystemTest, BrokenSymlinkRealFSIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  ScopedLink _a("no_such_file", TestDirectory + "/a");
+  ScopedDir _b(TestDirectory + "/b");
+  ScopedLink _c("no_such_file", TestDirectory + "/c");
+
+  std::error_code EC;
+  for (vfs::directory_iterator I = FS->dir_begin(Twine(TestDirectory), EC), E;
+       I != E; I.increment(EC)) {
+    // Skip broken symlinks.
+    if (EC == std::errc::no_such_file_or_directory) {
+      EC = std::error_code();
+      continue;
+    }
+    // For bot debugging.
+    if (EC) {
+      outs() << "std::errc::no_such_file_or_directory: "
+             << (int)std::errc::no_such_file_or_directory << "\n";
+      outs() << "EC: " << EC.value() << "\n";
+      outs() << "EC message: " << EC.message() << "\n";
+    }
+    ASSERT_FALSE(EC);
+    EXPECT_TRUE(I->getName() == _b);
+  }
+}
+#endif
+
 TEST(VirtualFileSystemTest, BasicRealFSRecursiveIteration) {
   ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/true);
   IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
@@ -373,6 +419,50 @@
   EXPECT_EQ(1, Counts[3]); // d
 }
 
+#ifdef LLVM_ON_UNIX
+TEST(VirtualFileSystemTest, BrokenSymlinkRealFSRecursiveIteration) {
+  ScopedDir TestDirectory("virtual-file-system-test", /*Unique*/ true);
+  IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getRealFileSystem();
+
+  ScopedLink _a("no_such_file", TestDirectory + "/a");
+  ScopedDir _b(TestDirectory + "/b");
+  ScopedLink _ba("no_such_file", TestDirectory + "/b/a");
+  ScopedDir _bb(TestDirectory + "/b/b");
+  ScopedLink _bc("no_such_file", TestDirectory + "/b/c");
+  ScopedLink _c("no_such_file", TestDirectory + "/c");
+  ScopedDir _d(TestDirectory + "/d");
+  ScopedDir _dd(TestDirectory + "/d/d");
+  ScopedDir _ddd(TestDirectory + "/d/d/d");
+  ScopedLink _e("no_such_file", TestDirectory + "/e");
+  std::vector<StringRef> Expected = {_b, _bb, _d, _dd, _ddd};
+
+  std::vector<std::string> Contents;
+  std::error_code EC;
+  for (vfs::recursive_directory_iterator I(*FS, Twine(TestDirectory), EC), E;
+       I != E; I.increment(EC)) {
+    // Skip broken symlinks.
+    if (EC == std::errc::no_such_file_or_directory) {
+      EC = std::error_code();
+      continue;
+    }
+    // For bot debugging.
+    if (EC) {
+      outs() << "std::errc::no_such_file_or_directory: "
+             << (int)std::errc::no_such_file_or_directory << "\n";
+      outs() << "EC: " << EC.value() << "\n";
+      outs() << "EC message: " << EC.message() << "\n";
+    }
+    ASSERT_FALSE(EC);
+    Contents.push_back(I->getName());
+  }
+
+  // Check sorted contents.
+  std::sort(Contents.begin(), Contents.end());
+  EXPECT_EQ(Expected.size(), Contents.size());
+  EXPECT_TRUE(std::equal(Contents.begin(), Contents.end(), Expected.begin()));
+}
+#endif
+
 template <typename DirIter>
 static void checkContents(DirIter I, ArrayRef<StringRef> ExpectedOut) {
   std::error_code EC;
diff --git a/unittests/Format/CMakeLists.txt b/unittests/Format/CMakeLists.txt
index eb7756a..240be6e 100644
--- a/unittests/Format/CMakeLists.txt
+++ b/unittests/Format/CMakeLists.txt
@@ -7,7 +7,6 @@
   FormatTest.cpp
   FormatTestJava.cpp
   FormatTestJS.cpp
-  FormatTestObjC.cpp
   FormatTestProto.cpp
   FormatTestSelective.cpp
   SortImportsTestJS.cpp
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index fb14a6b..f1cc429 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -2493,6 +2493,42 @@
                Style);
 }
 
+TEST_F(FormatTest, FormatObjCTryCatch) {
+  verifyFormat("@try {\n"
+               "  f();\n"
+               "} @catch (NSException e) {\n"
+               "  @throw;\n"
+               "} @finally {\n"
+               "  exit(42);\n"
+               "}");
+  verifyFormat("DEBUG({\n"
+               "  @try {\n"
+               "  } @finally {\n"
+               "  }\n"
+               "});\n");
+}
+
+TEST_F(FormatTest, FormatObjCAutoreleasepool) {
+  FormatStyle Style = getLLVMStyle();
+  verifyFormat("@autoreleasepool {\n"
+               "  f();\n"
+               "}\n"
+               "@autoreleasepool {\n"
+               "  f();\n"
+               "}\n",
+               Style);
+  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
+  verifyFormat("@autoreleasepool\n"
+               "{\n"
+               "  f();\n"
+               "}\n"
+               "@autoreleasepool\n"
+               "{\n"
+               "  f();\n"
+               "}\n",
+               Style);
+}
+
 TEST_F(FormatTest, StaticInitializers) {
   verifyFormat("static SomeClass SC = {1, 'a'};");
 
@@ -7355,6 +7391,704 @@
   verifyGoogleFormat("- foo:(int)foo;");
 }
 
+TEST_F(FormatTest, FormatObjCInterface) {
+  verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
+               "@public\n"
+               "  int field1;\n"
+               "@protected\n"
+               "  int field2;\n"
+               "@private\n"
+               "  int field3;\n"
+               "@package\n"
+               "  int field4;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyGoogleFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
+                     " @public\n"
+                     "  int field1;\n"
+                     " @protected\n"
+                     "  int field2;\n"
+                     " @private\n"
+                     "  int field3;\n"
+                     " @package\n"
+                     "  int field4;\n"
+                     "}\n"
+                     "+ (id)init;\n"
+                     "@end");
+
+  verifyFormat("@interface /* wait for it */ Foo\n"
+               "+ (id)init;\n"
+               "// Look, a comment!\n"
+               "- (int)answerWith:(int)i;\n"
+               "@end");
+
+  verifyFormat("@interface Foo\n"
+               "@end\n"
+               "@interface Bar\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : /**/ Bar /**/ <Baz, /**/ Quux>\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyGoogleFormat("@interface Foo : Bar<Baz, Quux>\n"
+                     "+ (id)init;\n"
+                     "@end");
+
+  verifyFormat("@interface Foo (HackStuff)\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo ()\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyGoogleFormat("@interface Foo (HackStuff)<MyProtocol>\n"
+                     "+ (id)init;\n"
+                     "@end");
+
+  verifyFormat("@interface Foo {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo : Bar <Baz, Quux> {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff) {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo () {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  verifyFormat("@interface Foo (HackStuff) <MyProtocol> {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init;\n"
+               "@end");
+
+  FormatStyle OnePerLine = getGoogleStyle();
+  OnePerLine.BinPackParameters = false;
+  verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
+               "}",
+               OnePerLine);
+}
+
+TEST_F(FormatTest, FormatObjCImplementation) {
+  verifyFormat("@implementation Foo : NSObject {\n"
+               "@public\n"
+               "  int field1;\n"
+               "@protected\n"
+               "  int field2;\n"
+               "@private\n"
+               "  int field3;\n"
+               "@package\n"
+               "  int field4;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+
+  verifyGoogleFormat("@implementation Foo : NSObject {\n"
+                     " @public\n"
+                     "  int field1;\n"
+                     " @protected\n"
+                     "  int field2;\n"
+                     " @private\n"
+                     "  int field3;\n"
+                     " @package\n"
+                     "  int field4;\n"
+                     "}\n"
+                     "+ (id)init {\n}\n"
+                     "@end");
+
+  verifyFormat("@implementation Foo\n"
+               "+ (id)init {\n"
+               "  if (true)\n"
+               "    return nil;\n"
+               "}\n"
+               "// Look, a comment!\n"
+               "- (int)answerWith:(int)i {\n"
+               "  return i;\n"
+               "}\n"
+               "+ (int)answerWith:(int)i {\n"
+               "  return i;\n"
+               "}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo\n"
+               "@end\n"
+               "@implementation Bar\n"
+               "@end");
+
+  EXPECT_EQ("@implementation Foo : Bar\n"
+            "+ (id)init {\n}\n"
+            "- (void)foo {\n}\n"
+            "@end",
+            format("@implementation Foo : Bar\n"
+                   "+(id)init{}\n"
+                   "-(void)foo{}\n"
+                   "@end"));
+
+  verifyFormat("@implementation Foo {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo : Bar {\n"
+               "  int _i;\n"
+               "}\n"
+               "+ (id)init {\n}\n"
+               "@end");
+
+  verifyFormat("@implementation Foo (HackStuff)\n"
+               "+ (id)init {\n}\n"
+               "@end");
+  verifyFormat("@implementation ObjcClass\n"
+               "- (void)method;\n"
+               "{}\n"
+               "@end");
+}
+
+TEST_F(FormatTest, FormatObjCProtocol) {
+  verifyFormat("@protocol Foo\n"
+               "@property(weak) id delegate;\n"
+               "- (NSUInteger)numberOfThings;\n"
+               "@end");
+
+  verifyFormat("@protocol MyProtocol <NSObject>\n"
+               "- (NSUInteger)numberOfThings;\n"
+               "@end");
+
+  verifyGoogleFormat("@protocol MyProtocol<NSObject>\n"
+                     "- (NSUInteger)numberOfThings;\n"
+                     "@end");
+
+  verifyFormat("@protocol Foo;\n"
+               "@protocol Bar;\n");
+
+  verifyFormat("@protocol Foo\n"
+               "@end\n"
+               "@protocol Bar\n"
+               "@end");
+
+  verifyFormat("@protocol myProtocol\n"
+               "- (void)mandatoryWithInt:(int)i;\n"
+               "@optional\n"
+               "- (void)optional;\n"
+               "@required\n"
+               "- (void)required;\n"
+               "@optional\n"
+               "@property(assign) int madProp;\n"
+               "@end\n");
+
+  verifyFormat("@property(nonatomic, assign, readonly)\n"
+               "    int *looooooooooooooooooooooooooooongNumber;\n"
+               "@property(nonatomic, assign, readonly)\n"
+               "    NSString *looooooooooooooooooooooooooooongName;");
+
+  verifyFormat("@implementation PR18406\n"
+               "}\n"
+               "@end");
+}
+
+TEST_F(FormatTest, FormatObjCMethodDeclarations) {
+  verifyFormat("- (void)doSomethingWith:(GTMFoo *)theFoo\n"
+               "                   rect:(NSRect)theRect\n"
+               "               interval:(float)theInterval {\n"
+               "}");
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "      longKeyword:(NSRect)theRect\n"
+               "    longerKeyword:(float)theInterval\n"
+               "            error:(NSError **)theError {\n"
+               "}");
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "          longKeyword:(NSRect)theRect\n"
+               "    evenLongerKeyword:(float)theInterval\n"
+               "                error:(NSError **)theError {\n"
+               "}");
+  verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n"
+               "                         y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n"
+               "    NS_DESIGNATED_INITIALIZER;",
+               getLLVMStyleWithColumns(60));
+
+  // Continuation indent width should win over aligning colons if the function
+  // name is long.
+  FormatStyle continuationStyle = getGoogleStyle();
+  continuationStyle.ColumnLimit = 40;
+  continuationStyle.IndentWrappedFunctionNames = true;
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "    dontAlignNamef:(NSRect)theRect {\n"
+               "}",
+               continuationStyle);
+
+  // Make sure we don't break aligning for short parameter names.
+  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
+               "       aShortf:(NSRect)theRect {\n"
+               "}",
+               continuationStyle);
+
+  // Format pairs correctly.
+  verifyFormat("- (void)drawRectOn:(id)surface\n"
+               "            ofSize:(aaaaaaaa)height\n"
+               "                  :(size_t)width\n"
+               "          atOrigin:(size_t)x\n"
+               "                  :(size_t)y\n"
+               "             aaaaa:(a)yyy\n"
+               "               bbb:(d)cccc;");
+  verifyFormat("- (void)drawRectOn:(id)surface ofSize:(aaa)height:(bbb)width;");
+  verifyFormat("- (void)drawRectOn:(id)surface\n"
+               "            ofSize:(size_t)height\n"
+               "                  :(size_t)width;",
+               getLLVMStyleWithColumns(60));
+}
+
+TEST_F(FormatTest, FormatObjCMethodExpr) {
+  verifyFormat("[foo bar:baz];");
+  verifyFormat("return [foo bar:baz];");
+  verifyFormat("return (a)[foo bar:baz];");
+  verifyFormat("f([foo bar:baz]);");
+  verifyFormat("f(2, [foo bar:baz]);");
+  verifyFormat("f(2, a ? b : c);");
+  verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];");
+
+  // Unary operators.
+  verifyFormat("int a = +[foo bar:baz];");
+  verifyFormat("int a = -[foo bar:baz];");
+  verifyFormat("int a = ![foo bar:baz];");
+  verifyFormat("int a = ~[foo bar:baz];");
+  verifyFormat("int a = ++[foo bar:baz];");
+  verifyFormat("int a = --[foo bar:baz];");
+  verifyFormat("int a = sizeof [foo bar:baz];");
+  verifyFormat("int a = alignof [foo bar:baz];", getGoogleStyle());
+  verifyFormat("int a = &[foo bar:baz];");
+  verifyFormat("int a = *[foo bar:baz];");
+  // FIXME: Make casts work, without breaking f()[4].
+  // verifyFormat("int a = (int)[foo bar:baz];");
+  // verifyFormat("return (int)[foo bar:baz];");
+  // verifyFormat("(void)[foo bar:baz];");
+  verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];");
+
+  // Binary operators.
+  verifyFormat("[foo bar:baz], [foo bar:baz];");
+  verifyFormat("[foo bar:baz] = [foo bar:baz];");
+  verifyFormat("[foo bar:baz] *= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] /= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] %= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] += [foo bar:baz];");
+  verifyFormat("[foo bar:baz] -= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] <<= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] >>= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] &= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] ^= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] |= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];");
+  verifyFormat("[foo bar:baz] || [foo bar:baz];");
+  verifyFormat("[foo bar:baz] && [foo bar:baz];");
+  verifyFormat("[foo bar:baz] | [foo bar:baz];");
+  verifyFormat("[foo bar:baz] ^ [foo bar:baz];");
+  verifyFormat("[foo bar:baz] & [foo bar:baz];");
+  verifyFormat("[foo bar:baz] == [foo bar:baz];");
+  verifyFormat("[foo bar:baz] != [foo bar:baz];");
+  verifyFormat("[foo bar:baz] >= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] <= [foo bar:baz];");
+  verifyFormat("[foo bar:baz] > [foo bar:baz];");
+  verifyFormat("[foo bar:baz] < [foo bar:baz];");
+  verifyFormat("[foo bar:baz] >> [foo bar:baz];");
+  verifyFormat("[foo bar:baz] << [foo bar:baz];");
+  verifyFormat("[foo bar:baz] - [foo bar:baz];");
+  verifyFormat("[foo bar:baz] + [foo bar:baz];");
+  verifyFormat("[foo bar:baz] * [foo bar:baz];");
+  verifyFormat("[foo bar:baz] / [foo bar:baz];");
+  verifyFormat("[foo bar:baz] % [foo bar:baz];");
+  // Whew!
+
+  verifyFormat("return in[42];");
+  verifyFormat("for (auto v : in[1]) {\n}");
+  verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}");
+  verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}");
+  verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}");
+  verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}");
+  verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}");
+  verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"
+               "}");
+  verifyFormat("[self aaaaa:MACRO(a, b:, c:)];");
+  verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];");
+  verifyFormat("[self aaaaa:(Type)a bbbbb:3];");
+
+  verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");
+  verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");
+  verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");
+  verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];");
+  verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]");
+  verifyFormat("[button setAction:@selector(zoomOut:)];");
+  verifyFormat("[color getRed:&r green:&g blue:&b alpha:&a];");
+
+  verifyFormat("arr[[self indexForFoo:a]];");
+  verifyFormat("throw [self errorFor:a];");
+  verifyFormat("@throw [self errorFor:a];");
+
+  verifyFormat("[(id)foo bar:(id)baz quux:(id)snorf];");
+  verifyFormat("[(id)foo bar:(id) ? baz : quux];");
+  verifyFormat("4 > 4 ? (id)a : (id)baz;");
+
+  // This tests that the formatter doesn't break after "backing" but before ":",
+  // which would be at 80 columns.
+  verifyFormat(
+      "void f() {\n"
+      "  if ((self = [super initWithContentRect:contentRect\n"
+      "                               styleMask:styleMask ?: otherMask\n"
+      "                                 backing:NSBackingStoreBuffered\n"
+      "                                   defer:YES]))");
+
+  verifyFormat(
+      "[foo checkThatBreakingAfterColonWorksOk:\n"
+      "         [bar ifItDoes:reduceOverallLineLengthLikeInThisCase]];");
+
+  verifyFormat("[myObj short:arg1 // Force line break\n"
+               "          longKeyword:arg2 != nil ? arg2 : @\"longKeyword\"\n"
+               "    evenLongerKeyword:arg3 ?: @\"evenLongerKeyword\"\n"
+               "                error:arg4];");
+  verifyFormat(
+      "void f() {\n"
+      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
+      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
+      "                                     pos.width(), pos.height())\n"
+      "                styleMask:NSBorderlessWindowMask\n"
+      "                  backing:NSBackingStoreBuffered\n"
+      "                    defer:NO]);\n"
+      "}");
+  verifyFormat(
+      "void f() {\n"
+      "  popup_wdow_.reset([[RenderWidgetPopupWindow alloc]\n"
+      "      iniithContentRect:NSMakRet(origin_global.x, origin_global.y,\n"
+      "                                 pos.width(), pos.height())\n"
+      "                syeMask:NSBorderlessWindowMask\n"
+      "                  bking:NSBackingStoreBuffered\n"
+      "                    der:NO]);\n"
+      "}",
+      getLLVMStyleWithColumns(70));
+  verifyFormat(
+      "void f() {\n"
+      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
+      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
+      "                                     pos.width(), pos.height())\n"
+      "                styleMask:NSBorderlessWindowMask\n"
+      "                  backing:NSBackingStoreBuffered\n"
+      "                    defer:NO]);\n"
+      "}",
+      getChromiumStyle(FormatStyle::LK_Cpp));
+  verifyFormat("[contentsContainer replaceSubview:[subviews objectAtIndex:0]\n"
+               "                             with:contentsNativeView];");
+
+  verifyFormat(
+      "[pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]\n"
+      "           owner:nillllll];");
+
+  verifyFormat(
+      "[pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]\n"
+      "        forType:kBookmarkButtonDragType];");
+
+  verifyFormat("[defaultCenter addObserver:self\n"
+               "                  selector:@selector(willEnterFullscreen)\n"
+               "                      name:kWillEnterFullscreenNotification\n"
+               "                    object:nil];");
+  verifyFormat("[image_rep drawInRect:drawRect\n"
+               "             fromRect:NSZeroRect\n"
+               "            operation:NSCompositeCopy\n"
+               "             fraction:1.0\n"
+               "       respectFlipped:NO\n"
+               "                hints:nil];");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n"
+               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
+  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n"
+               "    aaaaaaaaaaaaaaaaaaaaaa];");
+  verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n"
+               "        .aaaaaaaa];", // FIXME: Indentation seems off.
+               getLLVMStyleWithColumns(60));
+
+  verifyFormat(
+      "scoped_nsobject<NSTextField> message(\n"
+      "    // The frame will be fixed up when |-setMessageText:| is called.\n"
+      "    [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);");
+  verifyFormat("[self aaaaaa:bbbbbbbbbbbbb\n"
+               "    aaaaaaaaaa:bbbbbbbbbbbbbbbbb\n"
+               "         aaaaa:bbbbbbbbbbb + bbbbbbbbbbbb\n"
+               "          aaaa:bbb];");
+  verifyFormat("[self param:function( //\n"
+               "                parameter)]");
+  verifyFormat(
+      "[self aaaaaaaaaa:aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
+      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
+      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];");
+
+  // FIXME: This violates the column limit.
+  verifyFormat(
+      "[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
+      "    aaaaaaaaaaaaaaaaa:aaaaaaaa\n"
+      "                  aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];",
+      getLLVMStyleWithColumns(60));
+
+  // Variadic parameters.
+  verifyFormat(
+      "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];");
+  verifyFormat(
+      "[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
+      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
+      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];");
+  verifyFormat("[self // break\n"
+               "      a:a\n"
+               "    aaa:aaa];");
+  verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
+               "          [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
+
+  // Formats pair-parameters.
+  verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
+  verifyFormat("[I drawRectOn:surface //\n"
+               "        ofSize:aa:bbb\n"
+               "      atOrigin:cc:dd];");
+}
+
+TEST_F(FormatTest, ObjCAt) {
+  verifyFormat("@autoreleasepool");
+  verifyFormat("@catch");
+  verifyFormat("@class");
+  verifyFormat("@compatibility_alias");
+  verifyFormat("@defs");
+  verifyFormat("@dynamic");
+  verifyFormat("@encode");
+  verifyFormat("@end");
+  verifyFormat("@finally");
+  verifyFormat("@implementation");
+  verifyFormat("@import");
+  verifyFormat("@interface");
+  verifyFormat("@optional");
+  verifyFormat("@package");
+  verifyFormat("@private");
+  verifyFormat("@property");
+  verifyFormat("@protected");
+  verifyFormat("@protocol");
+  verifyFormat("@public");
+  verifyFormat("@required");
+  verifyFormat("@selector");
+  verifyFormat("@synchronized");
+  verifyFormat("@synthesize");
+  verifyFormat("@throw");
+  verifyFormat("@try");
+
+  EXPECT_EQ("@interface", format("@ interface"));
+
+  // The precise formatting of this doesn't matter, nobody writes code like
+  // this.
+  verifyFormat("@ /*foo*/ interface");
+}
+
+TEST_F(FormatTest, ObjCSnippets) {
+  verifyFormat("@autoreleasepool {\n"
+               "  foo();\n"
+               "}");
+  verifyFormat("@class Foo, Bar;");
+  verifyFormat("@compatibility_alias AliasName ExistingClass;");
+  verifyFormat("@dynamic textColor;");
+  verifyFormat("char *buf1 = @encode(int *);");
+  verifyFormat("char *buf1 = @encode(typeof(4 * 5));");
+  verifyFormat("char *buf1 = @encode(int **);");
+  verifyFormat("Protocol *proto = @protocol(p1);");
+  verifyFormat("SEL s = @selector(foo:);");
+  verifyFormat("@synchronized(self) {\n"
+               "  f();\n"
+               "}");
+
+  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
+  verifyGoogleFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
+
+  verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");
+  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
+  verifyGoogleFormat("@property(assign, getter=isEditable) BOOL editable;");
+  verifyFormat("@property (assign, getter=isEditable) BOOL editable;",
+               getMozillaStyle());
+  verifyFormat("@property BOOL editable;", getMozillaStyle());
+  verifyFormat("@property (assign, getter=isEditable) BOOL editable;",
+               getWebKitStyle());
+  verifyFormat("@property BOOL editable;", getWebKitStyle());
+
+  verifyFormat("@import foo.bar;\n"
+               "@import baz;");
+}
+
+TEST_F(FormatTest, ObjCForIn) {
+  verifyFormat("- (void)test {\n"
+               "  for (NSString *n in arrayOfStrings) {\n"
+               "    foo(n);\n"
+               "  }\n"
+               "}");
+  verifyFormat("- (void)test {\n"
+               "  for (NSString *n in (__bridge NSArray *)arrayOfStrings) {\n"
+               "    foo(n);\n"
+               "  }\n"
+               "}");
+}
+
+TEST_F(FormatTest, ObjCLiterals) {
+  verifyFormat("@\"String\"");
+  verifyFormat("@1");
+  verifyFormat("@+4.8");
+  verifyFormat("@-4");
+  verifyFormat("@1LL");
+  verifyFormat("@.5");
+  verifyFormat("@'c'");
+  verifyFormat("@true");
+
+  verifyFormat("NSNumber *smallestInt = @(-INT_MAX - 1);");
+  verifyFormat("NSNumber *piOverTwo = @(M_PI / 2);");
+  verifyFormat("NSNumber *favoriteColor = @(Green);");
+  verifyFormat("NSString *path = @(getenv(\"PATH\"));");
+
+  verifyFormat("[dictionary setObject:@(1) forKey:@\"number\"];");
+}
+
+TEST_F(FormatTest, ObjCDictLiterals) {
+  verifyFormat("@{");
+  verifyFormat("@{}");
+  verifyFormat("@{@\"one\" : @1}");
+  verifyFormat("return @{@\"one\" : @1;");
+  verifyFormat("@{@\"one\" : @1}");
+
+  verifyFormat("@{@\"one\" : @{@2 : @1}}");
+  verifyFormat("@{\n"
+               "  @\"one\" : @{@2 : @1},\n"
+               "}");
+
+  verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");
+  verifyIncompleteFormat("[self setDict:@{}");
+  verifyIncompleteFormat("[self setDict:@{@1 : @2}");
+  verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");
+  verifyFormat(
+      "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");
+  verifyFormat(
+      "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};");
+
+  verifyFormat("NSDictionary *d = @{\n"
+               "  @\"nam\" : NSUserNam(),\n"
+               "  @\"dte\" : [NSDate date],\n"
+               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
+               "};");
+  verifyFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
+      "regularFont,\n"
+      "};");
+  verifyGoogleFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
+      "regularFont,\n"
+      "};");
+  verifyFormat(
+      "@{\n"
+      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n"
+      "      reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n"
+      "};");
+
+  // We should try to be robust in case someone forgets the "@".
+  verifyFormat("NSDictionary *d = {\n"
+               "  @\"nam\" : NSUserNam(),\n"
+               "  @\"dte\" : [NSDate date],\n"
+               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
+               "};");
+  verifyFormat("NSMutableDictionary *dictionary =\n"
+               "    [NSMutableDictionary dictionaryWithDictionary:@{\n"
+               "      aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"
+               "      bbbbbbbbbbbbbbbbbb : bbbbb,\n"
+               "      cccccccccccccccc : ccccccccccccccc\n"
+               "    }];");
+
+  // Ensure that casts before the key are kept on the same line as the key.
+  verifyFormat(
+      "NSDictionary *d = @{\n"
+      "  (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n"
+      "  (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n"
+      "};");
+}
+
+TEST_F(FormatTest, ObjCArrayLiterals) {
+  verifyIncompleteFormat("@[");
+  verifyFormat("@[]");
+  verifyFormat(
+      "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");
+  verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];");
+  verifyFormat("NSArray *array = @[ [foo description] ];");
+
+  verifyFormat(
+      "NSArray *some_variable = @[\n"
+      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaaa\",\n"
+      "];");
+  verifyFormat(
+      "NSArray *some_variable = @[\n"
+      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
+      "  @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\"\n"
+      "];");
+  verifyFormat("NSArray *some_variable = @[\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "];");
+  verifyFormat("NSArray *array = @[\n"
+               "  @\"a\",\n"
+               "  @\"a\",\n" // Trailing comma -> one per line.
+               "];");
+
+  // We should try to be robust in case someone forgets the "@".
+  verifyFormat("NSArray *some_variable = [\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "  @\"aaaaaaaaaaaaaaaaa\",\n"
+               "];");
+  verifyFormat(
+      "- (NSAttributedString *)attributedStringForSegment:(NSUInteger)segment\n"
+      "                                             index:(NSUInteger)index\n"
+      "                                nonDigitAttributes:\n"
+      "                                    (NSDictionary *)noDigitAttributes;");
+  verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
+               "  NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
+               "]];");
+}
 
 TEST_F(FormatTest, BreaksStringLiterals) {
   EXPECT_EQ("\"some text \"\n"
@@ -10960,13 +11694,13 @@
                  llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: LLVM")));
   ASSERT_TRUE(
       FS.addFile("/a/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style1 = getStyle("file", "/a/.clang-format", "Google", "", &FS);
+  auto Style1 = getStyle("file", "/a/.clang-format", "Google", &FS);
   ASSERT_EQ(Style1, getLLVMStyle());
 
   // Test 2: fallback to default.
   ASSERT_TRUE(
       FS.addFile("/b/test.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", "", &FS);
+  auto Style2 = getStyle("file", "/b/test.cpp", "Mozilla", &FS);
   ASSERT_EQ(Style2, getMozillaStyle());
 
   // Test 3: format file in parent directory.
@@ -10975,7 +11709,7 @@
                  llvm::MemoryBuffer::getMemBuffer("BasedOnStyle: Google")));
   ASSERT_TRUE(FS.addFile("/c/sub/sub/sub/test.cpp", 0,
                          llvm::MemoryBuffer::getMemBuffer("int i;")));
-  auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", "", &FS);
+  auto Style3 = getStyle("file", "/c/sub/sub/sub/test.cpp", "LLVM", &FS);
   ASSERT_EQ(Style3, getGoogleStyle());
 }
 
diff --git a/unittests/Format/FormatTestObjC.cpp b/unittests/Format/FormatTestObjC.cpp
deleted file mode 100644
index 6a530f9..0000000
--- a/unittests/Format/FormatTestObjC.cpp
+++ /dev/null
@@ -1,822 +0,0 @@
-//===- unittest/Format/FormatTestObjC.cpp - Formatting unit tests----------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Format/Format.h"
-
-#include "../Tooling/ReplacementTest.h"
-#include "FormatTestUtils.h"
-
-#include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "gtest/gtest.h"
-
-#define DEBUG_TYPE "format-test"
-
-using clang::tooling::ReplacementTest;
-using clang::tooling::toReplacements;
-
-namespace clang {
-namespace format {
-namespace {
-
-class FormatTestObjC : public ::testing::Test {
-protected:
-  FormatTestObjC() {
-    Style = getLLVMStyle();
-    Style.Language = FormatStyle::LK_ObjC;
-  }
-
-  enum IncompleteCheck {
-    IC_ExpectComplete,
-    IC_ExpectIncomplete,
-    IC_DoNotCheck
-  };
-
-  std::string format(llvm::StringRef Code,
-                     IncompleteCheck CheckIncomplete = IC_ExpectComplete) {
-    DEBUG(llvm::errs() << "---\n");
-    DEBUG(llvm::errs() << Code << "\n\n");
-    std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
-    bool IncompleteFormat = false;
-    tooling::Replacements Replaces =
-        reformat(Style, Code, Ranges, "<stdin>", &IncompleteFormat);
-    if (CheckIncomplete != IC_DoNotCheck) {
-      bool ExpectedIncompleteFormat = CheckIncomplete == IC_ExpectIncomplete;
-      EXPECT_EQ(ExpectedIncompleteFormat, IncompleteFormat) << Code << "\n\n";
-    }
-    auto Result = applyAllReplacements(Code, Replaces);
-    EXPECT_TRUE(static_cast<bool>(Result));
-    DEBUG(llvm::errs() << "\n" << *Result << "\n\n");
-    return *Result;
-  }
-
-  void verifyFormat(StringRef Code) {
-    EXPECT_EQ(Code.str(), format(test::messUp(Code)));
-  }
-
-  void verifyIncompleteFormat(StringRef Code) {
-    EXPECT_EQ(Code.str(), format(test::messUp(Code), IC_ExpectIncomplete));
-  }
-
-  FormatStyle Style;
-};
-
-TEST_F(FormatTestObjC, DetectsObjCInHeaders) {
-  Style = getStyle("LLVM", "a.h", "none", "@interface\n"
-                                          "- (id)init;");
-  EXPECT_EQ(FormatStyle::LK_ObjC, Style.Language);
-  Style = getStyle("LLVM", "a.h", "none", "@interface\n"
-                                          "+ (id)init;");
-  EXPECT_EQ(FormatStyle::LK_ObjC, Style.Language);
-
-  // No recognizable ObjC.
-  Style = getStyle("LLVM", "a.h", "none", "void f() {}");
-  EXPECT_EQ(FormatStyle::LK_Cpp, Style.Language);
-}
-
-TEST_F(FormatTestObjC, FormatObjCTryCatch) {
-  verifyFormat("@try {\n"
-               "  f();\n"
-               "} @catch (NSException e) {\n"
-               "  @throw;\n"
-               "} @finally {\n"
-               "  exit(42);\n"
-               "}");
-  verifyFormat("DEBUG({\n"
-               "  @try {\n"
-               "  } @finally {\n"
-               "  }\n"
-               "});\n");
-}
-
-TEST_F(FormatTestObjC, FormatObjCAutoreleasepool) {
-  verifyFormat("@autoreleasepool {\n"
-               "  f();\n"
-               "}\n"
-               "@autoreleasepool {\n"
-               "  f();\n"
-               "}\n");
-  Style.BreakBeforeBraces = FormatStyle::BS_Allman;
-  verifyFormat("@autoreleasepool\n"
-               "{\n"
-               "  f();\n"
-               "}\n"
-               "@autoreleasepool\n"
-               "{\n"
-               "  f();\n"
-               "}\n");
-}
-
-TEST_F(FormatTestObjC, FormatObjCInterface) {
-  verifyFormat("@interface Foo : NSObject <NSSomeDelegate> {\n"
-               "@public\n"
-               "  int field1;\n"
-               "@protected\n"
-               "  int field2;\n"
-               "@private\n"
-               "  int field3;\n"
-               "@package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface /* wait for it */ Foo\n"
-               "+ (id)init;\n"
-               "// Look, a comment!\n"
-               "- (int)answerWith:(int)i;\n"
-               "@end");
-
-  verifyFormat("@interface Foo\n"
-               "@end\n"
-               "@interface Bar\n"
-               "@end");
-
-  verifyFormat("@interface Foo : Bar\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo : /**/ Bar /**/ <Baz, /**/ Quux>\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff)\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo ()\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff) <MyProtocol>\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo : Bar {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo : Bar <Baz, Quux> {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff) {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo () {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  verifyFormat("@interface Foo (HackStuff) <MyProtocol> {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat("@interface Foo : NSObject<NSSomeDelegate> {\n"
-               " @public\n"
-               "  int field1;\n"
-               " @protected\n"
-               "  int field2;\n"
-               " @private\n"
-               "  int field3;\n"
-               " @package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init;\n"
-               "@end");
-  verifyFormat("@interface Foo : Bar<Baz, Quux>\n"
-               "+ (id)init;\n"
-               "@end");
-  verifyFormat("@interface Foo (HackStuff)<MyProtocol>\n"
-               "+ (id)init;\n"
-               "@end");
-  Style.BinPackParameters = false;
-  Style.ColumnLimit = 80;
-  verifyFormat("@interface aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa ()<\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa> {\n"
-               "}");
-}
-
-TEST_F(FormatTestObjC, FormatObjCImplementation) {
-  verifyFormat("@implementation Foo : NSObject {\n"
-               "@public\n"
-               "  int field1;\n"
-               "@protected\n"
-               "  int field2;\n"
-               "@private\n"
-               "  int field3;\n"
-               "@package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo\n"
-               "+ (id)init {\n"
-               "  if (true)\n"
-               "    return nil;\n"
-               "}\n"
-               "// Look, a comment!\n"
-               "- (int)answerWith:(int)i {\n"
-               "  return i;\n"
-               "}\n"
-               "+ (int)answerWith:(int)i {\n"
-               "  return i;\n"
-               "}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo\n"
-               "@end\n"
-               "@implementation Bar\n"
-               "@end");
-
-  EXPECT_EQ("@implementation Foo : Bar\n"
-            "+ (id)init {\n}\n"
-            "- (void)foo {\n}\n"
-            "@end",
-            format("@implementation Foo : Bar\n"
-                   "+(id)init{}\n"
-                   "-(void)foo{}\n"
-                   "@end"));
-
-  verifyFormat("@implementation Foo {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo : Bar {\n"
-               "  int _i;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-
-  verifyFormat("@implementation Foo (HackStuff)\n"
-               "+ (id)init {\n}\n"
-               "@end");
-  verifyFormat("@implementation ObjcClass\n"
-               "- (void)method;\n"
-               "{}\n"
-               "@end");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat("@implementation Foo : NSObject {\n"
-               " @public\n"
-               "  int field1;\n"
-               " @protected\n"
-               "  int field2;\n"
-               " @private\n"
-               "  int field3;\n"
-               " @package\n"
-               "  int field4;\n"
-               "}\n"
-               "+ (id)init {\n}\n"
-               "@end");
-}
-
-TEST_F(FormatTestObjC, FormatObjCProtocol) {
-  verifyFormat("@protocol Foo\n"
-               "@property(weak) id delegate;\n"
-               "- (NSUInteger)numberOfThings;\n"
-               "@end");
-
-  verifyFormat("@protocol MyProtocol <NSObject>\n"
-               "- (NSUInteger)numberOfThings;\n"
-               "@end");
-
-  verifyFormat("@protocol Foo;\n"
-               "@protocol Bar;\n");
-
-  verifyFormat("@protocol Foo\n"
-               "@end\n"
-               "@protocol Bar\n"
-               "@end");
-
-  verifyFormat("@protocol myProtocol\n"
-               "- (void)mandatoryWithInt:(int)i;\n"
-               "@optional\n"
-               "- (void)optional;\n"
-               "@required\n"
-               "- (void)required;\n"
-               "@optional\n"
-               "@property(assign) int madProp;\n"
-               "@end\n");
-
-  verifyFormat("@property(nonatomic, assign, readonly)\n"
-               "    int *looooooooooooooooooooooooooooongNumber;\n"
-               "@property(nonatomic, assign, readonly)\n"
-               "    NSString *looooooooooooooooooooooooooooongName;");
-
-  verifyFormat("@implementation PR18406\n"
-               "}\n"
-               "@end");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat("@protocol MyProtocol<NSObject>\n"
-               "- (NSUInteger)numberOfThings;\n"
-               "@end");
-}
-
-TEST_F(FormatTestObjC, FormatObjCMethodDeclarations) {
-  verifyFormat("- (void)doSomethingWith:(GTMFoo *)theFoo\n"
-               "                   rect:(NSRect)theRect\n"
-               "               interval:(float)theInterval {\n"
-               "}");
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "      longKeyword:(NSRect)theRect\n"
-               "    longerKeyword:(float)theInterval\n"
-               "            error:(NSError **)theError {\n"
-               "}");
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "          longKeyword:(NSRect)theRect\n"
-               "    evenLongerKeyword:(float)theInterval\n"
-               "                error:(NSError **)theError {\n"
-               "}");
-  Style.ColumnLimit = 60;
-  verifyFormat("- (instancetype)initXxxxxx:(id<x>)x\n"
-               "                         y:(id<yyyyyyyyyyyyyyyyyyyy>)y\n"
-               "    NS_DESIGNATED_INITIALIZER;");
-  verifyFormat("- (void)drawRectOn:(id)surface\n"
-               "            ofSize:(size_t)height\n"
-               "                  :(size_t)width;");
-
-  // Continuation indent width should win over aligning colons if the function
-  // name is long.
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  Style.ColumnLimit = 40;
-  Style.IndentWrappedFunctionNames = true;
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "    dontAlignNamef:(NSRect)theRect {\n"
-               "}");
-
-  // Make sure we don't break aligning for short parameter names.
-  verifyFormat("- (void)shortf:(GTMFoo *)theFoo\n"
-               "       aShortf:(NSRect)theRect {\n"
-               "}");
-
-  // Format pairs correctly.
-  Style.ColumnLimit = 80;
-  verifyFormat("- (void)drawRectOn:(id)surface\n"
-               "            ofSize:(aaaaaaaa)height\n"
-               "                  :(size_t)width\n"
-               "          atOrigin:(size_t)x\n"
-               "                  :(size_t)y\n"
-               "             aaaaa:(a)yyy\n"
-               "               bbb:(d)cccc;");
-  verifyFormat("- (void)drawRectOn:(id)surface ofSize:(aaa)height:(bbb)width;");
-}
-
-TEST_F(FormatTestObjC, FormatObjCMethodExpr) {
-  verifyFormat("[foo bar:baz];");
-  verifyFormat("return [foo bar:baz];");
-  verifyFormat("return (a)[foo bar:baz];");
-  verifyFormat("f([foo bar:baz]);");
-  verifyFormat("f(2, [foo bar:baz]);");
-  verifyFormat("f(2, a ? b : c);");
-  verifyFormat("[[self initWithInt:4] bar:[baz quux:arrrr]];");
-
-  // Unary operators.
-  verifyFormat("int a = +[foo bar:baz];");
-  verifyFormat("int a = -[foo bar:baz];");
-  verifyFormat("int a = ![foo bar:baz];");
-  verifyFormat("int a = ~[foo bar:baz];");
-  verifyFormat("int a = ++[foo bar:baz];");
-  verifyFormat("int a = --[foo bar:baz];");
-  verifyFormat("int a = sizeof [foo bar:baz];");
-  verifyFormat("int a = alignof [foo bar:baz];");
-  verifyFormat("int a = &[foo bar:baz];");
-  verifyFormat("int a = *[foo bar:baz];");
-  // FIXME: Make casts work, without breaking f()[4].
-  // verifyFormat("int a = (int)[foo bar:baz];");
-  // verifyFormat("return (int)[foo bar:baz];");
-  // verifyFormat("(void)[foo bar:baz];");
-  verifyFormat("return (MyType *)[self.tableView cellForRowAtIndexPath:cell];");
-
-  // Binary operators.
-  verifyFormat("[foo bar:baz], [foo bar:baz];");
-  verifyFormat("[foo bar:baz] = [foo bar:baz];");
-  verifyFormat("[foo bar:baz] *= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] /= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] %= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] += [foo bar:baz];");
-  verifyFormat("[foo bar:baz] -= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] <<= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] >>= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] &= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] ^= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] |= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] ? [foo bar:baz] : [foo bar:baz];");
-  verifyFormat("[foo bar:baz] || [foo bar:baz];");
-  verifyFormat("[foo bar:baz] && [foo bar:baz];");
-  verifyFormat("[foo bar:baz] | [foo bar:baz];");
-  verifyFormat("[foo bar:baz] ^ [foo bar:baz];");
-  verifyFormat("[foo bar:baz] & [foo bar:baz];");
-  verifyFormat("[foo bar:baz] == [foo bar:baz];");
-  verifyFormat("[foo bar:baz] != [foo bar:baz];");
-  verifyFormat("[foo bar:baz] >= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] <= [foo bar:baz];");
-  verifyFormat("[foo bar:baz] > [foo bar:baz];");
-  verifyFormat("[foo bar:baz] < [foo bar:baz];");
-  verifyFormat("[foo bar:baz] >> [foo bar:baz];");
-  verifyFormat("[foo bar:baz] << [foo bar:baz];");
-  verifyFormat("[foo bar:baz] - [foo bar:baz];");
-  verifyFormat("[foo bar:baz] + [foo bar:baz];");
-  verifyFormat("[foo bar:baz] * [foo bar:baz];");
-  verifyFormat("[foo bar:baz] / [foo bar:baz];");
-  verifyFormat("[foo bar:baz] % [foo bar:baz];");
-  // Whew!
-
-  verifyFormat("return in[42];");
-  verifyFormat("for (auto v : in[1]) {\n}");
-  verifyFormat("for (int i = 0; i < in[a]; ++i) {\n}");
-  verifyFormat("for (int i = 0; in[a] < i; ++i) {\n}");
-  verifyFormat("for (int i = 0; i < n; ++i, ++in[a]) {\n}");
-  verifyFormat("for (int i = 0; i < n; ++i, in[a]++) {\n}");
-  verifyFormat("for (int i = 0; i < f(in[a]); ++i, in[a]++) {\n}");
-  verifyFormat("for (id foo in [self getStuffFor:bla]) {\n"
-               "}");
-  verifyFormat("[self aaaaa:MACRO(a, b:, c:)];");
-  verifyFormat("[self aaaaa:(1 + 2) bbbbb:3];");
-  verifyFormat("[self aaaaa:(Type)a bbbbb:3];");
-
-  verifyFormat("[self stuffWithInt:(4 + 2) float:4.5];");
-  verifyFormat("[self stuffWithInt:a ? b : c float:4.5];");
-  verifyFormat("[self stuffWithInt:a ? [self foo:bar] : c];");
-  verifyFormat("[self stuffWithInt:a ? (e ? f : g) : c];");
-  verifyFormat("[cond ? obj1 : obj2 methodWithParam:param]");
-  verifyFormat("[button setAction:@selector(zoomOut:)];");
-  verifyFormat("[color getRed:&r green:&g blue:&b alpha:&a];");
-
-  verifyFormat("arr[[self indexForFoo:a]];");
-  verifyFormat("throw [self errorFor:a];");
-  verifyFormat("@throw [self errorFor:a];");
-
-  verifyFormat("[(id)foo bar:(id)baz quux:(id)snorf];");
-  verifyFormat("[(id)foo bar:(id) ? baz : quux];");
-  verifyFormat("4 > 4 ? (id)a : (id)baz;");
-
-  // This tests that the formatter doesn't break after "backing" but before ":",
-  // which would be at 80 columns.
-  verifyFormat(
-      "void f() {\n"
-      "  if ((self = [super initWithContentRect:contentRect\n"
-      "                               styleMask:styleMask ?: otherMask\n"
-      "                                 backing:NSBackingStoreBuffered\n"
-      "                                   defer:YES]))");
-
-  verifyFormat(
-      "[foo checkThatBreakingAfterColonWorksOk:\n"
-      "         [bar ifItDoes:reduceOverallLineLengthLikeInThisCase]];");
-
-  verifyFormat("[myObj short:arg1 // Force line break\n"
-               "          longKeyword:arg2 != nil ? arg2 : @\"longKeyword\"\n"
-               "    evenLongerKeyword:arg3 ?: @\"evenLongerKeyword\"\n"
-               "                error:arg4];");
-  verifyFormat(
-      "void f() {\n"
-      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
-      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
-      "                                     pos.width(), pos.height())\n"
-      "                styleMask:NSBorderlessWindowMask\n"
-      "                  backing:NSBackingStoreBuffered\n"
-      "                    defer:NO]);\n"
-      "}");
-  verifyFormat("[contentsContainer replaceSubview:[subviews objectAtIndex:0]\n"
-               "                             with:contentsNativeView];");
-
-  verifyFormat(
-      "[pboard addTypes:[NSArray arrayWithObject:kBookmarkButtonDragType]\n"
-      "           owner:nillllll];");
-
-  verifyFormat(
-      "[pboard setData:[NSData dataWithBytes:&button length:sizeof(button)]\n"
-      "        forType:kBookmarkButtonDragType];");
-
-  verifyFormat("[defaultCenter addObserver:self\n"
-               "                  selector:@selector(willEnterFullscreen)\n"
-               "                      name:kWillEnterFullscreenNotification\n"
-               "                    object:nil];");
-  verifyFormat("[image_rep drawInRect:drawRect\n"
-               "             fromRect:NSZeroRect\n"
-               "            operation:NSCompositeCopy\n"
-               "             fraction:1.0\n"
-               "       respectFlipped:NO\n"
-               "                hints:nil];");
-  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
-  verifyFormat("[aaaaaaaaaaaaaaaaaaaa(aaaaaaaaaaaaaaaaaaaaa)\n"
-               "    aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
-  verifyFormat("[aaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaa[aaaaaaaaaaaaaaaaaaaaa]\n"
-               "    aaaaaaaaaaaaaaaaaaaaaa];");
-
-  verifyFormat(
-      "scoped_nsobject<NSTextField> message(\n"
-      "    // The frame will be fixed up when |-setMessageText:| is called.\n"
-      "    [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 0, 0)]);");
-  verifyFormat("[self aaaaaa:bbbbbbbbbbbbb\n"
-               "    aaaaaaaaaa:bbbbbbbbbbbbbbbbb\n"
-               "         aaaaa:bbbbbbbbbbb + bbbbbbbbbbbb\n"
-               "          aaaa:bbb];");
-  verifyFormat("[self param:function( //\n"
-               "                parameter)]");
-  verifyFormat(
-      "[self aaaaaaaaaa:aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
-      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa |\n"
-      "                 aaaaaaaaaaaaaaa | aaaaaaaaaaaaaaa];");
-
-  // Variadic parameters.
-  verifyFormat(
-      "NSArray *myStrings = [NSArray stringarray:@\"a\", @\"b\", nil];");
-  verifyFormat(
-      "[self aaaaaaaaaaaaa:aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
-      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa,\n"
-      "                    aaaaaaaaaaaaaaa, aaaaaaaaaaaaaaa];");
-  verifyFormat("[self // break\n"
-               "      a:a\n"
-               "    aaa:aaa];");
-  verifyFormat("bool a = ([aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaa ||\n"
-               "          [aaaaaaaa aaaaa] == aaaaaaaaaaaaaaaaaaaa);");
-
-  // Formats pair-parameters.
-  verifyFormat("[I drawRectOn:surface ofSize:aa:bbb atOrigin:cc:dd];");
-  verifyFormat("[I drawRectOn:surface //\n"
-               "        ofSize:aa:bbb\n"
-               "      atOrigin:cc:dd];");
-
-  Style.ColumnLimit = 70;
-  verifyFormat(
-      "void f() {\n"
-      "  popup_wdow_.reset([[RenderWidgetPopupWindow alloc]\n"
-      "      iniithContentRect:NSMakRet(origin_global.x, origin_global.y,\n"
-      "                                 pos.width(), pos.height())\n"
-      "                syeMask:NSBorderlessWindowMask\n"
-      "                  bking:NSBackingStoreBuffered\n"
-      "                    der:NO]);\n"
-      "}");
-
-  Style.ColumnLimit = 60;
-  verifyFormat("[call aaaaaaaa.aaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa.aaaaaaaa\n"
-               "        .aaaaaaaa];"); // FIXME: Indentation seems off.
-  // FIXME: This violates the column limit.
-  verifyFormat(
-      "[aaaaaaaaaaaaaaaaaaaaaaaaa\n"
-      "    aaaaaaaaaaaaaaaaa:aaaaaaaa\n"
-      "                  aaa:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa];");
-
-  Style = getChromiumStyle(FormatStyle::LK_ObjC);
-  Style.ColumnLimit = 80;
-  verifyFormat(
-      "void f() {\n"
-      "  popup_window_.reset([[RenderWidgetPopupWindow alloc]\n"
-      "      initWithContentRect:NSMakeRect(origin_global.x, origin_global.y,\n"
-      "                                     pos.width(), pos.height())\n"
-      "                styleMask:NSBorderlessWindowMask\n"
-      "                  backing:NSBackingStoreBuffered\n"
-      "                    defer:NO]);\n"
-      "}");
-}
-
-TEST_F(FormatTestObjC, ObjCAt) {
-  verifyFormat("@autoreleasepool");
-  verifyFormat("@catch");
-  verifyFormat("@class");
-  verifyFormat("@compatibility_alias");
-  verifyFormat("@defs");
-  verifyFormat("@dynamic");
-  verifyFormat("@encode");
-  verifyFormat("@end");
-  verifyFormat("@finally");
-  verifyFormat("@implementation");
-  verifyFormat("@import");
-  verifyFormat("@interface");
-  verifyFormat("@optional");
-  verifyFormat("@package");
-  verifyFormat("@private");
-  verifyFormat("@property");
-  verifyFormat("@protected");
-  verifyFormat("@protocol");
-  verifyFormat("@public");
-  verifyFormat("@required");
-  verifyFormat("@selector");
-  verifyFormat("@synchronized");
-  verifyFormat("@synthesize");
-  verifyFormat("@throw");
-  verifyFormat("@try");
-
-  EXPECT_EQ("@interface", format("@ interface"));
-
-  // The precise formatting of this doesn't matter, nobody writes code like
-  // this.
-  verifyFormat("@ /*foo*/ interface");
-}
-
-TEST_F(FormatTestObjC, ObjCSnippets) {
-  verifyFormat("@autoreleasepool {\n"
-               "  foo();\n"
-               "}");
-  verifyFormat("@class Foo, Bar;");
-  verifyFormat("@compatibility_alias AliasName ExistingClass;");
-  verifyFormat("@dynamic textColor;");
-  verifyFormat("char *buf1 = @encode(int *);");
-  verifyFormat("char *buf1 = @encode(typeof(4 * 5));");
-  verifyFormat("char *buf1 = @encode(int **);");
-  verifyFormat("Protocol *proto = @protocol(p1);");
-  verifyFormat("SEL s = @selector(foo:);");
-  verifyFormat("@synchronized(self) {\n"
-               "  f();\n"
-               "}");
-
-  verifyFormat("@import foo.bar;\n"
-               "@import baz;");
-
-  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
-
-  verifyFormat("@property(assign, nonatomic) CGFloat hoverAlpha;");
-  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
-
-  Style = getMozillaStyle();
-  verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
-  verifyFormat("@property BOOL editable;");
-
-  Style = getWebKitStyle();
-  verifyFormat("@property (assign, getter=isEditable) BOOL editable;");
-  verifyFormat("@property BOOL editable;");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat("@synthesize dropArrowPosition = dropArrowPosition_;");
-  verifyFormat("@property(assign, getter=isEditable) BOOL editable;");
-}
-
-TEST_F(FormatTestObjC, ObjCForIn) {
-  verifyFormat("- (void)test {\n"
-               "  for (NSString *n in arrayOfStrings) {\n"
-               "    foo(n);\n"
-               "  }\n"
-               "}");
-  verifyFormat("- (void)test {\n"
-               "  for (NSString *n in (__bridge NSArray *)arrayOfStrings) {\n"
-               "    foo(n);\n"
-               "  }\n"
-               "}");
-}
-
-TEST_F(FormatTestObjC, ObjCLiterals) {
-  verifyFormat("@\"String\"");
-  verifyFormat("@1");
-  verifyFormat("@+4.8");
-  verifyFormat("@-4");
-  verifyFormat("@1LL");
-  verifyFormat("@.5");
-  verifyFormat("@'c'");
-  verifyFormat("@true");
-
-  verifyFormat("NSNumber *smallestInt = @(-INT_MAX - 1);");
-  verifyFormat("NSNumber *piOverTwo = @(M_PI / 2);");
-  verifyFormat("NSNumber *favoriteColor = @(Green);");
-  verifyFormat("NSString *path = @(getenv(\"PATH\"));");
-
-  verifyFormat("[dictionary setObject:@(1) forKey:@\"number\"];");
-}
-
-TEST_F(FormatTestObjC, ObjCDictLiterals) {
-  verifyFormat("@{");
-  verifyFormat("@{}");
-  verifyFormat("@{@\"one\" : @1}");
-  verifyFormat("return @{@\"one\" : @1;");
-  verifyFormat("@{@\"one\" : @1}");
-
-  verifyFormat("@{@\"one\" : @{@2 : @1}}");
-  verifyFormat("@{\n"
-               "  @\"one\" : @{@2 : @1},\n"
-               "}");
-
-  verifyFormat("@{1 > 2 ? @\"one\" : @\"two\" : 1 > 2 ? @1 : @2}");
-  verifyIncompleteFormat("[self setDict:@{}");
-  verifyIncompleteFormat("[self setDict:@{@1 : @2}");
-  verifyFormat("NSLog(@\"%@\", @{@1 : @2, @2 : @3}[@1]);");
-  verifyFormat(
-      "NSDictionary *masses = @{@\"H\" : @1.0078, @\"He\" : @4.0026};");
-  verifyFormat(
-      "NSDictionary *settings = @{AVEncoderKey : @(AVAudioQualityMax)};");
-
-  verifyFormat("NSDictionary *d = @{\n"
-               "  @\"nam\" : NSUserNam(),\n"
-               "  @\"dte\" : [NSDate date],\n"
-               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
-               "};");
-  verifyFormat(
-      "@{\n"
-      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
-      "regularFont,\n"
-      "};");
-  verifyFormat(
-      "@{\n"
-      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee :\n"
-      "      reeeeeeeeeeeeeeeeeeeeeeeegularFont,\n"
-      "};");
-
-  // We should try to be robust in case someone forgets the "@".
-  verifyFormat("NSDictionary *d = {\n"
-               "  @\"nam\" : NSUserNam(),\n"
-               "  @\"dte\" : [NSDate date],\n"
-               "  @\"processInfo\" : [NSProcessInfo processInfo]\n"
-               "};");
-  verifyFormat("NSMutableDictionary *dictionary =\n"
-               "    [NSMutableDictionary dictionaryWithDictionary:@{\n"
-               "      aaaaaaaaaaaaaaaaaaaaa : aaaaaaaaaaaaa,\n"
-               "      bbbbbbbbbbbbbbbbbb : bbbbb,\n"
-               "      cccccccccccccccc : ccccccccccccccc\n"
-               "    }];");
-
-  // Ensure that casts before the key are kept on the same line as the key.
-  verifyFormat(
-      "NSDictionary *d = @{\n"
-      "  (aaaaaaaa id)aaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaaaaaaaaaaaa,\n"
-      "  (aaaaaaaa id)aaaaaaaaaaaaaa : (aaaaaaaa id)aaaaaaaaaaaaaa,\n"
-      "};");
-
-  Style = getGoogleStyle(FormatStyle::LK_ObjC);
-  verifyFormat(
-      "@{\n"
-      "  NSFontAttributeNameeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee : "
-      "regularFont,\n"
-      "};");
-}
-
-TEST_F(FormatTestObjC, ObjCArrayLiterals) {
-  verifyIncompleteFormat("@[");
-  verifyFormat("@[]");
-  verifyFormat(
-      "NSArray *array = @[ @\" Hey \", NSApp, [NSNumber numberWithInt:42] ];");
-  verifyFormat("return @[ @3, @[], @[ @4, @5 ] ];");
-  verifyFormat("NSArray *array = @[ [foo description] ];");
-
-  verifyFormat(
-      "NSArray *some_variable = @[\n"
-      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaaa\",\n"
-      "];");
-  verifyFormat(
-      "NSArray *some_variable = @[\n"
-      "  aaaa == bbbbbbbbbbb ? @\"aaaaaaaaaaaa\" : @\"aaaaaaaaaaaaaa\",\n"
-      "  @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\", @\"aaaaaaaaaaaaaaaa\"\n"
-      "];");
-  verifyFormat("NSArray *some_variable = @[\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "];");
-  verifyFormat("NSArray *array = @[\n"
-               "  @\"a\",\n"
-               "  @\"a\",\n" // Trailing comma -> one per line.
-               "];");
-
-  // We should try to be robust in case someone forgets the "@".
-  verifyFormat("NSArray *some_variable = [\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "  @\"aaaaaaaaaaaaaaaaa\",\n"
-               "];");
-  verifyFormat(
-      "- (NSAttributedString *)attributedStringForSegment:(NSUInteger)segment\n"
-      "                                             index:(NSUInteger)index\n"
-      "                                nonDigitAttributes:\n"
-      "                                    (NSDictionary *)noDigitAttributes;");
-  verifyFormat("[someFunction someLooooooooooooongParameter:@[\n"
-               "  NSBundle.mainBundle.infoDictionary[@\"a\"]\n"
-               "]];");
-}
-} // end namespace
-} // end namespace format
-} // end namespace clang
diff --git a/unittests/Lex/CMakeLists.txt b/unittests/Lex/CMakeLists.txt
index ef0f06c..2002fbf 100644
--- a/unittests/Lex/CMakeLists.txt
+++ b/unittests/Lex/CMakeLists.txt
@@ -13,6 +13,7 @@
   clangAST
   clangBasic
   clangLex
+  clangAPINotes
   clangParse
   clangSema
   )
diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index 918167b..b5a6fd9 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -12,6 +12,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
@@ -64,10 +65,12 @@
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
     VoidModuleLoader ModLoader;
+    MemoryBufferCache PCMCache;
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, LangOpts, Target.get());
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                    SourceMgr, HeaderInfo, ModLoader, /*IILookup =*/nullptr,
+                    SourceMgr, PCMCache, HeaderInfo, ModLoader,
+                    /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
     PP.EnterMainSourceFile();
diff --git a/unittests/Lex/PPCallbacksTest.cpp b/unittests/Lex/PPCallbacksTest.cpp
index 064abaf..0841791 100644
--- a/unittests/Lex/PPCallbacksTest.cpp
+++ b/unittests/Lex/PPCallbacksTest.cpp
@@ -14,6 +14,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
@@ -161,13 +162,14 @@
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
     VoidModuleLoader ModLoader;
+    MemoryBufferCache PCMCache;
 
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, LangOpts, Target.get());
     AddFakeHeader(HeaderInfo, HeaderPath, SystemHeader);
 
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                    SourceMgr, HeaderInfo, ModLoader,
+                    SourceMgr, PCMCache, HeaderInfo, ModLoader,
                     /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
@@ -198,11 +200,12 @@
     SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(SourceBuf)));
 
     VoidModuleLoader ModLoader;
+    MemoryBufferCache PCMCache;
     HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                             Diags, OpenCLLangOpts, Target.get());
 
     Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags,
-                    OpenCLLangOpts, SourceMgr, HeaderInfo, ModLoader,
+                    OpenCLLangOpts, SourceMgr, PCMCache, HeaderInfo, ModLoader,
                     /*IILookup =*/nullptr,
                     /*OwnsHeaderSearch =*/false);
     PP.Initialize(*Target);
diff --git a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
index dccfffd..b635604 100644
--- a/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
+++ b/unittests/Lex/PPConditionalDirectiveRecordTest.cpp
@@ -12,6 +12,7 @@
 #include "clang/Basic/DiagnosticOptions.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LangOptions.h"
+#include "clang/Basic/MemoryBufferCache.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TargetOptions.h"
@@ -93,10 +94,11 @@
   SourceMgr.setMainFileID(SourceMgr.createFileID(std::move(Buf)));
 
   VoidModuleLoader ModLoader;
+  MemoryBufferCache PCMCache;
   HeaderSearch HeaderInfo(std::make_shared<HeaderSearchOptions>(), SourceMgr,
                           Diags, LangOpts, Target.get());
   Preprocessor PP(std::make_shared<PreprocessorOptions>(), Diags, LangOpts,
-                  SourceMgr, HeaderInfo, ModLoader,
+                  SourceMgr, PCMCache, HeaderInfo, ModLoader,
                   /*IILookup =*/nullptr,
                   /*OwnsHeaderSearch =*/false);
   PP.Initialize(*Target);
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 7e08f96..269bdbb 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -52,6 +52,14 @@
   EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
 }
 
+TEST(RecursiveASTVisitor, VisitsAttributedLambdaExpr) {
+  LambdaExprVisitor Visitor;
+  Visitor.ExpectMatch("", 1, 12);
+  EXPECT_TRUE(Visitor.runOver(
+      "void f() { [] () __attribute__ (( fastcall )) { return; }(); }",
+      LambdaExprVisitor::Lang_CXX14));
+}
+
 // Matches the (optional) capture-default of a lambda-introducer.
 class LambdaDefaultCaptureVisitor
   : public ExpectedLocationVisitor<LambdaDefaultCaptureVisitor> {
diff --git a/unittests/Tooling/ReplacementTest.h b/unittests/Tooling/ReplacementTest.h
index b6fe5c7..91530f0 100644
--- a/unittests/Tooling/ReplacementTest.h
+++ b/unittests/Tooling/ReplacementTest.h
@@ -24,7 +24,7 @@
 /// \brief Converts a set of replacements to Replacements class.
 /// \return A Replacements class containing \p Replaces on success; otherwise,
 /// an empty Replacements is returned.
-inline tooling::Replacements
+static tooling::Replacements
 toReplacements(const std::set<tooling::Replacement> &Replaces) {
   tooling::Replacements Result;
   for (const auto &R : Replaces) {
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 27ab34c..c9f53e9 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -12,13 +12,15 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/TableGen/Error.h"
@@ -310,7 +312,7 @@
     }
 
     void writeDump(raw_ostream &OS) const override {
-      if (type == "FunctionDecl *") {
+      if (type == "FunctionDecl *" || type == "NamedDecl *") {
         OS << "    OS << \" \";\n";
         OS << "    dumpBareDeclRef(SA->get" << getUpperName() << "());\n"; 
       } else if (type == "IdentifierInfo *") {
@@ -1160,6 +1162,32 @@
     }
   };
 
+  class AttrArgument : public SimpleArgument {
+  public:
+    AttrArgument(const Record &Arg, StringRef Attr)
+      : SimpleArgument(Arg, Attr, "Attr *")
+    {}
+
+    void writePCHReadDecls(raw_ostream &OS) const override {
+      OS << "    AttrVec vec;\n"
+            "    ReadAttributes(F, vec, Record, Idx);\n"
+            "    assert(vec.size() == 1);\n"
+            "    Attr *" << getLowerName() << " = vec.front();";
+    }
+
+    void writePCHWrite(raw_ostream &OS) const override {
+      OS << "    AddAttributes(SA->get" << getUpperName() << "());";
+    }
+
+    void writeDump(raw_ostream &OS) const override {}
+  
+    void writeDumpChildren(raw_ostream &OS) const override {
+      OS << "    dumpAttr(SA->get" << getUpperName() << "());\n";
+    }
+
+    void writeHasChildren(raw_ostream &OS) const override { OS << "true"; }
+  };
+
 } // end anonymous namespace
 
 static std::unique_ptr<Argument>
@@ -1179,6 +1207,8 @@
     Ptr = llvm::make_unique<ExprArgument>(Arg, Attr);
   else if (ArgName == "FunctionArgument")
     Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "FunctionDecl *");
+  else if (ArgName == "NamedArgument")
+    Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "NamedDecl *");
   else if (ArgName == "IdentifierArgument")
     Ptr = llvm::make_unique<SimpleArgument>(Arg, Attr, "IdentifierInfo *");
   else if (ArgName == "DefaultBoolArgument")
@@ -1207,6 +1237,8 @@
     Ptr = llvm::make_unique<VariadicExprArgument>(Arg, Attr);
   else if (ArgName == "VersionArgument")
     Ptr = llvm::make_unique<VersionArgument>(Arg, Attr);
+  else if (ArgName == "AttrArgument")
+    Ptr = llvm::make_unique<AttrArgument>(Arg, Attr);
 
   if (!Ptr) {
     // Search in reverse order so that the most-derived type is handled first.
@@ -1522,6 +1554,408 @@
   OS << "#endif // CLANG_ATTR_LATE_PARSED_LIST\n\n";
 }
 
+static bool hasGNUorCXX11Spelling(const Record &Attribute) {
+  std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attribute);
+  for (const auto &I : Spellings) {
+    if (I.variety() == "GNU" || I.variety() == "CXX11")
+      return true;
+  }
+  return false;
+}
+
+namespace {
+
+struct AttributeSubjectMatchRule {
+  const Record *MetaSubject;
+  const Record *Constraint;
+
+  AttributeSubjectMatchRule(const Record *MetaSubject, const Record *Constraint)
+      : MetaSubject(MetaSubject), Constraint(Constraint) {
+    assert(MetaSubject && "Missing subject");
+  }
+
+  bool isSubRule() const { return Constraint != nullptr; }
+
+  std::vector<Record *> getSubjects() const {
+    return (Constraint ? Constraint : MetaSubject)
+        ->getValueAsListOfDefs("Subjects");
+  }
+
+  std::vector<Record *> getLangOpts() const {
+    if (Constraint) {
+      // Lookup the options in the sub-rule first, in case the sub-rule
+      // overrides the rules options.
+      std::vector<Record *> Opts = Constraint->getValueAsListOfDefs("LangOpts");
+      if (!Opts.empty())
+        return Opts;
+    }
+    return MetaSubject->getValueAsListOfDefs("LangOpts");
+  }
+
+  // Abstract rules are used only for sub-rules
+  bool isAbstractRule() const { return getSubjects().empty(); }
+
+  std::string getName() const {
+    return (Constraint ? Constraint : MetaSubject)->getValueAsString("Name");
+  }
+
+  bool isNegatedSubRule() const {
+    assert(isSubRule() && "Not a sub-rule");
+    return Constraint->getValueAsBit("Negated");
+  }
+
+  std::string getSpelling() const {
+    std::string Result = MetaSubject->getValueAsString("Name");
+    if (isSubRule()) {
+      Result += '(';
+      if (isNegatedSubRule())
+        Result += "unless(";
+      Result += getName();
+      if (isNegatedSubRule())
+        Result += ')';
+      Result += ')';
+    }
+    return Result;
+  }
+
+  std::string getEnumValueName() const {
+    std::string Result =
+        "SubjectMatchRule_" + MetaSubject->getValueAsString("Name");
+    if (isSubRule()) {
+      Result += "_";
+      if (isNegatedSubRule())
+        Result += "not_";
+      Result += Constraint->getValueAsString("Name");
+    }
+    if (isAbstractRule())
+      Result += "_abstract";
+    return Result;
+  }
+
+  std::string getEnumValue() const { return "attr::" + getEnumValueName(); }
+
+  static const char *EnumName;
+};
+
+const char *AttributeSubjectMatchRule::EnumName = "attr::SubjectMatchRule";
+
+struct PragmaClangAttributeSupport {
+  std::vector<AttributeSubjectMatchRule> Rules;
+
+  class RuleOrAggregateRuleSet {
+    std::vector<AttributeSubjectMatchRule> Rules;
+    bool IsRule;
+    RuleOrAggregateRuleSet(ArrayRef<AttributeSubjectMatchRule> Rules,
+                           bool IsRule)
+        : Rules(Rules), IsRule(IsRule) {}
+
+  public:
+    bool isRule() const { return IsRule; }
+
+    const AttributeSubjectMatchRule &getRule() const {
+      assert(IsRule && "not a rule!");
+      return Rules[0];
+    }
+
+    ArrayRef<AttributeSubjectMatchRule> getAggregateRuleSet() const {
+      return Rules;
+    }
+
+    static RuleOrAggregateRuleSet
+    getRule(const AttributeSubjectMatchRule &Rule) {
+      return RuleOrAggregateRuleSet(Rule, /*IsRule=*/true);
+    }
+    static RuleOrAggregateRuleSet
+    getAggregateRuleSet(ArrayRef<AttributeSubjectMatchRule> Rules) {
+      return RuleOrAggregateRuleSet(Rules, /*IsRule=*/false);
+    }
+  };
+  llvm::DenseMap<const Record *, RuleOrAggregateRuleSet> SubjectsToRules;
+
+  PragmaClangAttributeSupport(RecordKeeper &Records);
+
+  bool isAttributedSupported(const Record &Attribute);
+
+  void emitMatchRuleList(raw_ostream &OS);
+
+  std::string generateStrictConformsTo(const Record &Attr, raw_ostream &OS);
+
+  void generateParsingHelpers(raw_ostream &OS);
+};
+
+} // end anonymous namespace
+
+static bool doesDeclDeriveFrom(const Record *D, const Record *Base) {
+  const Record *CurrentBase = D->getValueAsDef("Base");
+  if (!CurrentBase)
+    return false;
+  if (CurrentBase == Base)
+    return true;
+  return doesDeclDeriveFrom(CurrentBase, Base);
+}
+
+PragmaClangAttributeSupport::PragmaClangAttributeSupport(
+    RecordKeeper &Records) {
+  std::vector<Record *> MetaSubjects =
+      Records.getAllDerivedDefinitions("AttrSubjectMatcherRule");
+  auto MapFromSubjectsToRules = [this](const Record *SubjectContainer,
+                                       const Record *MetaSubject,
+                                       const Record *Constraint = nullptr) {
+    Rules.emplace_back(MetaSubject, Constraint);
+    std::vector<Record *> ApplicableSubjects =
+        SubjectContainer->getValueAsListOfDefs("Subjects");
+    for (const auto *Subject : ApplicableSubjects) {
+      bool Inserted =
+          SubjectsToRules
+              .try_emplace(Subject, RuleOrAggregateRuleSet::getRule(
+                                        AttributeSubjectMatchRule(MetaSubject,
+                                                                  Constraint)))
+              .second;
+      if (!Inserted) {
+        PrintFatalError("Attribute subject match rules should not represent"
+                        "same attribute subjects.");
+      }
+    }
+  };
+  for (const auto *MetaSubject : MetaSubjects) {
+    MapFromSubjectsToRules(MetaSubject, MetaSubject);
+    std::vector<Record *> Constraints =
+        MetaSubject->getValueAsListOfDefs("Constraints");
+    for (const auto *Constraint : Constraints)
+      MapFromSubjectsToRules(Constraint, MetaSubject, Constraint);
+  }
+
+  std::vector<Record *> Aggregates =
+      Records.getAllDerivedDefinitions("AttrSubjectMatcherAggregateRule");
+  std::vector<Record *> DeclNodes = Records.getAllDerivedDefinitions("DDecl");
+  for (const auto *Aggregate : Aggregates) {
+    Record *SubjectDecl = Aggregate->getValueAsDef("Subject");
+
+    // Gather sub-classes of the aggregate subject that act as attribute
+    // subject rules.
+    std::vector<AttributeSubjectMatchRule> Rules;
+    for (const auto *D : DeclNodes) {
+      if (doesDeclDeriveFrom(D, SubjectDecl)) {
+        auto It = SubjectsToRules.find(D);
+        if (It == SubjectsToRules.end())
+          continue;
+        if (!It->second.isRule() || It->second.getRule().isSubRule())
+          continue; // Assume that the rule will be included as well.
+        Rules.push_back(It->second.getRule());
+      }
+    }
+
+    bool Inserted =
+        SubjectsToRules
+            .try_emplace(SubjectDecl,
+                         RuleOrAggregateRuleSet::getAggregateRuleSet(Rules))
+            .second;
+    if (!Inserted) {
+      PrintFatalError("Attribute subject match rules should not represent"
+                      "same attribute subjects.");
+    }
+  }
+}
+
+static PragmaClangAttributeSupport &
+getPragmaAttributeSupport(RecordKeeper &Records) {
+  static PragmaClangAttributeSupport Instance(Records);
+  return Instance;
+}
+
+void PragmaClangAttributeSupport::emitMatchRuleList(raw_ostream &OS) {
+  OS << "#ifndef ATTR_MATCH_SUB_RULE\n";
+  OS << "#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, "
+        "IsNegated) "
+     << "ATTR_MATCH_RULE(Value, Spelling, IsAbstract)\n";
+  OS << "#endif\n";
+  for (const auto &Rule : Rules) {
+    OS << (Rule.isSubRule() ? "ATTR_MATCH_SUB_RULE" : "ATTR_MATCH_RULE") << '(';
+    OS << Rule.getEnumValueName() << ", \"" << Rule.getSpelling() << "\", "
+       << Rule.isAbstractRule();
+    if (Rule.isSubRule())
+      OS << ", "
+         << AttributeSubjectMatchRule(Rule.MetaSubject, nullptr).getEnumValue()
+         << ", " << Rule.isNegatedSubRule();
+    OS << ")\n";
+  }
+  OS << "#undef ATTR_MATCH_SUB_RULE\n";
+}
+
+bool PragmaClangAttributeSupport::isAttributedSupported(
+    const Record &Attribute) {
+  if (Attribute.getValueAsBit("ForcePragmaAttributeSupport"))
+    return true;
+  // Opt-out rules:
+  // FIXME: The documentation check should be moved before
+  // the ForcePragmaAttributeSupport check after annotate is documented.
+  // No documentation present.
+  if (Attribute.isValueUnset("Documentation"))
+    return false;
+  std::vector<Record *> Docs = Attribute.getValueAsListOfDefs("Documentation");
+  if (Docs.empty())
+    return false;
+  if (Docs.size() == 1 && Docs[0]->getName() == "Undocumented")
+    return false;
+  // An attribute requires delayed parsing (LateParsed is on)
+  if (Attribute.getValueAsBit("LateParsed"))
+    return false;
+  // An attribute has no GNU/CXX11 spelling
+  if (!hasGNUorCXX11Spelling(Attribute))
+    return false;
+  // An attribute subject list has a subject that isn't covered by one of the
+  // subject match rules or has no subjects at all.
+  if (Attribute.isValueUnset("Subjects"))
+    return false;
+  const Record *SubjectObj = Attribute.getValueAsDef("Subjects");
+  std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
+  if (Subjects.empty())
+    return false;
+  for (const auto *Subject : Subjects) {
+    if (SubjectsToRules.find(Subject) == SubjectsToRules.end())
+      return false;
+  }
+  return true;
+}
+
+std::string
+PragmaClangAttributeSupport::generateStrictConformsTo(const Record &Attr,
+                                                      raw_ostream &OS) {
+  if (!isAttributedSupported(Attr))
+    return "nullptr";
+  // Generate a function that constructs a set of matching rules that describe
+  // to which declarations the attribute should apply to.
+  std::string FnName = "matchRulesFor" + Attr.getName().str();
+  std::stringstream SS;
+  SS << "static void " << FnName << "(llvm::SmallVectorImpl<std::pair<"
+     << AttributeSubjectMatchRule::EnumName
+     << ", bool>> &MatchRules, const LangOptions &LangOpts) {\n";
+  if (Attr.isValueUnset("Subjects")) {
+    SS << "}\n\n";
+    OS << SS.str();
+    return FnName;
+  }
+  const Record *SubjectObj = Attr.getValueAsDef("Subjects");
+  std::vector<Record *> Subjects = SubjectObj->getValueAsListOfDefs("Subjects");
+  for (const auto *Subject : Subjects) {
+    auto It = SubjectsToRules.find(Subject);
+    assert(It != SubjectsToRules.end() &&
+           "This attribute is unsupported by #pragma clang attribute");
+    for (const auto &Rule : It->getSecond().getAggregateRuleSet()) {
+      // The rule might be language specific, so only subtract it from the given
+      // rules if the specific language options are specified.
+      std::vector<Record *> LangOpts = Rule.getLangOpts();
+      SS << "  MatchRules.push_back(std::make_pair(" << Rule.getEnumValue()
+         << ", /*IsSupported=*/";
+      if (!LangOpts.empty()) {
+        for (auto I = LangOpts.begin(), E = LangOpts.end(); I != E; ++I) {
+          std::string Part = (*I)->getValueAsString("Name");
+          if ((*I)->getValueAsBit("Negated"))
+            SS << "!";
+          SS << "LangOpts." + Part;
+          if (I + 1 != E)
+            SS << " || ";
+        }
+      } else
+        SS << "true";
+      SS << "));\n";
+    }
+  }
+  SS << "}\n\n";
+  OS << SS.str();
+  return FnName;
+}
+
+void PragmaClangAttributeSupport::generateParsingHelpers(raw_ostream &OS) {
+  // Generate routines that check the names of sub-rules.
+  OS << "Optional<attr::SubjectMatchRule> "
+        "defaultIsAttributeSubjectMatchSubRuleFor(StringRef, bool) {\n";
+  OS << "  return None;\n";
+  OS << "}\n\n";
+
+  std::map<const Record *, std::vector<AttributeSubjectMatchRule>>
+      SubMatchRules;
+  for (const auto &Rule : Rules) {
+    if (!Rule.isSubRule())
+      continue;
+    SubMatchRules[Rule.MetaSubject].push_back(Rule);
+  }
+
+  for (const auto &SubMatchRule : SubMatchRules) {
+    OS << "Optional<attr::SubjectMatchRule> isAttributeSubjectMatchSubRuleFor_"
+       << SubMatchRule.first->getValueAsString("Name")
+       << "(StringRef Name, bool IsUnless) {\n";
+    OS << "  if (IsUnless)\n";
+    OS << "    return "
+          "llvm::StringSwitch<Optional<attr::SubjectMatchRule>>(Name).\n";
+    for (const auto &Rule : SubMatchRule.second) {
+      if (Rule.isNegatedSubRule())
+        OS << "    Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
+           << ").\n";
+    }
+    OS << "    Default(None);\n";
+    OS << "  return "
+          "llvm::StringSwitch<Optional<attr::SubjectMatchRule>>(Name).\n";
+    for (const auto &Rule : SubMatchRule.second) {
+      if (!Rule.isNegatedSubRule())
+        OS << "  Case(\"" << Rule.getName() << "\", " << Rule.getEnumValue()
+           << ").\n";
+    }
+    OS << "  Default(None);\n";
+    OS << "}\n\n";
+  }
+
+  // Generate the function that checks for the top-level rules.
+  OS << "std::pair<Optional<attr::SubjectMatchRule>, "
+        "Optional<attr::SubjectMatchRule> (*)(StringRef, "
+        "bool)> isAttributeSubjectMatchRule(StringRef Name) {\n";
+  OS << "  return "
+        "llvm::StringSwitch<std::pair<Optional<attr::SubjectMatchRule>, "
+        "Optional<attr::SubjectMatchRule> (*) (StringRef, "
+        "bool)>>(Name).\n";
+  for (const auto &Rule : Rules) {
+    if (Rule.isSubRule())
+      continue;
+    std::string SubRuleFunction;
+    if (SubMatchRules.count(Rule.MetaSubject))
+      SubRuleFunction = "isAttributeSubjectMatchSubRuleFor_" + Rule.getName();
+    else
+      SubRuleFunction = "defaultIsAttributeSubjectMatchSubRuleFor";
+    OS << "  Case(\"" << Rule.getName() << "\", std::make_pair("
+       << Rule.getEnumValue() << ", " << SubRuleFunction << ")).\n";
+  }
+  OS << "  Default(std::make_pair(None, "
+        "defaultIsAttributeSubjectMatchSubRuleFor));\n";
+  OS << "}\n\n";
+
+  // Generate the function that checks for the submatch rules.
+  OS << "const char *validAttributeSubjectMatchSubRules("
+     << AttributeSubjectMatchRule::EnumName << " Rule) {\n";
+  OS << "  switch (Rule) {\n";
+  for (const auto &SubMatchRule : SubMatchRules) {
+    OS << "  case "
+       << AttributeSubjectMatchRule(SubMatchRule.first, nullptr).getEnumValue()
+       << ":\n";
+    OS << "  return \"'";
+    bool IsFirst = true;
+    for (const auto &Rule : SubMatchRule.second) {
+      if (!IsFirst)
+        OS << ", '";
+      IsFirst = false;
+      if (Rule.isNegatedSubRule())
+        OS << "unless(";
+      OS << Rule.getName();
+      if (Rule.isNegatedSubRule())
+        OS << ')';
+      OS << "'";
+    }
+    OS << "\";\n";
+  }
+  OS << "  default: return nullptr;\n";
+  OS << "  }\n";
+  OS << "}\n\n";
+}
+
 template <typename Fn>
 static void forEachUniqueSpelling(const Record &Attr, Fn &&F) {
   std::vector<FlattenedSpelling> Spellings = GetFlattenedSpellings(Attr);
@@ -2109,6 +2543,17 @@
   OS << "#undef PRAGMA_SPELLING_ATTR\n";
 }
 
+// Emits the enumeration list for attributes.
+void EmitClangAttrSubjectMatchRuleList(RecordKeeper &Records, raw_ostream &OS) {
+  emitSourceFileHeader(
+      "List of all attribute subject matching rules that Clang recognizes", OS);
+  PragmaClangAttributeSupport &PragmaAttributeSupport =
+      getPragmaAttributeSupport(Records);
+  emitDefaultDefine(OS, "ATTR_MATCH_RULE", nullptr);
+  PragmaAttributeSupport.emitMatchRuleList(OS);
+  OS << "#undef ATTR_MATCH_RULE\n";
+}
+
 // Emits the code to read an attribute from a precompiled header.
 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Attribute deserialization code", OS);
@@ -2451,26 +2896,19 @@
   OS << "#endif  // ATTR_VISITOR_DECLS_ONLY\n";
 }
 
-// Emits code to instantiate dependent attributes on templates.
-void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
-  emitSourceFileHeader("Template instantiation code for attributes", OS);
+void EmitClangAttrTemplateInstantiateHelper(const std::vector<Record *> &Attrs,
+                                            raw_ostream &OS,
+                                            bool AppliesToDecl) {
 
-  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
-
-  OS << "namespace clang {\n"
-     << "namespace sema {\n\n"
-     << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
-     << "Sema &S,\n"
-     << "        const MultiLevelTemplateArgumentList &TemplateArgs) {\n"
-     << "  switch (At->getKind()) {\n";
-
+  OS << "  switch (At->getKind()) {\n";
   for (const auto *Attr : Attrs) {
     const Record &R = *Attr;
     if (!R.getValueAsBit("ASTNode"))
       continue;
-
     OS << "    case attr::" << R.getName() << ": {\n";
-    bool ShouldClone = R.getValueAsBit("Clone");
+    bool ShouldClone = R.getValueAsBit("Clone") &&
+                       (!AppliesToDecl ||
+                        R.getValueAsBit("MeaningfulToClassTemplateDefinition"));
 
     if (!ShouldClone) {
       OS << "      return nullptr;\n";
@@ -2507,8 +2945,27 @@
   }
   OS << "  } // end switch\n"
      << "  llvm_unreachable(\"Unknown attribute!\");\n"
-     << "  return nullptr;\n"
-     << "}\n\n"
+     << "  return nullptr;\n";
+}
+
+// Emits code to instantiate dependent attributes on templates.
+void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS) {
+  emitSourceFileHeader("Template instantiation code for attributes", OS);
+
+  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
+
+  OS << "namespace clang {\n"
+     << "namespace sema {\n\n"
+     << "Attr *instantiateTemplateAttribute(const Attr *At, ASTContext &C, "
+     << "Sema &S,\n"
+     << "        const MultiLevelTemplateArgumentList &TemplateArgs) {\n";
+  EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/false);
+  OS << "}\n\n"
+     << "Attr *instantiateTemplateAttributeForDecl(const Attr *At,\n"
+     << " ASTContext &C, Sema &S,\n"
+     << "        const MultiLevelTemplateArgumentList &TemplateArgs) {\n";
+  EmitClangAttrTemplateInstantiateHelper(Attrs, OS, /*AppliesToDecl*/true);
+  OS << "}\n\n"
      << "} // end namespace sema\n"
      << "} // end namespace clang\n";
 }
@@ -2584,7 +3041,8 @@
     Field = 1U << 12,
     CXXMethod = 1U << 13,
     ObjCProtocol = 1U << 14,
-    Enum = 1U << 15
+    Enum = 1U << 15,
+    Named = 1U << 16,
   };
   uint32_t SubMask = 0;
 
@@ -2619,6 +3077,7 @@
                    .Case("Field", Field)
                    .Case("CXXMethod", CXXMethod)
                    .Case("Enum", Enum)
+                   .Case("Named", Named)
                    .Default(0);
     if (!V) {
       // Something wasn't in our mapping, so be helpful and let the developer
@@ -2674,9 +3133,14 @@
              "            : ExpectedVariableOrFunction))";
 
     case ObjCMethod | ObjCProp: return "ExpectedMethodOrProperty";
+    case Func | ObjCMethod | ObjCProp:
+      return "ExpectedFunctionOrMethodOrProperty";
     case ObjCProtocol | ObjCInterface:
       return "ExpectedObjectiveCInterfaceOrProtocol";
     case Field | Var: return "ExpectedFieldOrGlobalVar";
+
+    case Named:
+      return "ExpectedNamedDecl";
   }
 
   PrintFatalError(S.getLoc(),
@@ -2692,9 +3156,13 @@
   return B + "Decl";
 }
 
+static std::string functionNameForCustomAppertainsTo(const Record &Subject) {
+  return "is" + Subject.getName().str();
+}
+
 static std::string GenerateCustomAppertainsTo(const Record &Subject,
                                               raw_ostream &OS) {
-  std::string FnName = "is" + Subject.getName().str();
+  std::string FnName = functionNameForCustomAppertainsTo(Subject);
 
   // If this code has already been generated, simply return the previous
   // instance of it.
@@ -2779,6 +3247,42 @@
   return FnName;
 }
 
+static void
+emitAttributeMatchRules(PragmaClangAttributeSupport &PragmaAttributeSupport,
+                        raw_ostream &OS) {
+  OS << "static bool checkAttributeMatchRuleAppliesTo(const Decl *D, "
+     << AttributeSubjectMatchRule::EnumName << " rule) {\n";
+  OS << "  switch (rule) {\n";
+  for (const auto &Rule : PragmaAttributeSupport.Rules) {
+    if (Rule.isAbstractRule()) {
+      OS << "  case " << Rule.getEnumValue() << ":\n";
+      OS << "    assert(false && \"Abstract matcher rule isn't allowed\");\n";
+      OS << "    return false;\n";
+      continue;
+    }
+    std::vector<Record *> Subjects = Rule.getSubjects();
+    assert(!Subjects.empty() && "Missing subjects");
+    OS << "  case " << Rule.getEnumValue() << ":\n";
+    OS << "    return ";
+    for (auto I = Subjects.begin(), E = Subjects.end(); I != E; ++I) {
+      // If the subject has custom code associated with it, use the function
+      // that was generated for GenerateAppertainsTo to check if the declaration
+      // is valid.
+      if ((*I)->isSubClassOf("SubsetSubject"))
+        OS << functionNameForCustomAppertainsTo(**I) << "(D)";
+      else
+        OS << "isa<" << GetSubjectWithSuffix(*I) << ">(D)";
+
+      if (I + 1 != E)
+        OS << " || ";
+    }
+    OS << ";\n";
+  }
+  OS << "  }\n";
+  OS << "  llvm_unreachable(\"Invalid match rule\");\nreturn false;\n";
+  OS << "}\n\n";
+}
+
 static void GenerateDefaultLangOptRequirements(raw_ostream &OS) {
   OS << "static bool defaultDiagnoseLangOpts(Sema &, ";
   OS << "const AttributeList &) {\n";
@@ -2937,6 +3441,9 @@
 void EmitClangAttrParsedAttrImpl(RecordKeeper &Records, raw_ostream &OS) {
   emitSourceFileHeader("Parsed attribute helpers", OS);
 
+  PragmaClangAttributeSupport &PragmaAttributeSupport =
+      getPragmaAttributeSupport(Records);
+
   // Get the list of parsed attributes, and accept the optional list of
   // duplicates due to the ParseKind.
   ParsedAttrMap Dupes;
@@ -2970,10 +3477,13 @@
     SS << ", " << I->second->isSubClassOf("TypeAttr");
     SS << ", " << I->second->isSubClassOf("StmtAttr");
     SS << ", " << IsKnownToGCC(*I->second);
+    SS << ", " << PragmaAttributeSupport.isAttributedSupported(*I->second);
     SS << ", " << GenerateAppertainsTo(*I->second, OS);
     SS << ", " << GenerateLangOptRequirements(*I->second, OS);
     SS << ", " << GenerateTargetRequirements(*I->second, Dupes, OS);
     SS << ", " << GenerateSpellingIndexToSemanticSpelling(*I->second, OS);
+    SS << ", "
+       << PragmaAttributeSupport.generateStrictConformsTo(*I->second, OS);
     SS << " }";
 
     if (I + 1 != E)
@@ -2985,6 +3495,9 @@
   OS << "static const ParsedAttrInfo AttrInfoMap[AttributeList::UnknownAttribute + 1] = {\n";
   OS << SS.str();
   OS << "};\n\n";
+
+  // Generate the attribute match rules.
+  emitAttributeMatchRules(PragmaAttributeSupport, OS);
 }
 
 // Emits the kind list of parsed attributes
@@ -3124,6 +3637,11 @@
   emitClangAttrLateParsedList(Records, OS);
 }
 
+void EmitClangAttrSubjectMatchRulesParserStringSwitches(RecordKeeper &Records,
+                                                        raw_ostream &OS) {
+  getPragmaAttributeSupport(Records).generateParsingHelpers(OS);
+}
+
 class DocumentationData {
 public:
   const Record *Documentation;
@@ -3155,8 +3673,8 @@
   Pragma = 1 << 5
 };
 
-static void WriteDocumentation(const DocumentationData &Doc,
-                               raw_ostream &OS) {
+static void WriteDocumentation(RecordKeeper &Records,
+                               const DocumentationData &Doc, raw_ostream &OS) {
   // FIXME: there is no way to have a per-spelling category for the attribute
   // documentation. This may not be a limiting factor since the spellings
   // should generally be consistently applied across the category.
@@ -3238,7 +3756,7 @@
   // List what spelling syntaxes the attribute supports.
   OS << ".. csv-table:: Supported Syntaxes\n";
   OS << "   :header: \"GNU\", \"C++11\", \"__declspec\", \"Keyword\",";
-  OS << " \"Pragma\"\n\n";
+  OS << " \"Pragma\", \"Pragma clang attribute\"\n\n";
   OS << "   \"";
   if (SupportedSpellings & GNU) OS << "X";
   OS << "\",\"";
@@ -3249,6 +3767,9 @@
   if (SupportedSpellings & Keyword) OS << "X";
   OS << "\", \"";
   if (SupportedSpellings & Pragma) OS << "X";
+  OS << "\", \"";
+  if (getPragmaAttributeSupport(Records).isAttributedSupported(*Doc.Attribute))
+    OS << "X";
   OS << "\"\n\n";
 
   // If the attribute is deprecated, print a message about it, and possibly
@@ -3315,7 +3836,50 @@
     // Walk over each of the attributes in the category and write out their
     // documentation.
     for (const auto &Doc : I.second)
-      WriteDocumentation(Doc, OS);
+      WriteDocumentation(Records, Doc, OS);
+  }
+}
+
+void EmitTestPragmaAttributeSupportedAttributes(RecordKeeper &Records,
+                                                raw_ostream &OS) {
+  PragmaClangAttributeSupport Support = getPragmaAttributeSupport(Records);
+  ParsedAttrMap Attrs = getParsedAttrList(Records);
+  unsigned NumAttrs = 0;
+  for (const auto &I : Attrs) {
+    if (Support.isAttributedSupported(*I.second))
+      ++NumAttrs;
+  }
+  OS << "#pragma clang attribute supports " << NumAttrs << " attributes:\n";
+  for (const auto &I : Attrs) {
+    if (!Support.isAttributedSupported(*I.second))
+      continue;
+    OS << I.first;
+    if (I.second->isValueUnset("Subjects")) {
+      OS << " ()\n";
+      continue;
+    }
+    const Record *SubjectObj = I.second->getValueAsDef("Subjects");
+    std::vector<Record *> Subjects =
+        SubjectObj->getValueAsListOfDefs("Subjects");
+    OS << " (";
+    for (const auto &Subject : llvm::enumerate(Subjects)) {
+      if (Subject.Index)
+        OS << ", ";
+      PragmaClangAttributeSupport::RuleOrAggregateRuleSet &RuleSet =
+          Support.SubjectsToRules.find(Subject.Value)->getSecond();
+      if (RuleSet.isRule()) {
+        OS << RuleSet.getRule().getEnumValueName();
+        continue;
+      }
+      OS << "(";
+      for (const auto &Rule : llvm::enumerate(RuleSet.getAggregateRuleSet())) {
+        if (Rule.Index)
+          OS << ", ";
+        OS << Rule.Value.getEnumValueName();
+      }
+      OS << ")";
+    }
+    OS << ")\n";
   }
 }
 
diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp
index 6fb5b00..1cdb0f1 100644
--- a/utils/TableGen/TableGen.cpp
+++ b/utils/TableGen/TableGen.cpp
@@ -25,8 +25,10 @@
 enum ActionType {
   GenClangAttrClasses,
   GenClangAttrParserStringSwitches,
+  GenClangAttrSubjectMatchRulesParserStringSwitches,
   GenClangAttrImpl,
   GenClangAttrList,
+  GenClangAttrSubjectMatchRuleList,
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
   GenClangAttrHasAttributeImpl,
@@ -53,7 +55,8 @@
   GenArmNeonSema,
   GenArmNeonTest,
   GenAttrDocs,
-  GenDiagDocs
+  GenDiagDocs,
+  GenTestPragmaAttributeSupportedAttributes
 };
 
 namespace {
@@ -65,10 +68,17 @@
         clEnumValN(GenClangAttrParserStringSwitches,
                    "gen-clang-attr-parser-string-switches",
                    "Generate all parser-related attribute string switches"),
+        clEnumValN(GenClangAttrSubjectMatchRulesParserStringSwitches,
+                   "gen-clang-attr-subject-match-rules-parser-string-switches",
+                   "Generate all parser-related attribute subject match rule"
+                   "string switches"),
         clEnumValN(GenClangAttrImpl, "gen-clang-attr-impl",
                    "Generate clang attribute implementations"),
         clEnumValN(GenClangAttrList, "gen-clang-attr-list",
                    "Generate a clang attribute list"),
+        clEnumValN(GenClangAttrSubjectMatchRuleList,
+                   "gen-clang-attr-subject-match-rule-list",
+                   "Generate a clang attribute subject match rule list"),
         clEnumValN(GenClangAttrPCHRead, "gen-clang-attr-pch-read",
                    "Generate clang PCH attribute reader"),
         clEnumValN(GenClangAttrPCHWrite, "gen-clang-attr-pch-write",
@@ -79,8 +89,7 @@
         clEnumValN(GenClangAttrSpellingListIndex,
                    "gen-clang-attr-spelling-index",
                    "Generate a clang attribute spelling index"),
-        clEnumValN(GenClangAttrASTVisitor,
-                   "gen-clang-attr-ast-visitor",
+        clEnumValN(GenClangAttrASTVisitor, "gen-clang-attr-ast-visitor",
                    "Generate a recursive AST visitor for clang attributes"),
         clEnumValN(GenClangAttrTemplateInstantiate,
                    "gen-clang-attr-template-instantiate",
@@ -135,7 +144,11 @@
         clEnumValN(GenAttrDocs, "gen-attr-docs",
                    "Generate attribute documentation"),
         clEnumValN(GenDiagDocs, "gen-diag-docs",
-                   "Generate attribute documentation")));
+                   "Generate diagnostic documentation"),
+        clEnumValN(GenTestPragmaAttributeSupportedAttributes,
+                   "gen-clang-test-pragma-attribute-supported-attributes",
+                   "Generate a list of attributes supported by #pragma clang "
+                   "attribute for testing purposes")));
 
 cl::opt<std::string>
 ClangComponent("clang-component",
@@ -150,12 +163,18 @@
   case GenClangAttrParserStringSwitches:
     EmitClangAttrParserStringSwitches(Records, OS);
     break;
+  case GenClangAttrSubjectMatchRulesParserStringSwitches:
+    EmitClangAttrSubjectMatchRulesParserStringSwitches(Records, OS);
+    break;
   case GenClangAttrImpl:
     EmitClangAttrImpl(Records, OS);
     break;
   case GenClangAttrList:
     EmitClangAttrList(Records, OS);
     break;
+  case GenClangAttrSubjectMatchRuleList:
+    EmitClangAttrSubjectMatchRuleList(Records, OS);
+    break;
   case GenClangAttrPCHRead:
     EmitClangAttrPCHRead(Records, OS);
     break;
@@ -238,6 +257,9 @@
   case GenDiagDocs:
     EmitClangDiagDocs(Records, OS);
     break;
+  case GenTestPragmaAttributeSupportedAttributes:
+    EmitTestPragmaAttributeSupportedAttributes(Records, OS);
+    break;
   }
 
   return false;
diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h
index 0305ed1..20b3a50 100644
--- a/utils/TableGen/TableGenBackends.h
+++ b/utils/TableGen/TableGenBackends.h
@@ -33,9 +33,12 @@
                        const std::string &N, const std::string &S);
 
 void EmitClangAttrParserStringSwitches(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrSubjectMatchRulesParserStringSwitches(RecordKeeper &Records,
+                                                        raw_ostream &OS);
 void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrSubjectMatchRuleList(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrHasAttrImpl(RecordKeeper &Records, raw_ostream &OS);
@@ -71,6 +74,9 @@
 void EmitClangAttrDocs(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangDiagDocs(RecordKeeper &Records, raw_ostream &OS);
 
+void EmitTestPragmaAttributeSupportedAttributes(RecordKeeper &Records,
+                                                raw_ostream &OS);
+
 } // end namespace clang
 
 #endif
diff --git a/utils/perf-training/lit.cfg b/utils/perf-training/lit.cfg
index edae551..16c9367 100644
--- a/utils/perf-training/lit.cfg
+++ b/utils/perf-training/lit.cfg
@@ -7,7 +7,7 @@
 def getSysrootFlagsOnDarwin(config, lit_config):
     # On Darwin, support relocatable SDKs by providing Clang with a
     # default system root path.
-    if 'darwin' in config.target_triple:
+    if lit.util.isMacOSTriple(config.target_triple):
         try:
             out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
             res = 0
diff --git a/utils/perf-training/order-files.lit.cfg b/utils/perf-training/order-files.lit.cfg
index a4fd812..3ea3c9e 100644
--- a/utils/perf-training/order-files.lit.cfg
+++ b/utils/perf-training/order-files.lit.cfg
@@ -8,7 +8,7 @@
 def getSysrootFlagsOnDarwin(config, lit_config):
     # On Darwin, support relocatable SDKs by providing Clang with a
     # default system root path.
-    if 'darwin' in config.target_triple:
+    if lit.util.isMacOSTriple(config.target_triple):
         try:
             out = lit.util.capture(['xcrun', '--show-sdk-path']).strip()
             res = 0
diff --git a/www/analyzer/alpha_checks.html b/www/analyzer/alpha_checks.html
index 0312d16..ce9392b 100644
--- a/www/analyzer/alpha_checks.html
+++ b/www/analyzer/alpha_checks.html
@@ -910,6 +910,30 @@
 }
 </pre></div></div></td></tr>
 
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.unix.cstring.BlockInCriticalSection</span><span class="lang">
+(C)</span><div class="descr">
+Check for calls to blocking functions inside a critical section; applies
+to:<div class=functions>
+lock, unlock<br>
+sleep<br>
+getc<br>
+fgets<br>
+read<br>
+recv<br>
+pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock<br>
+mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock<br>
+</div></div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void testBlockInCriticalSection() {
+  std::mutex m;
+  m.lock();
+  sleep(3); // warn
+  m.unlock();
+}
+</pre></div></div></td></tr>
 </tbody></table>
 
 </div> <!-- page -->