Propagating prior merge from 'llvm.org/release_50'.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2667b1d..f16c8eb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -411,7 +411,8 @@
 
 # All targets below may depend on all tablegen'd files.
 get_property(CLANG_TABLEGEN_TARGETS GLOBAL PROPERTY CLANG_TABLEGEN_TARGETS)
-list(APPEND LLVM_COMMON_DEPENDS ${CLANG_TABLEGEN_TARGETS})
+add_custom_target(clang-tablegen-targets DEPENDS ${CLANG_TABLEGEN_TARGETS})
+list(APPEND LLVM_COMMON_DEPENDS clang-tablegen-targets)
 
 add_subdirectory(lib)
 add_subdirectory(tools)
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/ClangConfig.cmake.in b/cmake/modules/ClangConfig.cmake.in
index 03bca69..a5a7eae 100644
--- a/cmake/modules/ClangConfig.cmake.in
+++ b/cmake/modules/ClangConfig.cmake.in
@@ -11,3 +11,10 @@
 
 # Provide all our library targets to users.
 include("@CLANG_CONFIG_EXPORTS_FILE@")
+
+# By creating clang-tablegen-targets here, subprojects that depend on Clang's
+# tablegen-generated headers can always depend on this target whether building
+# in-tree with Clang or not.
+if(NOT TARGET clang-tablegen-targets)
+  add_custom_target(clang-tablegen-targets)
+endif()
diff --git a/docs/ClangCommandLineReference.rst b/docs/ClangCommandLineReference.rst
index d964e34..a7b485a 100644
--- a/docs/ClangCommandLineReference.rst
+++ b/docs/ClangCommandLineReference.rst
@@ -656,10 +656,6 @@
 
 Pass <arg> to the clang compiler
 
-.. option:: -fclang-abi-compat=<version>
-
-Attempt to match the ABI of Clang <version>
-
 .. option:: -fcomment-block-commands=<arg>,<arg2>...
 
 Treat each comma separated argument in <arg> as a documentation comment block command
diff --git a/docs/Modules.rst b/docs/Modules.rst
index ed6f817..af42461 100644
--- a/docs/Modules.rst
+++ b/docs/Modules.rst
@@ -317,11 +317,12 @@
 
 .. parsed-literal::
 
-  ``config_macros`` ``export``     ``private``
+  ``config_macros`` ``export_as``  ``private``
   ``conflict``      ``framework``  ``requires``
   ``exclude``       ``header``     ``textual``
   ``explicit``      ``link``       ``umbrella``
   ``extern``        ``module``     ``use``
+  ``export``
 
 Module map file
 ---------------
@@ -381,6 +382,7 @@
     *umbrella-dir-declaration*
     *submodule-declaration*
     *export-declaration*
+    *export-as-declaration*
     *use-declaration*
     *link-declaration*
     *config-macros-declaration*
@@ -660,6 +662,30 @@
   compatibility for programs that rely on transitive inclusion (i.e.,
   all of them).
 
+Re-export Declaration
+~~~~~~~~~~~~~~~~~~
+An *export-as-declaration* specifies that the current module will have
+its interface re-exported by the named module.
+
+.. parsed-literal::
+
+  *export-as-declaration*:
+    ``export_as`` *identifier*
+
+The *export-as-declaration* names the module that the current
+module will be re-exported through. Only top-level modules
+can be re-exported, and any given module may only be re-exported
+through a single module.
+
+**Example:** In the following example, the module ``MyFrameworkCore``
+will be re-exported via the module ``MyFramework``:
+
+.. parsed-literal::
+
+  module MyFrameworkCore {
+    export_as MyFramework
+  }
+
 Use declaration
 ~~~~~~~~~~~~~~~
 A *use-declaration* specifies another module that the current top-level module
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 6e8b005..4af76a7 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -316,28 +316,10 @@
 Undefined Behavior Sanitizer (UBSan)
 ------------------------------------
 
-- The Undefined Behavior Sanitizer has a new check for pointer overflow. This
-  check is on by default. The flag to control this functionality is
-  ``-fsanitize=pointer-overflow``.
-
-  Pointer overflow is an indicator of undefined behavior: when a pointer
-  indexing expression wraps around the address space, or produces other
-  unexpected results, its result may not point to a valid object.
-
-- UBSan has several new checks which detect violations of nullability
-  annotations. These checks are off by default. The flag to control this group
-  of checks is ``-fsanitize=nullability``. The checks can be individially enabled
-  by ``-fsanitize=nullability-arg`` (which checks calls),
-  ``-fsanitize=nullability-assign`` (which checks assignments), and
-  ``-fsanitize=nullability-return`` (which checks return statements).
-
-- UBSan can now detect invalid loads from bitfields and from ObjC BOOLs.
-
-- UBSan can now avoid emitting unnecessary type checks in C++ class methods and
-  in several other cases where the result is known at compile-time. UBSan can
-  also avoid emitting unnecessary overflow checks in arithmetic expressions
-  with promoted integer operands.
-
+* A minimal runtime is now available. It is suitable for use in production
+  environments, and has a small attack surface. It only provides very basic
+  issue logging and deduplication, and does not support ``-fsanitize=vptr``
+  checking.
 
 Python Binding Changes
 ----------------------
diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst
index 85dd549..81e4059 100644
--- a/docs/UndefinedBehaviorSanitizer.rst
+++ b/docs/UndefinedBehaviorSanitizer.rst
@@ -75,6 +75,7 @@
      of a misaligned reference.
   -  ``-fsanitize=bool``: Load of a ``bool`` value which is neither
      ``true`` nor ``false``.
+  -  ``-fsanitize=builtin``: Passing invalid values to compiler builtins.
   -  ``-fsanitize=bounds``: Out of bounds array indexing, in cases
      where the array bound can be statically determined.
   -  ``-fsanitize=enum``: Load of a value of an enumerated type which
@@ -86,7 +87,8 @@
   -  ``-fsanitize=float-divide-by-zero``: Floating point division by
      zero.
   -  ``-fsanitize=function``: Indirect call of a function through a
-     function pointer of the wrong type (Linux, C++ and x86/x86_64 only).
+     function pointer of the wrong type (Darwin/Linux, C++ and x86/x86_64
+     only).
   -  ``-fsanitize=integer-divide-by-zero``: Integer division by zero.
   -  ``-fsanitize=nonnull-attribute``: Passing null pointer as a function
      parameter which is declared to never be null.
@@ -130,11 +132,11 @@
      it is often unintentional, so UBSan offers to catch it.
   -  ``-fsanitize=vla-bound``: A variable-length array whose bound
      does not evaluate to a positive value.
-  -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that
-     it is of the wrong dynamic type, or that its lifetime has not
-     begun or has ended. Incompatible with ``-fno-rtti``. Link must
-     be performed by ``clang++``, not ``clang``, to make sure C++-specific
-     parts of the runtime library and C++ standard libraries are present.
+  -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that it is of
+    the wrong dynamic type, or that its lifetime has not begun or has ended.
+    Incompatible with ``-fno-rtti``. Link must be performed by ``clang++``, not
+    ``clang``, to make sure C++-specific parts of the runtime library and C++
+    standard libraries are present.
 
 You can also use the following check groups:
   -  ``-fsanitize=undefined``: All of the checks listed above other than
@@ -154,6 +156,19 @@
 The ``null``, ``alignment``, ``object-size``, and ``vptr`` checks do not apply
 to pointers to types with the ``volatile`` qualifier.
 
+Minimal Runtime
+===============
+
+There is a minimal UBSan runtime available suitable for use in production
+environments. This runtime has a small attack surface. It only provides very
+basic issue logging and deduplication, and does not support ``-fsanitize=vptr``
+checking.
+
+To use the minimal runtime, add ``-fsanitize-minimal-runtime`` to the clang
+command line options. For example, if you're used to compiling with
+``-fsanitize=undefined``, you could enable the minimal runtime with
+``-fsanitize=undefined -fsanitize-minimal-runtime``.
+
 Stack traces and report symbolization
 =====================================
 If you want UBSan to print symbolized stack trace for each error report, you
diff --git a/include/clang-c/CXErrorCode.h b/include/clang-c/CXErrorCode.h
index aff73b7..9bee50b 100644
--- a/include/clang-c/CXErrorCode.h
+++ b/include/clang-c/CXErrorCode.h
@@ -54,7 +54,25 @@
   /**
    * \brief An AST deserialization error has occurred.
    */
-  CXError_ASTReadError = 4
+  CXError_ASTReadError = 4,
+
+  /**
+  * \brief A refactoring action is not available at the given location
+  * or in the given source range.
+  */
+  CXError_RefactoringActionUnavailable = 5,
+
+  /**
+  * \brief A refactoring action is not able to use the given name because
+  * it contains an unexpected number of strings.
+  */
+  CXError_RefactoringNameSizeMismatch = 6,
+
+  /**
+  * \brief A name of a symbol is invalid, i.e. it is reserved by the source
+  * language and can't be used as a name for this symbol.
+  */
+  CXError_RefactoringNameInvalid = 7
 };
 
 #ifdef __cplusplus
diff --git a/include/clang-c/Refactor.h b/include/clang-c/Refactor.h
new file mode 100644
index 0000000..b11cfb8
--- /dev/null
+++ b/include/clang-c/Refactor.h
@@ -0,0 +1,1306 @@
+/*==-- clang-c/Refactor.h - Refactoring Public C Interface --------*- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a public inferface to a Clang library for performing  *|
+|* refactoring actions on projects without exposing the full Clang C++ API.   *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_REFACTOR_H
+#define LLVM_CLANG_C_REFACTOR_H
+
+#include "clang-c/Index.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \defgroup CINDEX_REFACTOR Refactoring options.
+ *
+ * @{
+ */
+
+/**
+ * \brief The refactoring options that can be specified for each refactoring
+ * action.
+ */
+enum CXRefactoringOption {
+  /**
+   * \brief The refactoring actions like 'rename' will avoid looking for
+   * occurrences of the renamed symbol in comments if this option is enabled.
+   */
+  CXRefactorOption_AvoidTextualMatches = 1
+};
+
+/**
+ * \brief Opaque pointer representing a set of options that can be given to
+ * a refactoring action.
+ */
+typedef void *CXRefactoringOptionSet;
+
+/**
+ * \brief Returns a new option set.
+ */
+CINDEX_LINKAGE
+CXRefactoringOptionSet clang_RefactoringOptionSet_create(void);
+
+/**
+ * \brief Parses and returns a new option set or NULL if the given string is
+ * invalid.
+ */
+CINDEX_LINKAGE
+CXRefactoringOptionSet
+clang_RefactoringOptionSet_createFromString(const char *String);
+
+/**
+ * \brief Adds a new option to the given refactoring option set.
+ */
+CINDEX_LINKAGE
+void clang_RefactoringOptionSet_add(CXRefactoringOptionSet Set,
+                                    enum CXRefactoringOption Option);
+
+/**
+ * \brief Converts the given refactoring option set to a string value.
+ */
+CINDEX_LINKAGE
+CXString clang_RefactoringOptionSet_toString(CXRefactoringOptionSet Set);
+
+/**
+ * \brief Free the given option set.
+ *
+ * Option sets should be freed by this function only when they were created
+ * using the \c clang_RefactoringOptionSet_create* methods.
+ */
+CINDEX_LINKAGE
+void clang_RefactoringOptionSet_dispose(CXRefactoringOptionSet Set);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_REFACTOR Refactoring actions.
+ *
+ * @{
+ */
+
+/**
+ * \brief The refactoring actions that can be performed by libclang.
+ */
+enum CXRefactoringActionType {
+  /**
+   * \brief The 'rename' refactoring action.
+   */
+  CXRefactor_Rename = 0,
+
+  /**
+   * \brief The local 'rename' refactoring action.
+   */
+  CXRefactor_Rename_Local = 1,
+
+  /**
+   * \brief The 'extract' refactoring action extracts source code into a
+   * new function.
+   */
+  CXRefactor_Extract = 2,
+
+  /**
+   * \brief The sub-action of 'extract' that extracts source code into a new
+   * method.
+   */
+  CXRefactor_Extract_Method = 3,
+
+  /**
+  * \brief The action that converts an if/else constructs to a switch block.
+  */
+  CXRefactor_IfSwitchConversion = 4,
+
+  /**
+  * \brief The action that wraps an Objective-C string literal in an
+  * NSLocalizedString macro.
+  */
+  CXRefactor_LocalizeObjCStringLiteral = 5,
+
+  /**
+  * \brief The action that adds missing switch cases to an switch over an enum.
+  */
+  CXRefactor_FillInEnumSwitchCases = 6,
+
+  /**
+  * \brief The action that adds missing protocol methods to an Objective-C
+  * class.
+  */
+  CXRefactor_FillInMissingProtocolStubs = 7,
+
+  /**
+  * \brief The action that extracts an expression that's repeated in a function
+  * into a new variable.
+  */
+  CXRefactor_ExtractRepeatedExpressionIntoVariable = 8,
+
+  /**
+  * \brief The action that adds missing abstract class method overrides to a
+  * class.
+  */
+  CXRefactor_FillInMissingMethodStubsFromAbstractClasses = 9,
+
+  /**
+  * \brief The action that generates dummy method definitions for method
+  * declarations without respective definitions.
+  */
+  CXRefactor_ImplementDeclaredMethods = 10,
+
+  /**
+   * \brief The sub-action of 'extract' that extracts source expression into a
+   * new variable.
+   */
+  CXRefactor_Extract_Expression = 11,
+};
+
+/**
+ * \brief Return the name of the given refactoring action.
+ */
+CINDEX_LINKAGE
+CXString
+clang_RefactoringActionType_getName(enum CXRefactoringActionType Action);
+
+/**
+ * \brief A set of refactoring actions that can be performed at some specific
+ * location in a source file.
+ *
+ * The actions in the action set are ordered by their priority: most important
+ * actions are placed before the less important ones.
+ */
+typedef struct {
+  const enum CXRefactoringActionType *Actions;
+  unsigned NumActions;
+} CXRefactoringActionSet;
+
+/**
+ * \brief Free the given refactoring action set.
+ */
+CINDEX_LINKAGE void
+clang_RefactoringActionSet_dispose(CXRefactoringActionSet *Set);
+
+typedef struct {
+  enum CXRefactoringActionType Action;
+  /**
+   * \brief The set of diagnostics that describes the reason why this action
+   * couldn't be initiated. This set of diagnostics is managed by the
+   * \c CXRefactoringActionSetWithDiagnostics and shouldn't be freed manually.
+   */
+  CXDiagnosticSet Diagnostics;
+} CXRefactoringActionWithDiagnostics;
+
+/**
+ * \brief A set of refactoring actions that couldn't be initiated at some
+ * location and their respective diagnostics that describe the reason why
+ * the initiation failed.
+ */
+typedef struct {
+  CXRefactoringActionWithDiagnostics *Actions;
+  unsigned NumActions;
+} CXRefactoringActionSetWithDiagnostics;
+
+/**
+ * \brief Free the given refactoring action set with diagnostics.
+ */
+CINDEX_LINKAGE void clang_RefactoringActionSetWithDiagnostics_dispose(
+    CXRefactoringActionSetWithDiagnostics *Set);
+
+/**
+ * \brief Find the set of refactoring actions that can be performed at the given
+ * location.
+ *
+ * This function examines the AST around the given source range and creates a
+ * \c CXRefactoringActionSet that contains all of the actions that can be
+ * performed in the given source range.
+ *
+ * \param TU The translation unit which contains the given source range.
+ *
+ * \param Location The location at which the refactoring action will be
+ * performed.
+ *
+ * \param SelectionRange The range in which the AST should be checked. Usually
+ * corresponds to the selection range or location of the cursor in the editor.
+ * Can be a null range.
+ *
+ * \param Options The optional refactoring options that might influence the way
+ * the search is performed.
+ *
+ * \param[out] OutSet A non-NULL pointer to store the created
+ * \c CXRefactoringActionSet.
+ *
+ * \returns Zero on success, CXError_RefactoringActionUnavailable when
+ * there are no actions available in the given range, or an error code
+ * otherwise.
+ */
+CINDEX_LINKAGE
+enum CXErrorCode
+clang_Refactoring_findActionsAt(CXTranslationUnit TU, CXSourceLocation Location,
+                                CXSourceRange SelectionRange,
+                                CXRefactoringOptionSet Options,
+                                CXRefactoringActionSet *OutSet);
+
+/**
+ * \brief Find the set of refactoring actions that can be performed at the given
+ * location.
+ *
+ * This function examines the AST around the given source range and creates a
+ * \c CXRefactoringActionSet that contains all of the actions that can be
+ * performed in the given source range. It also creates a
+ * \c CXRefactoringActionSetWithDiagnostics that might describe the reason why
+ * some refactoring actions are not be available.
+ *
+ * \param TU The translation unit which contains the given source range.
+ *
+ * \param Location The location at which the refactoring action will be
+ * performed.
+ *
+ * \param SelectionRange The range in which the AST should be checked. Usually
+ * corresponds to the selection range or location of the cursor in the editor.
+ * Can be a null range.
+ *
+ * \param Options The optional refactoring options that might influence the way
+ * the search is performed.
+ *
+ * \param[out] OutSet A non-NULL pointer to store the created
+ * \c CXRefactoringActionSet.
+ *
+ * \param[out] OutFailureSet An optional pointer to store the created
+ * \c CXRefactoringActionSetWithDiagnostics that describes the failures reasons
+ * for some of the refactoring actions.
+ *
+ * \returns Zero on success, CXError_RefactoringActionUnavailable when
+ * there are no actions available in the given range, or an error code
+ * otherwise.
+ */
+CINDEX_LINKAGE
+enum CXErrorCode clang_Refactoring_findActionsWithInitiationFailureDiagnosicsAt(
+    CXTranslationUnit TU, CXSourceLocation Location,
+    CXSourceRange SelectionRange, CXRefactoringOptionSet Options,
+    CXRefactoringActionSet *OutSet,
+    CXRefactoringActionSetWithDiagnostics *OutFailureSet);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_REFACTOR_INITIATE Refactoring initiation
+ *
+ * @{
+ */
+
+/**
+ * \brief Opaque pointer representing the initiated refactoring action.
+ */
+typedef void *CXRefactoringAction;
+
+/**
+ * \brief Free the given refactoring action.
+ *
+ * The refactoring action should be freed before the initiation and/or
+ * implementation translation units.
+ */
+CINDEX_LINKAGE void clang_RefactoringAction_dispose(CXRefactoringAction Action);
+
+/**
+ * \brief Return the source range that's associated with the initiated
+ * refactoring action.
+ *
+ * The returned source range covers the source that will be modified by the
+ * given refactoring action. If the action has no associated source range,
+ * then this function will return a null \c CXSourceRange.
+ */
+CINDEX_LINKAGE CXSourceRange
+clang_RefactoringAction_getSourceRangeOfInterest(CXRefactoringAction Action);
+
+/**
+ * \brief Return the type of the initiated action, which might be different
+ * to the type of the requested action. For an operation 'rename', the action
+ * could actually initiate the local 'rename' operation.
+ */
+CINDEX_LINKAGE
+enum CXRefactoringActionType
+clang_RefactoringAction_getInitiatedActionType(CXRefactoringAction Action);
+
+/**
+ * \brief Return a non-zero value when the refactoring action requires access
+ * to an additional translation unit that contains an implementation of some
+ * declaration.
+ */
+// TODO: Remove (this is no longer needed due to refactoring continuations).
+CINDEX_LINKAGE
+int clang_RefactoringAction_requiresImplementationTU(
+    CXRefactoringAction Action);
+
+/**
+ * \brief Return a USR that corresponds to the declaration whose implementation
+ * is required in order for the given refactoring action to work correctly.
+ */
+// TODO: Remove (this is no longer needed due to refactoring continuations).
+CINDEX_LINKAGE
+CXString clang_RefactoringAction_getUSRThatRequiresImplementationTU(
+    CXRefactoringAction Action);
+
+/**
+ * \brief Set the translation unit that contains the declaration whose
+ * implementation is required for the given refactoring action to work
+ * correctly.
+ */
+// TODO: Remove (this is no longer needed due to refactoring continuations).
+CINDEX_LINKAGE
+enum CXErrorCode
+clang_RefactoringAction_addImplementationTU(CXRefactoringAction Action,
+                                            CXTranslationUnit TU);
+
+/**
+ * \brief A refactoring candidate determines on which piece of source code the
+ * action should be applied.
+ *
+ * Most refactoring actions have just one candidate, but some actions, like
+ * 'Extract' can produce multiple candidates.
+ *
+ * The candidates are managed by the refactoring action, and their description
+ * string doesn't need to be freed manually.
+ */
+typedef struct { CXString Description; } CXRefactoringCandidate;
+
+/**
+ * \brief A set of refactoring candidates on which the previously initiatied
+ * refactoring action can be performed.
+ *
+ * The candidates in the candidate set are ordered by their priority: the
+ * ones that are more likely to be selected are placed before the other ones.
+ *
+ * A non-empty refactoring candidate set always has more than one refactoring
+ * candidate, because when a refactoring action has just one candidate,
+ * \c clang_RefactoringAction_getRefactoringCandidates will return an empty
+ * candidate set.
+ */
+typedef struct {
+  const CXRefactoringCandidate *Candidates;
+  unsigned NumCandidates;
+} CXRefactoringCandidateSet;
+
+/**
+ * \brief Returns the given action's refactoring candidates.
+ *
+ * The resulting refactoring candidate set will be empty when the given \c
+ * CXRefactoringAction has just one refactoring candidate.
+ *
+ * \param Action A previously initiated \c CXRefactoringAction.
+ *
+ * \param[out] OutRefactoringCandidateSet An pointer to store the action's
+ * refactoring candidate set.
+ *
+ * \returns Zero on success, or an error code otherwise.
+ */
+CINDEX_LINKAGE
+enum CXErrorCode clang_RefactoringAction_getRefactoringCandidates(
+    CXRefactoringAction Action,
+    CXRefactoringCandidateSet *OutRefactoringCandidateSet);
+
+/**
+ * \brief Tells the given refactoring action that it has to perform the
+ * operation on the refactoring candidate that's located at \p Index in the \c
+ * CXRefactoringCandidateSet.
+ */
+CINDEX_LINKAGE
+enum CXErrorCode
+clang_RefactoringAction_selectRefactoringCandidate(CXRefactoringAction Action,
+                                                   unsigned Index);
+
+// TODO: Remove.
+CINDEX_LINKAGE
+enum CXErrorCode clang_Refactoring_initiateActionAt(
+    CXTranslationUnit TU, CXSourceLocation Location,
+    CXSourceRange SelectionRange, enum CXRefactoringActionType ActionType,
+    CXRefactoringOptionSet Options, CXRefactoringAction *OutAction,
+    CXString *OutFailureReason);
+
+/**
+ * \brief Initiate a specific refactoring action at the given location.
+ *
+ * This function initiates an \p ActionType refactoring action when it can
+ * be initiated at the given location and creates a \c CXRefactoringAction
+ * action that will allow the control.
+ *
+ * \param TU The translation unit in which the action should be initiated.
+ *
+ * \param Location The location at which the refactoring action will be
+ * performed.
+ *
+ * \param SelectionRange The range in which the AST should be checked. Usually
+ * corresponds to the selection range or location of the cursor in the editor.
+ * Can be a null range.
+ *
+ * \param ActionType The type of action that should be initiated.
+ *
+ * \param Options The optional refactoring options that might have an influence
+ * on the initiation process.
+ *
+ * \param[out] OutAction A non-NULL pointer to store the created
+ * \c CXRefactoringAction.
+ *
+ * \param[out] OutDiagnostics An optional pointer to store any diagnostics that
+ * describe why the action wasn't initiated.
+ *
+ * \returns Zero on success, CXError_RefactoringActionUnavailable when
+ * the given refactoring action can't be performed at the given location, or an
+ * error code otherwise.
+ */
+CINDEX_LINKAGE
+enum CXErrorCode clang_Refactoring_initiateAction(
+    CXTranslationUnit TU, CXSourceLocation Location,
+    CXSourceRange SelectionRange, enum CXRefactoringActionType ActionType,
+    CXRefactoringOptionSet Options, CXRefactoringAction *OutAction,
+    CXDiagnosticSet *OutDiagnostics);
+
+/**
+ * \brief Initiate a specific refactoring action on a particular declaration.
+ *
+ * This function searches for the declaration that corresponds to \p DeclUSR
+ * and initiates an \p ActionType a refactoring action on that declaration
+ * if possible.
+ *
+ * \param TU The translation unit in which the declaration is defined.
+ *
+ * \param DeclUSR The USR that corresponds to the declaration of interest.
+ *
+ * \param ActionType The type of action that should be initiated.
+ *
+ * \param Options The optional refactoring options that might have an influence
+ * on the initiation process.
+ *
+ * \param[out] OutAction A non-NULL pointer to store the created
+ * \c CXRefactoringAction.
+ *
+ * \returns Zero on success, CXError_RefactoringActionUnavailable when
+ * the given refactoring action can't be performed on the found declaration, or
+ * an error code otherwise.
+ */
+// TODO: Remove (not needed).
+CINDEX_LINKAGE
+enum CXErrorCode clang_Refactoring_initiateActionOnDecl(
+    CXTranslationUnit TU, const char *DeclUSR,
+    enum CXRefactoringActionType ActionType, CXRefactoringOptionSet Options,
+    CXRefactoringAction *OutAction, CXString *OutFailureReason);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_REFACTOR_REPLACEMENT Refactoring replacement
+ *
+ * @{
+ */
+
+/**
+ * \brief A source location in a single file that is independent of \c
+ * CXTranslationUnit.
+ */
+typedef struct { unsigned Line, Column; } CXFileLocation;
+
+/**
+ * \brief A source range in a single file that is independent of \c
+ * CXTranslationUnit.
+ */
+typedef struct { CXFileLocation Begin, End; } CXFileRange;
+
+// TODO: Remove
+typedef struct {
+  CXFileRange Range;
+  CXString ReplacementString;
+} CXRefactoringReplacement_Old;
+
+// TODO: Remove
+typedef struct {
+  CXString Filename;
+  const CXRefactoringReplacement_Old *Replacements;
+  unsigned NumReplacements;
+} CXRefactoringFileReplacementSet_Old;
+
+// TODO: Remove
+typedef struct {
+  const CXRefactoringFileReplacementSet_Old *FileReplacementSets;
+  unsigned NumFileReplacementSets;
+} CXRefactoringReplacements_Old;
+
+/**
+ * \brief Identifies a character range in the source code of a single file that
+ * should be replaced with the replacement string.
+ *
+ * Replacements are managed by the result of a specific refactoring action,
+ * like \c CXRenamingResult, and are invalidated when the refactoring result is
+ * destroyed.
+ */
+typedef struct {
+  CXFileRange Range;
+  CXString ReplacementString;
+  void *AssociatedData;
+} CXRefactoringReplacement;
+
+/**
+* \brief A set of refactoring replacements that are applicable to a certain
+ * file.
+ */
+typedef struct {
+  CXString Filename;
+  const CXRefactoringReplacement *Replacements;
+  unsigned NumReplacements;
+} CXRefactoringFileReplacementSet;
+
+/**
+ * \brief A set of refactoring replacements that have been produced by a
+ * refactoring operation.
+ *
+ * The refactoring replacements depend on \c CXRefactoringResult, and can't be
+ * used after the refactoring result is freed.
+ */
+typedef struct {
+  const CXRefactoringFileReplacementSet *FileReplacementSets;
+  unsigned NumFileReplacementSets;
+} CXRefactoringReplacements;
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_SYMBOL_OPERATION Symbol-based refactoring operation
+ * (e.g. Rename).
+ *
+ * @{
+ */
+
+/**
+ * \brief The type of a symbol occurrence.
+ *
+ * The occurrence kind determines if an occurrence can be renamed automatically
+ * or if the user has to make the decision whether or not this occurrence
+ * should be renamed.
+ */
+enum CXSymbolOccurrenceKind {
+  /**
+   * \brief This occurrence is an exact match and can be renamed automatically.
+   */
+  CXSymbolOccurrence_MatchingSymbol = 0,
+
+  /**
+  * \brief This is an occurrence of a matching selector. It can't be renamed
+  * automatically unless the indexer proves that this selector refers only
+  * to the declarations that correspond to the renamed symbol.
+  */
+  CXSymbolOccurrence_MatchingSelector = 1,
+
+  /**
+  * \brief This is an occurrence of an implicit property that uses the
+  * renamed method.
+  */
+  CXSymbolOccurrence_MatchingImplicitProperty = 2,
+
+  /**
+  * \brief This is an occurrence of an symbol name in a comment.
+  */
+  CXSymbolOccurrence_MatchingCommentString = 3,
+
+  /**
+  * \brief This is an occurrence of an symbol name in a documentation comment.
+  */
+  CXSymbolOccurrence_MatchingDocCommentString = 4,
+
+  /**
+  * \brief This is an occurrence of an symbol name in a filename in an inclusion
+  * directive.
+  */
+  CXSymbolOccurrence_MatchingFilename = 5,
+
+  /**
+  * \brief This is an occurrence of a symbol name that belongs to the extracted
+  * declaration. Note: this occurrence can be in two replacements as we might
+  * extract an out-of-line method that will be both declared and defined.
+  */
+  CXSymbolOccurrence_ExtractedDeclaration = 100,
+
+  /**
+  * \brief This is an occurrence of a symbol name that references the extracted
+  * declaration.
+  */
+  CXSymbolOccurrence_ExtractedDeclaration_Reference = 101,
+};
+
+// TODO: Remove
+typedef struct {
+  const CXRefactoringReplacement_Old *Replacements;
+  unsigned ReplacementCount;
+  enum CXSymbolOccurrenceKind Kind;
+  /**
+   * Whether or not this occurrence is inside a macro. When this is true, the
+   * replacements of the occurrence contain just a single empty replacement that
+   * points to the location of the macro expansion.
+   */
+  int IsMacroExpansion;
+} CXRenamedSymbolOccurrence;
+
+/**
+ * \brief An occurrence of a symbol.
+ *
+ * Contains the source ranges that represent the pieces of the name of the
+ * symbol. The occurrences are managed by \c CXRenamingResult, and are
+ * invalidated when \c CXRenamingResult is destroyed.
+ */
+typedef struct {
+  const CXFileRange *NamePieces;
+  unsigned NumNamePieces;
+  enum CXSymbolOccurrenceKind Kind;
+  /**
+   * Whether or not this occurrence is inside a macro. When this is true, the
+   * replacements of the occurrence contain just a single empty replacement that
+   * points to the location of the macro expansion.
+   */
+  int IsMacroExpansion;
+  unsigned SymbolIndex;
+} CXSymbolOccurrence;
+
+// TODO: Remove
+typedef struct {
+  CXString Filename;
+  const CXRenamedSymbolOccurrence *Occurrences;
+  unsigned NumOccurrences;
+} CXFileRenamingResult; // TODO: Remove
+
+/**
+* \brief A set of symbol occurrences that occur in a single file.
+ */
+typedef struct {
+  CXString Filename;
+  /**
+   * The set of occurrences for each symbol of interest.
+   */
+  const CXSymbolOccurrence *Occurrences;
+  unsigned NumOccurrences;
+} CXSymbolOccurrencesInFile;
+
+/**
+ * \brief Opaque pointer representing all of the renames that should take place
+ * in a single translation unit.
+ *
+ * The result of a renaming action is indepedent from \c CXRenamingAction, and
+ * remains valid after \c CXRenamingAction is destroyed.
+ */
+typedef void *CXRenamingResult;
+
+/**
+ * \brief Opaque pointer representing all of the symbol occurrences from a
+ * single TU/file.
+ *
+ * The result of a symbol search occurrence search operation is indepedent from
+ * \c CXRefactoringAction, and remains valid after \c CXRefactoringAction is
+ * destroyed.
+ */
+typedef void *CXSymbolOccurrencesResult;
+
+/**
+ * \brief Find the cursor that's being renamed at the given location.
+ *
+ * \param TU The translation unit in which the cursor is present.
+ *
+ * \param Location The location at which the refactoring action will be
+ * performed.
+ *
+ * \param SelectionRange The range in which the AST should be checked. Usually
+ * corresponds to the selection range or location of the cursor in the editor.
+ * Can be a null range.
+ *
+ * \returns Zero on success, CXError_RefactoringActionUnavailable when
+ * there's no suitable cursor at the given location, or an error code otherwise.
+ */
+CINDEX_LINKAGE
+enum CXErrorCode clang_Refactoring_findRenamedCursor(
+    CXTranslationUnit TU, CXSourceLocation Location,
+    CXSourceRange SelectionRange, CXCursor *OutCursor);
+
+/**
+ * \brief Initiates a renaming operation on a previously initiated refactoring
+ * action.
+ *
+ * The initiation process finds the symbols that have to be renamed for a
+ * previously initiated \c CXRefactor_Rename refactoring action.
+ *
+ * \returns Zero on success, or an error code otherwise.
+ */
+// TODO: Remove
+CINDEX_LINKAGE
+enum CXErrorCode
+clang_Refactoring_initiateRenamingOperation(CXRefactoringAction Action);
+
+/**
+ * \brief Set the new name of the renamed symbol in the given \c
+ * RenamingAction.
+ *
+ * \returns Zero on success, CXError_RefactoringNameInvalid when the new name
+ * isn't a valid identifier, CXError_RefactoringNameSizeMismatch when the new
+ * name has an incorrect number of pieces or a different error code otherwise.
+ */
+// TODO: Remove
+CINDEX_LINKAGE
+enum CXErrorCode clang_RenamingOperation_setNewName(CXRefactoringAction Action,
+                                                    const char *NewName);
+
+/**
+ * \brief Return the number of symbols that are renamed by the given renaming
+ * action.
+ *
+ * A renaming action typically works on just one symbol. However, there are
+ * certain language constructs that require work with more than one symbol in
+ * order for them to be renamed correctly. Property declarations in Objective-C
+ * are the perfect example: in addition to the actual property, the action has
+ * to rename the corresponding getters and setters, as well as the backing ivar.
+ */
+// TODO: Remove
+CINDEX_LINKAGE
+unsigned clang_RenamingOperation_getNumSymbols(CXRefactoringAction Action);
+
+/**
+ * \brief Return the USR of the declaration that was found for the symbol at the
+ * given \p Index in the given renaming action.
+ */
+// TODO: Remove
+CINDEX_LINKAGE
+CXString clang_RenamingOperation_getUSRForSymbol(CXRefactoringAction Action,
+                                                 unsigned Index);
+
+// TODO: Remove
+CINDEX_LINKAGE
+CXRenamingResult clang_Refactoring_findRenamedOccurrencesInPrimaryTUs(
+    CXRefactoringAction Action, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, struct CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles);
+
+/**
+ * \brief Find all of the occurrences of the symbol that is being searched for
+ * by the given refactoring action in the translation unit that was used to
+ * initiate the refactoring action.
+ *
+ * This function searches for all of the \c CXSymbolOccurrence in the
+ * translation units that are referenced by the given \c CXRefactoringAction by
+ * iterating through the AST of the each translation unit. The occurrences that
+ * are found don't have to be from the main file in the translation unit, they
+ * can be from files included in that translation unit.
+ *
+ * \param Action The \c CXRefactoringAction operation that was inititated by
+ * \c clang_Refactoring_initiateActionAt().
+ *
+ * \param CommandLineArgs The command-line arguments that would be
+ * passed to the \c clang executable if it were being invoked out-of-process.
+ *
+ * \param NumCommandLineArgs The number of command-line arguments in
+ * \c CommandLineArgs.
+ *
+ * \param UnsavedFiles the files that have not yet been saved to disk
+ * but may be required for parsing, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param NumUnsavedFiles the number of unsaved file entries in \p
+ * UnsavedFiles.
+ *
+ * \returns If successful, a new \c CXSymbolOccurrencesResult structure
+ * containing the occurrences of the symbol in the initiation translation unit,
+ * which should eventually be freed with \c clang_SymbolOccurrences_dispose().
+ * If symbol search fails, returns NULL.
+ */
+CINDEX_LINKAGE
+CXSymbolOccurrencesResult clang_Refactoring_findSymbolOccurrencesInInitiationTU(
+    CXRefactoringAction Action, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, struct CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles);
+
+// TODO: Remove
+typedef struct {
+  CXFileLocation Location;
+  /**
+   * The kind of the declaration/expression that was indexed at this location.
+   * This is particularly important for Objective-C selectors. The refactoring
+   * engine requires the following cursor kinds for the following indexed
+   * occurrences:
+   *   - ObjC method declaration:  CXCursor_ObjC(Instance/Class)MethodDecl
+   *   - ObjC method message send: CXCursor_ObjCMessageExpr
+   * Other occurrences can use any other cursor cursor kinds.
+   */
+  enum CXCursorKind CursorKind;
+} CXRenamedIndexedSymbolLocation;
+
+// TODO: Remove
+typedef struct {
+  /**
+   * An array of occurrences that represent indexed occurrences of a symbol.
+   * It's valid to pass-in no indexed locations, the refactoring engine will
+   * just perform textual search in that case.
+   */
+  const CXRenamedIndexedSymbolLocation *IndexedLocations;
+  unsigned IndexedLocationCount;
+  /**
+  * The kind of the declaration that is being renamed.
+  * This is particularly important for Objective-C selectors. The refactoring
+  * engine requires the following cursor kinds for the following renamed
+  * declaration:
+  *   - ObjC methods:  CXCursor_ObjC(Instance/Class)MethodDecl
+  * Other declarations can use any other cursor cursor kinds.
+  */
+  enum CXCursorKind CursorKind;
+  const char *Name;
+  const char *NewName;
+} CXRenamedIndexedSymbol;
+
+// TODO: Remove
+CINDEX_LINKAGE
+enum CXErrorCode clang_Refactoring_findRenamedOccurrencesInIndexedFile(
+    const CXRenamedIndexedSymbol *Symbols, unsigned NumSymbols, CXIndex CIdx,
+    const char *Filename, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, struct CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles, CXRefactoringOptionSet Options,
+    CXRenamingResult *OutResult);
+
+/**
+ * \brief A location of an already known occurrence of a symbol.
+ *
+ * Used for rename-indexed operation where the renaming is performed on an
+ * already indexed source file.
+ */
+typedef struct {
+  CXFileLocation Location;
+  /**
+   * The kind of the declaration/expression that was indexed at this location.
+   * This is particularly important for Objective-C selectors. The refactoring
+   * engine requires the following cursor kinds for the following indexed
+   * occurrences:
+   *   - ObjC method declaration:  CXCursor_ObjC(Instance/Class)MethodDecl
+   *   - ObjC method message send: CXCursor_ObjCMessageExpr
+   *   - filename in an #include: CXCursor_InclusionDirective
+   * Other occurrences can use any other cursor cursor kinds.
+   */
+  enum CXCursorKind CursorKind;
+} CXIndexedSymbolLocation;
+
+/**
+ * \brief A symbol that should be found the an indexer symbol search operation.
+ *
+ * Used for rename-indexed operation where the renaming is performed on an
+ * already indexed source file.
+ */
+typedef struct {
+  /**
+   * An array of occurrences that represent indexed occurrences of a symbol.
+   * It's valid to pass-in no indexed locations, the refactoring engine will
+   * just perform textual search in that case.
+   */
+  const CXIndexedSymbolLocation *IndexedLocations;
+  unsigned IndexedLocationCount;
+  /**
+   * The kind of the declaration that is being renamed.
+   * This is particularly important for Objective-C selectors. The refactoring
+   * engine requires the following cursor kinds for the following renamed
+   * declaration:
+   *   - ObjC methods:  CXCursor_ObjC(Instance/Class)MethodDecl
+   * Other declarations can use any other cursor cursor kinds.
+   */
+  enum CXCursorKind CursorKind;
+  /**
+   * The name of the symbol. Objective-C selector names should be specified
+   * using the ':' separator for selector pieces.
+   */
+  const char *Name;
+} CXIndexedSymbol;
+
+/**
+ * \brief Find all of the occurrences of a symbol in an indexed file.
+ *
+ * This function searches for all of the \c CXIndexedSymbol in the
+ * given file by inspecting the source code at the given indexed locations.
+ *
+ * The indexed operations are thread-safe and can be performed concurrently.
+ *
+ * \param Symbols The information about the symbols that includes the locations
+ * for a symbol in the file as determined by the indexer.
+ *
+ * \param NumSymbols The number of symbols in \p Symbols.
+ *
+ * \param CIdx The index object with which the translation unit will be
+ * associated.
+ *
+ * \param Filename The name of the source file that contains the given
+ * \p Locations.
+ *
+ * \param CommandLineArgs The command-line arguments that would be
+ * passed to the \c clang executable if it were being invoked out-of-process.
+ * These command-line options will be parsed and will affect how the translation
+ * unit is parsed.
+ *
+ * \param NumCommandLineArgs The number of command-line arguments in
+ * \c CommandLineArgs.
+ *
+ * \param UnsavedFiles the files that have not yet been saved to disk
+ * but may be required for parsing, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param NumUnsavedFiles the number of unsaved file entries in \p
+ * UnsavedFiles.
+ *
+ * \param Options The optional refactoring options that might have an influence
+ * on the initiation process.
+ *
+ * \param[out] OutResult A non-NULL pointer to store the created
+ * \c CXSymbolOccurrencesResult.
+ *
+ * \returns Zero on success, or a different error code otherwise.
+ */
+CINDEX_LINKAGE
+enum CXErrorCode clang_Refactoring_findSymbolOccurrencesInIndexedFile(
+    const CXIndexedSymbol *Symbols, unsigned NumSymbols, CXIndex CIdx,
+    const char *Filename, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, struct CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles, CXRefactoringOptionSet Options,
+    CXSymbolOccurrencesResult *OutResult);
+
+// TODO: Remove
+CINDEX_LINKAGE
+unsigned clang_RenamingResult_getNumModifiedFiles(CXRenamingResult Result);
+
+// TODO: Remove
+CINDEX_LINKAGE
+void clang_RenamingResult_getResultForFile(CXRenamingResult Result,
+                                           unsigned FileIndex,
+                                           CXFileRenamingResult *OutResult);
+
+// TODO: Remove
+CINDEX_LINKAGE
+void clang_RenamingResult_dispose(CXRenamingResult Result);
+
+/**
+ * \brief Return the number of files that have occurrences of the specific
+ * symbol.
+ */
+CINDEX_LINKAGE
+unsigned clang_SymbolOccurrences_getNumFiles(CXSymbolOccurrencesResult Result);
+
+/**
+ * \brief Return the set of symbol occurrences in a single file.
+ *
+ * The resulting \c CXSymbolOccurrencesInFile is managed by the
+ * \c CXSymbolOccurrencesResult and doesn't have to be disposed of manually.
+ */
+CINDEX_LINKAGE
+void clang_SymbolOccurrences_getOccurrencesForFile(
+    CXSymbolOccurrencesResult Result, unsigned FileIndex,
+    CXSymbolOccurrencesInFile *OutResult);
+
+// TODO: Support refactoring continuations for \c CXSymbolOccurrencesResult,
+// e.g. for function parameter name rename.
+
+/**
+ * \brief Free the given symbol occurrences result.
+ */
+CINDEX_LINKAGE
+void clang_SymbolOccurrences_dispose(CXSymbolOccurrencesResult Result);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_REFACTOR_PERFORM Performing refactoring operations.
+ *
+ * @{
+ */
+
+/**
+ * \brief Opaque pointer representing the results of the refactoring operation.
+ *
+ * The result of a refactoring action depends on the \c CXRefactoringAction, and
+ * is invalidated after \c CXRefactoringAction is destroyed.
+ */
+typedef void *CXRefactoringResult;
+
+/**
+ * \brief Opaque pointer representing a refactoring continuation.
+ *
+ * Refactoring continuations allow refactoring operations to run in external
+ * AST units with some results that were obtained after querying the indexer.
+ *
+ * The refactoring continuation is not dependent on the \c CXRefactoringAction
+ * or \c CXRefactoringResult. It does depend on the initiation
+ * \c CXTranslationUnit initially, but that dependency can be terminated.
+ */
+typedef void *CXRefactoringContinuation;
+
+/**
+ * \brief Opaque pointer representing a query to the indexer.
+ */
+typedef void *CXIndexerQuery;
+
+/**
+ * \brief Performs the previously initiated refactoring operation.
+ *
+ * This function executes the refactoring operation which produces a set of
+ * candidate source replacements that can be applied to the source files.
+ *
+ * \param Action The refactoring action.
+ *
+ * \param CommandLineArgs The command-line arguments that would be
+ * passed to the \c clang executable if it were being invoked out-of-process.
+ * These command-line options will be parsed and will affect how the translation
+ * unit is parsed.
+ *
+ * \param NumCommandLineArgs The number of command-line arguments in
+ * \c CommandLineArgs.
+ *
+ * \param UnsavedFiles the files that have not yet been saved to disk
+ * but may be required for parsing, including the contents of
+ * those files.  The contents and name of these files (as specified by
+ * CXUnsavedFile) are copied when necessary, so the client only needs to
+ * guarantee their validity until the call to this function returns.
+ *
+ * \param NumUnsavedFiles the number of unsaved file entries in \p
+ * UnsavedFiles.
+ *
+ * \param Options The optional refactoring options that might have an influence
+ * on the way the particular action will be performed.
+ *
+ * \param[out] OutFailureReason An optional pointer to store a message that
+ * describes why the action wasn't performed.
+ *
+ * \returns If successful, a new \c CXRefactoringResult structure containing the
+ * source replacement candidates, which should eventually be freed with
+ * \c clang_RefactoringResult_dispose(). If the refactoring operation fails,
+ * returns NULL.
+ */
+CINDEX_LINKAGE
+CXRefactoringResult clang_Refactoring_performOperation(
+    CXRefactoringAction Action, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, struct CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles, CXRefactoringOptionSet Options,
+    CXString *OutFailureReason);
+
+// TODO: Remove. This is the deprecated API.
+CINDEX_LINKAGE
+void clang_RefactoringResult_getReplacements(
+    CXRefactoringResult Result, CXRefactoringReplacements_Old *OutReplacements);
+
+/**
+ * \brief Return the set of refactoring source replacements.
+ *
+ * The resulting \c CXRefactoringReplacements are managed by the
+ * \c CXRefactoringResult and don't have to be disposed of manually.
+ */
+CINDEX_LINKAGE
+CXRefactoringReplacements
+clang_RefactoringResult_getSourceReplacements(CXRefactoringResult Result);
+
+/**
+ * \brief Represents a set of symbol occurrences that are associated with a
+ * single refactoring replacement.
+ *
+ * The symbol occurrences depend on \c CXRefactoringResult, and can't be
+ * used after the refactoring result is freed.
+ */
+typedef struct {
+  const CXSymbolOccurrence *AssociatedSymbolOccurrences;
+  unsigned NumAssociatedSymbolOccurrences;
+} CXRefactoringReplacementAssociatedSymbolOccurrences;
+
+/**
+ * \brief Return the set of symbol occurrences that are associated with the
+ * given \p Replacement.
+ */
+CXRefactoringReplacementAssociatedSymbolOccurrences
+clang_RefactoringReplacement_getAssociatedSymbolOccurrences(
+    CXRefactoringReplacement Replacement);
+
+/**
+ * \brief Returns the refactoring continuation associated with this result, or
+ * NULL if this result has no refactoring continuation.
+ */
+CINDEX_LINKAGE
+CXRefactoringContinuation
+clang_RefactoringResult_getContinuation(CXRefactoringResult Result);
+
+/**
+ * \brief Free the given refactoring result.
+ */
+CINDEX_LINKAGE
+void clang_RefactoringResult_dispose(CXRefactoringResult Result);
+
+/**
+ * \brief Load the indexer query results from a YAML string.
+ *
+ * Mainly used for testing.
+ */
+CINDEX_LINKAGE
+enum CXErrorCode
+clang_RefactoringContinuation_loadSerializedIndexerQueryResults(
+    CXRefactoringContinuation Continuation, const char *Source);
+
+/**
+ * \brief Return the number of indexer queries that a refactoring continuation
+ * has.
+ */
+CINDEX_LINKAGE
+unsigned clang_RefactoringContinuation_getNumIndexerQueries(
+    CXRefactoringContinuation Continuation);
+
+/**
+ * \brief Return the indexer query at index \p Index.
+ */
+CINDEX_LINKAGE
+CXIndexerQuery clang_RefactoringContinuation_getIndexerQuery(
+    CXRefactoringContinuation Continuation, unsigned Index);
+
+/**
+ * \brief Verify that the all of the indexer queries are satisfied by the
+ * continuation.
+ *
+ * \returns Null if all of the queries are satisfied an no errors have been
+ * reported, or a set of diagnostics that describes why the continuation should
+ * not be run.
+ */
+CINDEX_LINKAGE
+CXDiagnosticSet clang_RefactoringContinuation_verifyBeforeFinalizing(
+    CXRefactoringContinuation Continuation);
+
+/**
+ * \brief Terminate the connection between the initiation TU and the refactoring
+ * continuation.
+ *
+ * The continuation converts all the TU-specific state to TU-independent state.
+ * The indexer queries that are associate with this continuation are also
+ * invalidated.
+ */
+CINDEX_LINKAGE
+void clang_RefactoringContinuation_finalizeEvaluationInInitationTU(
+    CXRefactoringContinuation Continuation);
+
+/**
+ * \brief Continue performing the previously initiated and performed refactoring
+ * operation in the given translation unit \p TU.
+ */
+CINDEX_LINKAGE
+CXRefactoringResult clang_RefactoringContinuation_continueOperationInTU(
+    CXRefactoringContinuation Continuation, CXTranslationUnit TU,
+    CXString *OutFailureReason);
+
+/**
+ * \brief Free the given refactoring continuation.
+ */
+CINDEX_LINKAGE
+void clang_RefactoringContinuation_dispose(
+    CXRefactoringContinuation Continuation);
+
+/**
+ * @}
+ */
+
+/**
+ * \defgroup CINDEX_REFACTOR_INDEXER_QUERY Indexer Queries.
+ *
+ * @{
+ */
+
+/**
+ * \brief The types of indexer queries.
+ */
+enum CXIndexerQueryKind {
+  CXIndexerQuery_Unknown = 0,
+
+  /**
+   * \brief The indexer should find the file that contains/should contain the
+   * implementation of some declaration.
+   * A file result is expected.
+   */
+  CXIndexerQuery_Decl_FileThatShouldImplement = 1,
+
+  /**
+   * \brief The indexer should determine if the some declaration is defined.
+   * An integer result is expected.
+   */
+  CXIndexerQuery_Decl_IsDefined = 2,
+};
+
+/**
+ * \brief Return the kind of the indexer query \p Query.
+ */
+CINDEX_LINKAGE
+enum CXIndexerQueryKind clang_IndexerQuery_getKind(CXIndexerQuery Query);
+
+/**
+ * \brief Return the number of cursors that the \p Query has.
+ */
+CINDEX_LINKAGE
+unsigned clang_IndexerQuery_getNumCursors(CXIndexerQuery Query);
+
+/**
+ * \brief Return the cursor at the given \p CursorIndex.
+ */
+CINDEX_LINKAGE
+CXCursor clang_IndexerQuery_getCursor(CXIndexerQuery Query,
+                                      unsigned CursorIndex);
+
+/**
+ * \brief The action that the indexer should take after evaluating the query.
+ */
+enum CXIndexerQueryAction {
+  /**
+   * \brief This result requires no further action.
+   */
+  CXIndexerQueryAction_None = 0,
+
+  /**
+   * \brief The indexer should run the \c CXRefactoringContinuaton in a
+   * translation unit that contains this file.
+   */
+  CXIndexerQueryAction_RunContinuationInTUThatHasThisFile = 1,
+};
+
+/**
+ * \brief Consumes an integer/boolean query result.
+ */
+CINDEX_LINKAGE
+enum CXIndexerQueryAction
+clang_IndexerQuery_consumeIntResult(CXIndexerQuery Query, unsigned CursorIndex,
+                                    int Value);
+
+/**
+ * \brief Consumes a filename query result.
+ *
+ * This function may return
+ * \c CXIndexerQueryAction_RunContinuationInTUThatHasThisFile which
+ * should tell the indexer that it has to run the refactoring continuation in
+ * the TU that contains this file.
+ */
+CINDEX_LINKAGE
+enum CXIndexerQueryAction
+clang_IndexerQuery_consumeFileResult(CXIndexerQuery Query, unsigned CursorIndex,
+                                     const char *Filename);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LLVM_CLANG_C_REFACTOR_H */
diff --git a/include/clang/APINotes/APINotesManager.h b/include/clang/APINotes/APINotesManager.h
new file mode 100644
index 0000000..6eb0534
--- /dev/null
+++ b/include/clang/APINotes/APINotesManager.h
@@ -0,0 +1,144 @@
+//===--- 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 };
+
+  /// 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/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/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 2f735c5..515cb77 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -375,7 +375,6 @@
     /// \brief These flags are \c true if a defaulted corresponding special
     /// member can't be fully analyzed without performing overload resolution.
     /// @{
-    unsigned NeedOverloadResolutionForCopyConstructor : 1;
     unsigned NeedOverloadResolutionForMoveConstructor : 1;
     unsigned NeedOverloadResolutionForMoveAssignment : 1;
     unsigned NeedOverloadResolutionForDestructor : 1;
@@ -384,7 +383,6 @@
     /// \brief These flags are \c true if an implicit defaulted corresponding
     /// special member would be defined as deleted.
     /// @{
-    unsigned DefaultedCopyConstructorIsDeleted : 1;
     unsigned DefaultedMoveConstructorIsDeleted : 1;
     unsigned DefaultedMoveAssignmentIsDeleted : 1;
     unsigned DefaultedDestructorIsDeleted : 1;
@@ -417,12 +415,6 @@
     /// constructor.
     unsigned HasDefaultedDefaultConstructor : 1;
 
-    /// \brief True if this class can be passed in a non-address-preserving
-    /// fashion (such as in registers) according to the C++ language rules.
-    /// This does not imply anything about how the ABI in use will actually
-    /// pass an object of this class.
-    unsigned CanPassInRegisters : 1;
-
     /// \brief True if a defaulted default constructor for this class would
     /// be constexpr.
     unsigned DefaultedDefaultConstructorIsConstexpr : 1;
@@ -819,50 +811,18 @@
     return data().FirstFriend.isValid();
   }
 
-  /// \brief \c true if a defaulted copy constructor for this class would be
-  /// deleted.
-  bool defaultedCopyConstructorIsDeleted() const {
-    assert((!needsOverloadResolutionForCopyConstructor() ||
-            (data().DeclaredSpecialMembers & SMF_CopyConstructor)) &&
-           "this property has not yet been computed by Sema");
-    return data().DefaultedCopyConstructorIsDeleted;
-  }
-
-  /// \brief \c true if a defaulted move constructor for this class would be
-  /// deleted.
-  bool defaultedMoveConstructorIsDeleted() const {
-    assert((!needsOverloadResolutionForMoveConstructor() ||
-            (data().DeclaredSpecialMembers & SMF_MoveConstructor)) &&
-           "this property has not yet been computed by Sema");
-    return data().DefaultedMoveConstructorIsDeleted;
-  }
-
-  /// \brief \c true if a defaulted destructor for this class would be deleted.
-  bool defaultedDestructorIsDeleted() const {
-    return !data().DefaultedDestructorIsDeleted;
-  }
-
-  /// \brief \c true if we know for sure that this class has a single,
-  /// accessible, unambiguous copy constructor that is not deleted.
-  bool hasSimpleCopyConstructor() const {
-    return !hasUserDeclaredCopyConstructor() &&
-           !data().DefaultedCopyConstructorIsDeleted;
-  }
-
   /// \brief \c true if we know for sure that this class has a single,
   /// accessible, unambiguous move constructor that is not deleted.
   bool hasSimpleMoveConstructor() const {
     return !hasUserDeclaredMoveConstructor() && hasMoveConstructor() &&
            !data().DefaultedMoveConstructorIsDeleted;
   }
-
   /// \brief \c true if we know for sure that this class has a single,
   /// accessible, unambiguous move assignment operator that is not deleted.
   bool hasSimpleMoveAssignment() const {
     return !hasUserDeclaredMoveAssignment() && hasMoveAssignment() &&
            !data().DefaultedMoveAssignmentIsDeleted;
   }
-
   /// \brief \c true if we know for sure that this class has an accessible
   /// destructor that is not deleted.
   bool hasSimpleDestructor() const {
@@ -918,16 +878,7 @@
   /// \brief Determine whether we need to eagerly declare a defaulted copy
   /// constructor for this class.
   bool needsOverloadResolutionForCopyConstructor() const {
-    // C++17 [class.copy.ctor]p6:
-    //   If the class definition declares a move constructor or move assignment
-    //   operator, the implicitly declared copy constructor is defined as
-    //   deleted.
-    // In MSVC mode, sometimes a declared move assignment does not delete an
-    // implicit copy constructor, so defer this choice to Sema.
-    if (data().UserDeclaredSpecialMembers &
-        (SMF_MoveConstructor | SMF_MoveAssignment))
-      return true;
-    return data().NeedOverloadResolutionForCopyConstructor;
+    return data().HasMutableFields;
   }
 
   /// \brief Determine whether an implicit copy constructor for this type
@@ -968,16 +919,7 @@
            needsImplicitMoveConstructor();
   }
 
-  /// \brief Set that we attempted to declare an implicit copy
-  /// constructor, but overload resolution failed so we deleted it.
-  void setImplicitCopyConstructorIsDeleted() {
-    assert((data().DefaultedCopyConstructorIsDeleted ||
-            needsOverloadResolutionForCopyConstructor()) &&
-           "Copy constructor should not be deleted");
-    data().DefaultedCopyConstructorIsDeleted = true;
-  }
-
-  /// \brief Set that we attempted to declare an implicit move
+  /// \brief Set that we attempted to declare an implicitly move
   /// constructor, but overload resolution failed so we deleted it.
   void setImplicitMoveConstructorIsDeleted() {
     assert((data().DefaultedMoveConstructorIsDeleted ||
@@ -1374,18 +1316,6 @@
     return data().HasIrrelevantDestructor;
   }
 
-  /// \brief Determine whether this class has at least one trivial, non-deleted
-  /// copy or move constructor.
-  bool canPassInRegisters() const {
-    return data().CanPassInRegisters;
-  }
-
-  /// \brief Set that we can pass this RecordDecl in registers.
-  // FIXME: This should be set as part of completeDefinition.
-  void setCanPassInRegisters(bool CanPass) {
-    data().CanPassInRegisters = CanPass;
-  }
-
   /// \brief Determine whether this class has a non-literal or/ volatile type
   /// non-static data member or base class.
   bool hasNonLiteralTypeFieldsOrBases() const {
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 1cd6e00..4c04fb0 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -858,6 +858,11 @@
     return Assign;
   }
 
+  /// Return true if this property has an explicitly specified getter name.
+  bool hasExplicitGetterName() const {
+    return (PropertyAttributes & OBJC_PR_getter);
+  }
+
   Selector getGetterName() const { return GetterName; }
   SourceLocation getGetterNameLoc() const { return GetterNameLoc; }
   void setGetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
@@ -865,6 +870,11 @@
     GetterNameLoc = Loc;
   }
 
+  /// Return true if this property has an explicitly specified setter name.
+  bool hasExplicitSetterName() const {
+    return (PropertyAttributes & OBJC_PR_setter);
+  }
+
   Selector getSetterName() const { return SetterName; }
   SourceLocation getSetterNameLoc() const { return SetterNameLoc; }
   void setSetterName(Selector Sel, SourceLocation Loc = SourceLocation()) {
@@ -2617,14 +2627,23 @@
   void anchor() override;
   /// Class that this is an alias of.
   ObjCInterfaceDecl *AliasedClass;
+  /// The location of the name of the referenced class.
+  SourceLocation AliasedClassLoc;
+  /// The location of the '@'.
+  SourceLocation AtLoc;
 
-  ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id,
-                          ObjCInterfaceDecl* aliasedClass)
-    : NamedDecl(ObjCCompatibleAlias, DC, L, Id), AliasedClass(aliasedClass) {}
+  ObjCCompatibleAliasDecl(DeclContext *DC, SourceLocation NameLoc,
+                          IdentifierInfo *Id, ObjCInterfaceDecl *AliasedClass,
+                          SourceLocation AliasedClassLoc, SourceLocation AtLoc)
+      : NamedDecl(ObjCCompatibleAlias, DC, NameLoc, Id),
+        AliasedClass(AliasedClass), AliasedClassLoc(AliasedClassLoc),
+        AtLoc(AtLoc) {}
+
 public:
-  static ObjCCompatibleAliasDecl *Create(ASTContext &C, DeclContext *DC,
-                                         SourceLocation L, IdentifierInfo *Id,
-                                         ObjCInterfaceDecl* aliasedClass);
+  static ObjCCompatibleAliasDecl *
+  Create(ASTContext &C, DeclContext *DC, SourceLocation NameLoc,
+         IdentifierInfo *Id, ObjCInterfaceDecl *AliasedClass,
+         SourceLocation AliasedClassLoc, SourceLocation AtLoc);
 
   static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, 
                                                      unsigned ID);
@@ -2633,6 +2652,17 @@
   ObjCInterfaceDecl *getClassInterface() { return AliasedClass; }
   void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; }
 
+  SourceLocation getClassInterfaceLoc() const { return AliasedClassLoc; }
+
+  void setClassInterfaceLoc(SourceLocation Loc) { AliasedClassLoc = Loc; }
+
+  SourceLocation getAtLoc() const { return AtLoc; }
+  void setAtLoc(SourceLocation Loc) { AtLoc = Loc; }
+
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(AtLoc, AtLoc);
+  }
+
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == ObjCCompatibleAlias; }
 
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 2879452..1d0a203 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -157,6 +157,9 @@
     return SourceRange(TemplateLoc, RAngleLoc);
   }
 
+  void print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
+             const ASTContext &Context, unsigned Indentation = 0) const;
+
   friend TrailingObjects;
 
   template <size_t N, bool HasRequiresClause>
diff --git a/include/clang/AST/DependentASTVisitor.h b/include/clang/AST/DependentASTVisitor.h
new file mode 100644
index 0000000..4177344
--- /dev/null
+++ b/include/clang/AST/DependentASTVisitor.h
@@ -0,0 +1,91 @@
+//===--- DependentASTVisitor.h - Helper for dependent nodes -----*- 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 DependentASTVisitor RecursiveASTVisitor layer, which
+//  is responsible for visiting unresolved symbol references.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DEPENDENT_AST_VISITOR_H
+#define LLVM_CLANG_AST_DEPENDENT_AST_VISITOR_H
+
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/AST/Type.h"
+
+namespace clang {
+
+// TODO: Use in the indexer.
+template <typename Derived>
+class DependentASTVisitor : public RecursiveASTVisitor<Derived> {
+private:
+  bool visitDependentReference(
+      const Type *T, const DeclarationName &Name, SourceLocation Loc,
+      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(Name, Filter);
+    // FIXME: Improve overload handling.
+    if (Symbols.size() != 1)
+      return true;
+    if (Loc.isInvalid())
+      return true;
+    return RecursiveASTVisitor<Derived>::getDerived()
+        .VisitDependentSymbolReference(Symbols[0], Loc);
+  }
+
+public:
+  bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+    const DeclarationNameInfo &Info = E->getMemberNameInfo();
+    return visitDependentReference(
+        E->getBaseType().getTypePtrOrNull(), Info.getName(), Info.getLoc(),
+        [](const NamedDecl *D) { return D->isCXXInstanceMember(); });
+  }
+
+  bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+    const DeclarationNameInfo &Info = E->getNameInfo();
+    const NestedNameSpecifier *NNS = E->getQualifier();
+    return visitDependentReference(
+        NNS->getAsType(), Info.getName(), Info.getLoc(),
+        [](const NamedDecl *D) { return !D->isCXXInstanceMember(); });
+  }
+
+  bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+    const DependentNameType *DNT = TL.getTypePtr();
+    const NestedNameSpecifier *NNS = DNT->getQualifier();
+    DeclarationName Name(DNT->getIdentifier());
+    return visitDependentReference(
+        NNS->getAsType(), Name, TL.getNameLoc(),
+        [](const NamedDecl *ND) { return isa<TypeDecl>(ND); });
+  }
+
+  bool VisitDependentSymbolReference(const NamedDecl *Symbol,
+                                     SourceLocation SymbolNameLoc) {
+    return true;
+  }
+};
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_DEPENDENT_AST_VISITOR_H
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 0cdbd2a..0b72535 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -2771,6 +2771,16 @@
   path_const_iterator path_begin() const { return path_buffer(); }
   path_const_iterator path_end() const { return path_buffer() + path_size(); }
 
+  const FieldDecl *getTargetUnionField() const {
+    assert(getCastKind() == CK_ToUnion);
+    return getTargetFieldForToUnionCast(getType(), getSubExpr()->getType());
+  }
+
+  static const FieldDecl *getTargetFieldForToUnionCast(QualType unionType,
+                                                       QualType opType);
+  static const FieldDecl *getTargetFieldForToUnionCast(const RecordDecl *RD,
+                                                       QualType opType);
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() >= firstCastExprConstant &&
            T->getStmtClass() <= lastCastExprConstant;
diff --git a/include/clang/AST/NestedNameSpecifier.h b/include/clang/AST/NestedNameSpecifier.h
index b1ff9bd..3a6a3c3 100644
--- a/include/clang/AST/NestedNameSpecifier.h
+++ b/include/clang/AST/NestedNameSpecifier.h
@@ -219,6 +219,23 @@
   /// in debugging.
   void dump(const LangOptions &LO) const;
   void dump() const;
+
+  /// \brief Compute the qualification required to get from the current context
+  /// (\p CurContext) to the target context (\p TargetContext).
+  ///
+  /// \param Context the AST context in which the qualification will be used.
+  ///
+  /// \param CurContext the context where an entity is being named, which is
+  /// typically based on the current scope.
+  ///
+  /// \param TargetContext the context in which the named entity actually
+  /// resides.
+  ///
+  /// \returns a nested name specifier that refers into the target context, or
+  /// NULL if no qualification is needed.
+  static NestedNameSpecifier *
+  getRequiredQualification(ASTContext &Context, const DeclContext *CurContext,
+                           const DeclContext *TargetContext);
 };
 
 /// \brief A C++ nested-name-specifier augmented with source location
diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h
index 274df22..4128155 100644
--- a/include/clang/AST/PrettyPrinter.h
+++ b/include/clang/AST/PrettyPrinter.h
@@ -39,7 +39,7 @@
   /// \brief Create a default printing policy for the specified language.
   PrintingPolicy(const LangOptions &LO)
     : Indentation(2), SuppressSpecifiers(false),
-      SuppressTagKeyword(LO.CPlusPlus),
+      SupressStorageClassSpecifiers(false), SuppressTagKeyword(LO.CPlusPlus),
       IncludeTagDefinition(false), SuppressScope(false),
       SuppressUnwrittenScope(false), SuppressInitializers(false),
       ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
@@ -50,7 +50,8 @@
       UseVoidForZeroParams(!LO.CPlusPlus),
       TerseOutput(false), PolishForDeclaration(false),
       Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),
-      IncludeNewlines(true), MSVCFormatting(false) { }
+      IncludeNewlines(true), MSVCFormatting(false),
+      ConstantsAsWritten(false), UseStdFunctionForLambda(false) { }
 
   /// \brief Adjust this printing policy for cases where it's known that
   /// we're printing C++ code (for instance, if AST dumping reaches a
@@ -81,6 +82,10 @@
   /// "const int" type specifier and instead only print the "*y".
   bool SuppressSpecifiers : 1;
 
+  /// \brief Whether we should supress the printing of the actual storage class
+  /// specifiers for the given declaration.
+  bool SupressStorageClassSpecifiers : 1;
+
   /// \brief Whether type printing should skip printing the tag keyword.
   ///
   /// This is used when printing the inner type of elaborated types,
@@ -200,6 +205,27 @@
   /// prints anonymous namespaces as `anonymous namespace' and does not insert
   /// spaces after template arguments.
   bool MSVCFormatting : 1;
+
+  /// \brief Whether we should print the constant expressions as written in the
+  /// sources.
+  ///
+  /// This flag determines whether constants expressions like
+  ///
+  /// \code
+  /// 0x10
+  /// 2.5e3
+  /// \endcode
+  ///
+  /// will be printed as written or as follows:
+  ///
+  /// \code
+  /// 0x10
+  /// 2.5e3
+  /// \endcode
+  bool ConstantsAsWritten;
+
+  /// \brief Whether we should use std::function<...> for lambda record types.
+  bool UseStdFunctionForLambda : 1;
 };
 
 } // end namespace clang
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index c210bd1..795f4d6 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -389,8 +389,8 @@
   /// back to its original source language syntax.
   void dumpPretty(const ASTContext &Context) const;
   void printPretty(raw_ostream &OS, PrinterHelper *Helper,
-                   const PrintingPolicy &Policy,
-                   unsigned Indentation = 0) const;
+                   const PrintingPolicy &Policy, unsigned Indentation = 0,
+                   const ASTContext *Context = nullptr) const;
 
   /// viewAST - Visualize an AST rooted at this Stmt* using GraphViz.  Only
   ///   works on systems with GraphViz (Mac OS X) or dot+gv installed.
diff --git a/include/clang/AST/StmtVisitor.h b/include/clang/AST/StmtVisitor.h
index df4a2d8..470788e 100644
--- a/include/clang/AST/StmtVisitor.h
+++ b/include/clang/AST/StmtVisitor.h
@@ -29,15 +29,17 @@
 /// StmtVisitorBase - This class implements a simple visitor for Stmt
 /// subclasses. Since Expr derives from Stmt, this also includes support for
 /// visiting Exprs.
-template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
+template<template <typename> class Ptr, typename ImplClass, typename RetTy=void,
+         class... ParamTys>
 class StmtVisitorBase {
 public:
 
 #define PTR(CLASS) typename Ptr<CLASS>::type
 #define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass*>(this)->Visit ## NAME(static_cast<PTR(CLASS)>(S))
+  return static_cast<ImplClass*>(this)->Visit ## NAME( \
+    static_cast<PTR(CLASS)>(S), std::forward<ParamTys>(P)...)
 
-  RetTy Visit(PTR(Stmt) S) {
+  RetTy Visit(PTR(Stmt) S, ParamTys... P) {
 
     // If we have a binary expr, dispatch to the subcode of the binop.  A smart
     // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
@@ -111,13 +113,13 @@
   // If the implementation chooses not to implement a certain visit method, fall
   // back on VisitExpr or whatever else is the superclass.
 #define STMT(CLASS, PARENT)                                   \
-  RetTy Visit ## CLASS(PTR(CLASS) S) { DISPATCH(PARENT, PARENT); }
+  RetTy Visit ## CLASS(PTR(CLASS) S, ParamTys... P) { DISPATCH(PARENT, PARENT); }
 #include "clang/AST/StmtNodes.inc"
 
   // If the implementation doesn't implement binary operator methods, fall back
   // on VisitBinaryOperator.
 #define BINOP_FALLBACK(NAME) \
-  RetTy VisitBin ## NAME(PTR(BinaryOperator) S) { \
+  RetTy VisitBin ## NAME(PTR(BinaryOperator) S, ParamTys... P) { \
     DISPATCH(BinaryOperator, BinaryOperator); \
   }
   BINOP_FALLBACK(PtrMemD)                    BINOP_FALLBACK(PtrMemI)
@@ -137,7 +139,7 @@
   // If the implementation doesn't implement compound assignment operator
   // methods, fall back on VisitCompoundAssignOperator.
 #define CAO_FALLBACK(NAME) \
-  RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S) { \
+  RetTy VisitBin ## NAME(PTR(CompoundAssignOperator) S, ParamTys... P) { \
     DISPATCH(CompoundAssignOperator, CompoundAssignOperator); \
   }
   CAO_FALLBACK(MulAssign) CAO_FALLBACK(DivAssign) CAO_FALLBACK(RemAssign)
@@ -149,7 +151,7 @@
   // If the implementation doesn't implement unary operator methods, fall back
   // on VisitUnaryOperator.
 #define UNARYOP_FALLBACK(NAME) \
-  RetTy VisitUnary ## NAME(PTR(UnaryOperator) S) { \
+  RetTy VisitUnary ## NAME(PTR(UnaryOperator) S, ParamTys... P) { \
     DISPATCH(UnaryOperator, UnaryOperator);    \
   }
   UNARYOP_FALLBACK(PostInc)   UNARYOP_FALLBACK(PostDec)
@@ -163,7 +165,7 @@
 #undef UNARYOP_FALLBACK
 
   // Base case, ignore it. :)
-  RetTy VisitStmt(PTR(Stmt) Node) { return RetTy(); }
+  RetTy VisitStmt(PTR(Stmt) Node, ParamTys... P) { return RetTy(); }
 
 #undef PTR
 #undef DISPATCH
@@ -174,18 +176,18 @@
 ///
 /// This class does not preserve constness of Stmt pointers (see also
 /// ConstStmtVisitor).
-template<typename ImplClass, typename RetTy=void>
+template<typename ImplClass, typename RetTy=void, typename... ParamTys>
 class StmtVisitor
- : public StmtVisitorBase<make_ptr, ImplClass, RetTy> {};
+ : public StmtVisitorBase<make_ptr, ImplClass, RetTy, ParamTys...> {};
 
 /// ConstStmtVisitor - This class implements a simple visitor for Stmt
 /// subclasses. Since Expr derives from Stmt, this also includes support for
 /// visiting Exprs.
 ///
 /// This class preserves constness of Stmt pointers (see also StmtVisitor).
-template<typename ImplClass, typename RetTy=void>
+template<typename ImplClass, typename RetTy=void, typename... ParamTys>
 class ConstStmtVisitor
- : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy> {};
+ : public StmtVisitorBase<make_const_ptr, ImplClass, RetTy, ParamTys...> {};
 
 /// \brief This class implements a simple visitor for OMPClause
 /// subclasses.
diff --git a/include/clang/Basic/AlignedAllocation.h b/include/clang/Basic/AlignedAllocation.h
new file mode 100644
index 0000000..b349694
--- /dev/null
+++ b/include/clang/Basic/AlignedAllocation.h
@@ -0,0 +1,44 @@
+//===--- AlignedAllocation.h - Aligned Allocation ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Defines a function that returns the minimum OS versions supporting
+/// C++17's aligned allocation functions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
+#define LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
+
+#include "clang/Basic/VersionTuple.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace clang {
+
+inline VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS) {
+  switch (OS) {
+  default:
+    break;
+  case llvm::Triple::Darwin:
+  case llvm::Triple::MacOSX: // Earliest supporting version is 10.13.
+    return VersionTuple(10U, 13U);
+  case llvm::Triple::IOS:
+  case llvm::Triple::TvOS: // Earliest supporting version is 11.0.0.
+    return VersionTuple(11U);
+  case llvm::Triple::WatchOS: // Earliest supporting version is 4.0.0.
+    return VersionTuple(4U);
+  }
+
+  llvm_unreachable("Unexpected OS");
+}
+
+} // end namespace clang
+
+#endif // LLVM_CLANG_BASIC_ALIGNED_ALLOCATION_H
diff --git a/include/clang/Basic/AllDiagnostics.h b/include/clang/Basic/AllDiagnostics.h
index fc861a1..4af321f 100644
--- a/include/clang/Basic/AllDiagnostics.h
+++ b/include/clang/Basic/AllDiagnostics.h
@@ -24,6 +24,7 @@
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Sema/SemaDiagnostic.h"
 #include "clang/Serialization/SerializationDiagnostic.h"
+#include "clang/Tooling/Core/RefactoringDiagnostic.h"
 
 namespace clang {
 template <size_t SizeOfStr, typename FieldType>
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index f13e13b..9b4dd62 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()}]>;
 
@@ -195,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;
@@ -654,6 +660,7 @@
              .Case("macos_app_extension", "macOS (App Extension)")
              .Case("tvos_app_extension", "tvOS (App Extension)")
              .Case("watchos_app_extension", "watchOS (App Extension)")
+             .Case("swift", "Swift")
              .Default(llvm::StringRef());
 }
 static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
@@ -1383,6 +1390,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]>;
@@ -1453,6 +1466,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]>;
@@ -1539,6 +1558,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>;
@@ -1641,6 +1666,94 @@
   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 : InheritableAttr {
+  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">,
+              BoolArgument<"IsReplacedByActive">];
+  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">,
+              BoolArgument<"IsReplacedByActive">];
+  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">,
@@ -2673,6 +2786,14 @@
   let Documentation = [Undocumented];
 }
 
+def OMPCaptureKind : Attr {
+  // This attribute has no spellings as it is only ever created implicitly.
+  let Spellings = [];
+  let SemaHandler = 0;
+  let Args = [UnsignedArgument<"CaptureKind">];
+  let Documentation = [Undocumented];
+}
+
 def OMPDeclareSimdDecl : Attr {
   let Spellings = [Pragma<"omp", "declare simd">];
   let Subjects = SubjectList<[Function]>;
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 33ef3ea..f18540a 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -2554,6 +2554,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/CMakeLists.txt b/include/clang/Basic/CMakeLists.txt
index 3e0fb87..ced4d63 100644
--- a/include/clang/Basic/CMakeLists.txt
+++ b/include/clang/Basic/CMakeLists.txt
@@ -15,6 +15,7 @@
 clang_diag_gen(Parse)
 clang_diag_gen(Sema)
 clang_diag_gen(Serialization)
+clang_diag_gen(Refactoring)
 clang_tablegen(DiagnosticGroups.inc -gen-clang-diag-groups
   SOURCE Diagnostic.td
   TARGET ClangDiagnosticGroups)
diff --git a/include/clang/Basic/Diagnostic.td b/include/clang/Basic/Diagnostic.td
index f25068e..cb87d87 100644
--- a/include/clang/Basic/Diagnostic.td
+++ b/include/clang/Basic/Diagnostic.td
@@ -139,4 +139,4 @@
 include "DiagnosticParseKinds.td"
 include "DiagnosticSemaKinds.td"
 include "DiagnosticSerializationKinds.td"
-
+include "DiagnosticRefactoringKinds.td"
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 98fd3c4..66cf135 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -94,6 +94,12 @@
   "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_shadowed : Error<
+  "import of shadowed module '%0'">;
+def err_module_lock_failure : Error<
+  "could not acquire lock file for module '%0': %1">, DefaultFatal;
+def err_module_lock_timeout : Error<
+  "timed out waiting to acquire lock file for module '%0'">, DefaultFatal;
 def err_module_cycle : Error<"cyclic dependency in module '%0': %1">, 
   DefaultFatal;
 def err_module_prebuilt : Error<
@@ -224,6 +230,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 fcef881..e5611fa 100644
--- a/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/include/clang/Basic/DiagnosticDriverKinds.td
@@ -231,7 +231,7 @@
   InGroup<DiagGroup<"rtti-for-exceptions">>;
 def warn_drv_disabling_vptr_no_rtti_default : Warning<
   "implicitly disabling vptr sanitizer because rtti wasn't enabled">,
-  InGroup<DiagGroup<"auto-disable-vptr-sanitizer">>;
+  InGroup<AutoDisableVptrSanitizer>;
 def warn_drv_object_size_disabled_O0 : Warning<
   "the object size sanitizer has no effect at -O0, but is explicitly enabled: %0">,
   InGroup<InvalidCommandLineArgument>;
diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td
index 57c24e9..38bc726 100644
--- a/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -216,6 +216,10 @@
   Error<"file '%0' specified by '-fmodules-embed-file=' not found">,
   DefaultFatal;
 
+def remark_index_producing_module_file_data : Remark<"producing index data for "
+  "module file '%0'">,
+  InGroup<IndexStore>;
+
 def err_test_module_file_extension_version : Error<
   "test module file extension '%0' has different version (%1.%2) than expected "
   "(%3.%4)">;
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 23e4d46..9387ed2 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -27,6 +27,7 @@
 def GNUAutoType : DiagGroup<"gnu-auto-type">;
 def ArrayBounds : DiagGroup<"array-bounds">;
 def ArrayBoundsPointerArithmetic : DiagGroup<"array-bounds-pointer-arithmetic">;
+def AutoDisableVptrSanitizer : DiagGroup<"auto-disable-vptr-sanitizer">;
 def Availability : DiagGroup<"availability">;
 def Section : DiagGroup<"section">;
 def AutoImport : DiagGroup<"auto-import">;
@@ -299,6 +300,7 @@
 def ModuleBuild : DiagGroup<"module-build">;
 def ModuleConflict : DiagGroup<"module-conflict">;
 def ModuleFileExtension : DiagGroup<"module-file-extension">;
+def IndexStore : DiagGroup<"index-store">;
 def NewlineEOF : DiagGroup<"newline-eof">;
 def Nullability : DiagGroup<"nullability">;
 def NullabilityDeclSpec : DiagGroup<"nullability-declspec">;
@@ -405,6 +407,9 @@
 def StringPlusInt : DiagGroup<"string-plus-int">;
 def StringPlusChar : DiagGroup<"string-plus-char">;
 def StrncatSize : DiagGroup<"strncat-size">;
+
+def SwiftNameAttribute : DiagGroup<"swift-name-attribute">;
+
 def TautologicalOutOfRangeCompare : DiagGroup<"tautological-constant-out-of-range-compare">;
 def TautologicalPointerCompare : DiagGroup<"tautological-pointer-compare">;
 def TautologicalOverlapCompare : DiagGroup<"tautological-overlap-compare">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index cdd3585..14fb24c 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -37,8 +37,9 @@
       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_UPPER_LIMIT         = DIAG_START_ANALYSIS        +  100
+      DIAG_START_ANALYSIS      = DIAG_START_SEMA            + 4000,
+      DIAG_START_REFACTORING   = DIAG_START_ANALYSIS        +  100,
+      DIAG_UPPER_LIMIT         = DIAG_START_REFACTORING     +  100
     };
 
     class CustomDiagInfo;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 706881b..2f52005 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -674,6 +674,13 @@
   "expected integer literal as value for header attribute '%0'">;
 def err_mmap_expected_header_attribute : Error<
   "expected a header attribute name ('size' or 'mtime')">;
+def err_mmap_conflicting_export_as : Error<
+  "conflicting re-export of module '%0' as '%1' or '%2'">;
+def warn_mmap_redundant_export_as : Warning<
+  "module '%0' already re-exported as '%1'">,
+  InGroup<PrivateModule>;
+def err_mmap_submodule_export_as : Error<
+  "only top-level modules can be re-exported as public">;
 
 def warn_auto_module_import : Warning<
   "treating #%select{include|import|include_next|__include_macros}0 as an "
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 5170c07..193a31a 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -1106,6 +1106,9 @@
 def err_pragma_invalid_keyword : Error<
   "invalid argument; expected 'enable'%select{|, 'full'}0%select{|, 'assume_safety'}1 or 'disable'">;
 
+// API notes.
+def err_type_unparsed : Error<"unparsed tokens following type">;
+
 // Pragma unroll support.
 def warn_pragma_unroll_cuda_value_in_parens : Warning<
   "argument to '#pragma unroll' should not be in parentheses in CUDA C/C++">,
diff --git a/include/clang/Basic/DiagnosticRefactoringKinds.td b/include/clang/Basic/DiagnosticRefactoringKinds.td
new file mode 100644
index 0000000..41113c2
--- /dev/null
+++ b/include/clang/Basic/DiagnosticRefactoringKinds.td
@@ -0,0 +1,39 @@
+//==--- DiagnosticRefactoringKinds.td - refactoring diagnostics -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Refactoring Diagnostics
+//===----------------------------------------------------------------------===//
+
+let Component = "Refactoring" in {
+
+let CategoryName = "Rename Issue" in {
+def err_rename_builtin_function : Error<"%0 is a builtin function that "
+  "cannot be renamed">;
+def err_rename_sys_header : Error<"%0 cannot be renamed because it is "
+  "declared in a system header">;
+def err_method_rename_override_sys_framework : Error<"method %0 cannot be "
+  "renamed because it overrides a method declared in a system framework">;
+def err_rename_external_source_symbol : Error<"%0 is declared in a %1 file; "
+  "rename can be initiated in a %1 file only">;
+}
+
+let CategoryName = "Refactoring Continuation Issue" in {
+
+def err_ref_continuation_missing_implementation : Error<
+  "no %select{implementation file|@implementation declaration}0 for the "
+  "selected %select{declaration|@interface}0 %1; please add one and run the "
+  "refactoring action again">;
+
+def err_implement_declared_methods_all_implemented : Error<
+  "the selected methods are already implemented">;
+
+}
+
+} // end of Refactoring diagnostics
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 6456913..c33bf18 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1181,6 +1181,12 @@
   InGroup<Selector>, DefaultIgnore;
 def warn_unimplemented_protocol_method : Warning<
   "method %0 in protocol %1 not implemented">, InGroup<Protocol>;
+def warn_class_does_not_conform_protocol : Warning<
+  "%select{class|category}0 %1 does not conform to protocol"
+  "%plural{1: %3|2:s %3 and %4|3:s %3, %4 and %5|:s %3, %4, %5, ...}2">,
+  InGroup<Protocol>;
+def note_add_missing_protocol_stubs : Note<
+  "add stubs for missing protocol requirements">;
 def warn_multiple_selectors: Warning<
   "several methods with selector %0 of mismatched types are found "
   "for the @selector expression">,
@@ -1313,6 +1319,8 @@
   "%0 cannot be defined in a type alias template">;
 def err_type_defined_in_condition : Error<
   "%0 cannot be defined in a condition">;
+def err_type_defined_in_enum : Error<
+  "%0 cannot be defined in an enumeration">;
 
 def note_pure_virtual_function : Note<
   "unimplemented pure virtual method %0 in %1">;
@@ -2870,6 +2878,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">;
 
@@ -3253,6 +3264,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<
@@ -3378,6 +3392,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<
@@ -6420,8 +6496,8 @@
   "guarantees %2 bytes">,
   InGroup<OveralignedType>, DefaultIgnore;
 def warn_aligned_allocation_unavailable :Warning<
-  "aligned %select{allocation|deallocation}0 function of type '%1' possibly "
-  "unavailable on %2">, InGroup<AlignedAllocationUnavailable>, DefaultError;
+  "aligned %select{allocation|deallocation}0 function of type '%1' is only "
+  "available on %2 %3 or newer">, InGroup<AlignedAllocationUnavailable>, DefaultError;
 def note_silence_unligned_allocation_unavailable : Note<
   "if you supply your own aligned allocation functions, use "
   "-Wno-aligned-allocation-unavailable to silence this diagnostic">;
@@ -7925,6 +8001,7 @@
   "3:enumeration values %1, %2, and %3 not handled in switch|"
   ":%0 enumeration values not handled in switch: %1, %2, %3...}0">,
   InGroup<Switch>;
+def note_fill_in_missing_cases : Note<"add missing switch cases">;
 
 def warn_unannotated_fallthrough : Warning<
   "unannotated fall-through between switch labels">,
@@ -8201,6 +8278,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">;
@@ -8485,6 +8570,13 @@
   InGroup<OpenCLUnsupportedRGBA>;
 } // end of sema category
 
+let CategoryName = "API Notes Issue" in {
+
+def err_incompatible_replacement_type : Error<
+  "API notes replacement type %0 has a different size from original type %1">;
+
+}
+
 let CategoryName = "OpenMP Issue" in {
 // OpenMP support.
 def err_omp_expected_var_arg : Error<
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index c9230e0..2826c10 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -154,6 +154,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__)")
@@ -261,6 +262,8 @@
 LANGOPT(ApplePragmaPack, 1, 0, "Apple gcc-compatible #pragma pack handling")
 
 LANGOPT(RetainCommentsFromSystemHeaders, 1, 0, "retain documentation comments from system headers in the AST")
+LANGOPT(APINotes, 1, 0, "use external API notes")
+LANGOPT(APINotesModules, 1, 0, "use external API notes")
 
 LANGOPT(SanitizeAddressFieldPadding, 2, 0, "controls how aggressive is ASan "
                                            "field padding (0: none, 1:least "
diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h
index 177175e..453b062 100644
--- a/include/clang/Basic/Module.h
+++ b/include/clang/Basic/Module.h
@@ -95,6 +95,10 @@
 
   /// \brief The name of the umbrella entry, as written in the module map.
   std::string UmbrellaAsWritten;
+
+  /// \brief The module through which entities defined in this module will
+  /// eventually be exposed, for use in "private" modules.
+  std::string ExportAsModule;
   
 private:
   /// \brief The submodules of this module, indexed by name.
@@ -181,6 +185,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;
 
@@ -214,6 +221,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.
   ///
@@ -359,13 +369,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/Sanitizers.def b/include/clang/Basic/Sanitizers.def
index 71b1197..d6df617 100644
--- a/include/clang/Basic/Sanitizers.def
+++ b/include/clang/Basic/Sanitizers.def
@@ -50,6 +50,9 @@
 // libFuzzer
 SANITIZER("fuzzer", Fuzzer)
 
+// libFuzzer-required instrumentation, no linking.
+SANITIZER("fuzzer-no-link", FuzzerNoLink)
+
 // ThreadSanitizer
 SANITIZER("thread", Thread)
 
@@ -60,6 +63,7 @@
 SANITIZER("alignment", Alignment)
 SANITIZER("array-bounds", ArrayBounds)
 SANITIZER("bool", Bool)
+SANITIZER("builtin", Builtin)
 SANITIZER("enum", Enum)
 SANITIZER("float-cast-overflow", FloatCastOverflow)
 SANITIZER("float-divide-by-zero", FloatDivideByZero)
@@ -107,11 +111,12 @@
 // -fsanitize=undefined includes all the sanitizers which have low overhead, no
 // ABI or address space layout implications, and only catch undefined behavior.
 SANITIZER_GROUP("undefined", Undefined,
-                Alignment | Bool | ArrayBounds | Enum | FloatCastOverflow |
-                    FloatDivideByZero | IntegerDivideByZero | NonnullAttribute |
-                    Null | ObjectSize | PointerOverflow | Return |
-                    ReturnsNonnullAttribute | Shift | SignedIntegerOverflow |
-                    Unreachable | VLABound | Function | Vptr)
+                Alignment | Bool | Builtin | ArrayBounds | Enum |
+                    FloatCastOverflow | FloatDivideByZero |
+                    IntegerDivideByZero | NonnullAttribute | Null | ObjectSize |
+                    PointerOverflow | Return | ReturnsNonnullAttribute | Shift |
+                    SignedIntegerOverflow | Unreachable | VLABound | Function |
+                    Vptr)
 
 // -fsanitize=undefined-trap is an alias for -fsanitize=undefined.
 SANITIZER_GROUP("undefined-trap", UndefinedTrap, Undefined)
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 d1a9ea8..beb1a7b 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -447,6 +447,9 @@
   /// \brief Return the maximum width lock-free atomic operation which can be
   /// inlined given the supported features of the given target.
   unsigned getMaxAtomicInlineWidth() const { return MaxAtomicInlineWidth; }
+  /// \brief Set the maximum inline or promote width lock-free atomic operation
+  /// for the given target.
+  virtual void setMaxAtomicWidth() {}
   /// \brief Returns true if the given target supports lock-free atomic
   /// operations at the specified width and alignment.
   virtual bool hasBuiltinAtomic(uint64_t AtomicSizeInBits,
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/DirectoryWatcher/DirectoryWatcher.h b/include/clang/DirectoryWatcher/DirectoryWatcher.h
new file mode 100644
index 0000000..09d17a9
--- /dev/null
+++ b/include/clang/DirectoryWatcher/DirectoryWatcher.h
@@ -0,0 +1,47 @@
+//===- DirectoryWatcher.h - Listens for directory file changes --*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief Utility class for listening for file system changes in a directory.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_DIRECTORYWATCHER_DIRECTORYWATCHER_H
+#define LLVM_CLANG_DIRECTORYWATCHER_DIRECTORYWATCHER_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Index/IndexDataStore.h"
+#include <functional>
+#include <memory>
+#include <string>
+
+namespace clang {
+
+/// Provides notifications for file system changes in a directory.
+///
+/// Guarantees that the first time the directory is processed, the receiver will
+/// be invoked even if the directory is empty.
+class DirectoryWatcher : public index::AbstractDirectoryWatcher {
+  struct Implementation;
+  Implementation &Impl;
+
+  DirectoryWatcher();
+
+  DirectoryWatcher(const DirectoryWatcher&) = delete;
+  DirectoryWatcher &operator =(const DirectoryWatcher&) = delete;
+
+public:
+  ~DirectoryWatcher();
+
+  static std::unique_ptr<DirectoryWatcher>
+    create(StringRef Path, EventReceiver Receiver, bool waitInitialSync,
+           std::string &Error);
+};
+
+} // namespace clang
+
+#endif
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 205f36b..fd70845 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -461,6 +461,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. "
diff --git a/include/clang/Driver/Job.h b/include/clang/Driver/Job.h
index ff88256..09f7ab5 100644
--- a/include/clang/Driver/Job.h
+++ b/include/clang/Driver/Job.h
@@ -34,9 +34,11 @@
 struct CrashReportInfo {
   StringRef Filename;
   StringRef VFSPath;
+  StringRef IndexStorePath;
 
-  CrashReportInfo(StringRef Filename, StringRef VFSPath)
-      : Filename(Filename), VFSPath(VFSPath) {}
+  CrashReportInfo(StringRef Filename, StringRef VFSPath,
+                  StringRef IndexStorePath)
+      : Filename(Filename), VFSPath(VFSPath), IndexStorePath(IndexStorePath) {}
 };
 
 /// Command - An executable path/name and argument vector to
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 05dc9d7..d4d8ed4 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -320,6 +320,13 @@
 def : Joined<["-"], "objcmt-white-list-dir-path=">, Flags<[CC1Option]>,
     Alias<objcmt_whitelist_dir_path>;
 
+def index_store_path : Separate<["-"], "index-store-path">, Flags<[CC1Option]>,
+  HelpText<"Enable indexing with the specified data store path">;
+def index_ignore_system_symbols : Flag<["-"], "index-ignore-system-symbols">, Flags<[CC1Option]>,
+  HelpText<"Ignore symbols from system headers">;
+def index_record_codegen_name : Flag<["-"], "index-record-codegen-name">, Flags<[CC1Option]>,
+  HelpText<"Record the codegen name for symbols">;
+
 // Make sure all other -ccc- options are rejected.
 def ccc_ : Joined<["-"], "ccc-">, Group<internal_Group>, Flags<[Unsupported]>;
 
@@ -685,6 +692,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]>, MetaVarName<"<directory>">,
+  HelpText<"Does nothing; API notes are no longer cached separately from modules">;
+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>;
@@ -694,9 +716,6 @@
 def fbuiltin_module_map : Flag <["-"], "fbuiltin-module-map">, Group<f_Group>,
   Flags<[DriverOption]>, HelpText<"Load the clang builtins module map file.">;
 def fcaret_diagnostics : Flag<["-"], "fcaret-diagnostics">, Group<f_Group>;
-def fclang_abi_compat_EQ : Joined<["-"], "fclang-abi-compat=">, Group<f_clang_Group>,
-  Flags<[CC1Option]>, MetaVarName<"<version>">, Values<"<major>.<minor>,latest">,
-  HelpText<"Attempt to match the ABI of Clang <version>">;
 def fclasspath_EQ : Joined<["-"], "fclasspath=">, Group<f_Group>;
 def fcolor_diagnostics : Flag<["-"], "fcolor-diagnostics">, Group<f_Group>,
   Flags<[CoreOption, CC1Option]>, HelpText<"Use colors in diagnostics">;
@@ -868,6 +887,10 @@
                                         Group<f_clang_Group>;
 def fno_sanitize_undefined_trap_on_error : Flag<["-"], "fno-sanitize-undefined-trap-on-error">,
                                            Group<f_clang_Group>;
+def fsanitize_minimal_runtime : Flag<["-"], "fsanitize-minimal-runtime">,
+                                        Group<f_clang_Group>;
+def fno_sanitize_minimal_runtime : Flag<["-"], "fno-sanitize-minimal-runtime">,
+                                        Group<f_clang_Group>;
 def fsanitize_link_cxx_runtime : Flag<["-"], "fsanitize-link-c++-runtime">,
                                  Group<f_clang_Group>;
 def fsanitize_cfi_cross_dso : Flag<["-"], "fsanitize-cfi-cross-dso">,
@@ -1585,6 +1608,8 @@
   HelpText<"Display available options">;
 def index_header_map : Flag<["-"], "index-header-map">, Flags<[CC1Option]>,
   HelpText<"Make the next included directory (-I or -F) an indexer header map">;
+def iapinotes_modules : JoinedOrSeparate<["-"], "iapinotes-modules">, Group<clang_i_Group>, Flags<[CC1Option]>,
+  HelpText<"Add directory to the API notes search path referenced by module name">, MetaVarName<"<directory>">;
 def idirafter : JoinedOrSeparate<["-"], "idirafter">, Group<clang_i_Group>, Flags<[CC1Option]>,
   HelpText<"Add directory to AFTER include search path">;
 def iframework : JoinedOrSeparate<["-"], "iframework">, Group<clang_i_Group>, Flags<[CC1Option]>,
@@ -2131,6 +2156,7 @@
 def nostdincxx : Flag<["-"], "nostdinc++">, Flags<[CC1Option]>,
   HelpText<"Disable standard #include directories for the C++ standard library">;
 def nostdlib : Flag<["-"], "nostdlib">;
+def nostdlibxx : Flag<["-"], "nostdlib++">;
 def object : Flag<["-"], "object">;
 def o : JoinedOrSeparate<["-"], "o">, Flags<[DriverOption, RenderAsInput, CC1Option, CC1AsOption]>,
   HelpText<"Write output to <file>">, MetaVarName<"<file>">;
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index a9645d4..3021d47 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -42,6 +42,7 @@
   bool TsanMemoryAccess = true;
   bool TsanFuncEntryExit = true;
   bool TsanAtomics = true;
+  bool MinimalRuntime = false;
 
  public:
   /// Parses the sanitizer arguments from an argument list.
@@ -57,6 +58,7 @@
            !Sanitizers.has(SanitizerKind::Address);
   }
   bool needsUbsanRt() const;
+  bool requiresMinimalRuntime() const { return MinimalRuntime; }
   bool needsDfsanRt() const { return Sanitizers.has(SanitizerKind::DataFlow); }
   bool needsSafeStackRt() const {
     return Sanitizers.has(SanitizerKind::SafeStack);
diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h
index 6651491..a62a759 100644
--- a/include/clang/Driver/ToolChain.h
+++ b/include/clang/Driver/ToolChain.h
@@ -432,6 +432,10 @@
   AddClangCXXStdlibIncludeArgs(const llvm::opt::ArgList &DriverArgs,
                                llvm::opt::ArgStringList &CC1Args) const;
 
+  /// Returns if the C++ standard library should be linked in.
+  /// Note that e.g. -lm should still be linked even if this returns false.
+  bool ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const;
+
   /// AddCXXStdlibLibArgs - Add the system specific linker arguments to use
   /// for the given C++ standard library type.
   virtual void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args,
diff --git a/include/clang/Edit/RefactoringFixits.h b/include/clang/Edit/RefactoringFixits.h
new file mode 100644
index 0000000..bf8adb5
--- /dev/null
+++ b/include/clang/Edit/RefactoringFixits.h
@@ -0,0 +1,66 @@
+//===--- RefactoringFixits.h - Fixit producers for refactorings -*- 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_EDIT_REFACTORING_FIXITS_H
+#define LLVM_CLANG_EDIT_REFACTORING_FIXITS_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/STLExtras.h"
+
+namespace clang {
+
+class ASTContext;
+class SwitchStmt;
+class EnumDecl;
+class ObjCContainerDecl;
+
+namespace edit {
+
+/**
+ * Generates the fix-its that perform the "add missing switch cases" refactoring
+ * operation.
+ */
+void fillInMissingSwitchEnumCases(
+    ASTContext &Context, const SwitchStmt *Switch, const EnumDecl *Enum,
+    const DeclContext *SwitchContext,
+    llvm::function_ref<void(const FixItHint &)> Consumer);
+
+/// Responsible for the fix-its that perform the
+/// "add missing protocol requirements" refactoring operation.
+namespace fillInMissingProtocolStubs {
+
+class FillInMissingProtocolStubsImpl;
+class FillInMissingProtocolStubs {
+  std::unique_ptr<FillInMissingProtocolStubsImpl> Impl;
+
+public:
+  FillInMissingProtocolStubs();
+  ~FillInMissingProtocolStubs();
+  FillInMissingProtocolStubs(FillInMissingProtocolStubs &&);
+  FillInMissingProtocolStubs &operator=(FillInMissingProtocolStubs &&);
+
+  /// Initiate the FillInMissingProtocolStubs edit.
+  ///
+  /// \returns true on Error.
+  bool initiate(ASTContext &Context, const ObjCContainerDecl *Container);
+  bool hasMissingRequiredMethodStubs();
+  void perform(ASTContext &Context,
+               llvm::function_ref<void(const FixItHint &)> Consumer);
+};
+
+void addMissingProtocolStubs(
+    ASTContext &Context, const ObjCContainerDecl *Container,
+    llvm::function_ref<void(const FixItHint &)> Consumer);
+
+} // end namespace fillInMissingProtocolStubs
+
+} // end namespace edit
+} // end namespace clang
+
+#endif // LLVM_CLANG_EDIT_REFACTORING_FIXITS_H
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 4002415..8bfa46e 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -120,10 +120,6 @@
 ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy)
 CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is
                                         ///< enabled.
-
-/// A version of Clang that we should attempt to be ABI-compatible with.
-ENUM_CODEGENOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest)
-
 VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
 VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified.
 
@@ -152,6 +148,8 @@
 CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection
                                              ///< in MemorySanitizer
 CODEGENOPT(SanitizeCfiCrossDso, 1, 0) ///< Enable cross-dso support in CFI.
+CODEGENOPT(SanitizeMinimalRuntime, 1, 0) ///< Use "_minimal" sanitizer runtime for
+                                         ///< diagnostics.
 CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage
                                        ///< instrumentation.
 CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage
diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h
index 71730a2..22d5d3d 100644
--- a/include/clang/Frontend/CodeGenOptions.h
+++ b/include/clang/Frontend/CodeGenOptions.h
@@ -69,23 +69,6 @@
     LocalExecTLSModel
   };
 
-  /// Clang versions with different platform ABI conformance.
-  enum class ClangABI {
-    /// Attempt to be ABI-compatible with code generated by Clang 3.8.x
-    /// (SVN r257626). This causes <1 x long long> to be passed in an
-    /// integer register instead of an SSE register on x64_64.
-    Ver3_8,
-
-    /// Attempt to be ABI-compatible with code generated by Clang 4.0.x
-    /// (SVN r291814). This causes move operations to be ignored when
-    /// determining whether a class type can be passed or returned directly.
-    Ver4,
-
-    /// Conform to the underlying platform's C and C++ ABIs as closely
-    /// as we can.
-    Latest
-  };
-
   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 5b5c752..46e10ad 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -183,6 +183,12 @@
   /// The list of active output files.
   std::list<OutputFile> OutputFiles;
 
+  /// \brief An optional callback function used to wrap all FrontendActions
+  /// produced to generate imported modules before they are executed.
+  std::function<std::unique_ptr<FrontendAction>
+    (const FrontendOptions &opts, std::unique_ptr<FrontendAction> action)>
+    GenModuleActionWrapper;
+
   CompilerInstance(const CompilerInstance &) = delete;
   void operator=(const CompilerInstance &) = delete;
 public:
@@ -303,6 +309,13 @@
     return Invocation->getHeaderSearchOptsPtr();
   }
 
+  APINotesOptions &getAPINotesOpts() {
+    return Invocation->getAPINotesOpts();
+  }
+  const APINotesOptions &getAPINotesOpts() const {
+    return Invocation->getAPINotesOpts();
+  }
+
   LangOptions &getLangOpts() {
     return *Invocation->getLangOpts();
   }
@@ -794,6 +807,15 @@
 
   bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override;
 
+  void setGenModuleActionWrapper(std::function<std::unique_ptr<FrontendAction>
+    (const FrontendOptions &Opts, std::unique_ptr<FrontendAction> Action)> Wrapper) {
+    GenModuleActionWrapper = Wrapper;
+  };
+
+  std::function<std::unique_ptr<FrontendAction>
+    (const FrontendOptions &Opts, std::unique_ptr<FrontendAction> Action)>
+  getGenModuleActionWrapper() const { return GenModuleActionWrapper; }
+
   void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) {
     DependencyCollectors.push_back(std::move(Listener));
   }
diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h
index 8c4c932..4d3449f 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/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h
index e757a7e..b784a6f 100644
--- a/include/clang/Frontend/FrontendOptions.h
+++ b/include/clang/Frontend/FrontendOptions.h
@@ -256,6 +256,10 @@
   std::string MTMigrateDir;
   std::string ARCMTMigrateReportOut;
 
+  std::string IndexStorePath;
+  unsigned IndexIgnoreSystemSymbols : 1;
+  unsigned IndexRecordCodegenName : 1;
+
   /// The input files and their types.
   std::vector<FrontendInputFile> Inputs;
 
@@ -333,8 +337,9 @@
     SkipFunctionBodies(false), UseGlobalModuleIndex(true),
     GenerateGlobalModuleIndex(true), ASTDumpDecls(false), ASTDumpLookups(false),
     BuildingImplicitModule(false), ModulesEmbedAllFiles(false),
-    IncludeTimestamps(true), ARCMTAction(ARCMT_None),
-    ObjCMTAction(ObjCMT_None), ProgramAction(frontend::ParseSyntaxOnly)
+    IncludeTimestamps(true), ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None),
+    IndexIgnoreSystemSymbols(false), IndexRecordCodegenName(false),
+    ProgramAction(frontend::ParseSyntaxOnly)
   {}
 
   /// getInputKindForExtension - Return the appropriate input kind for a file
diff --git a/include/clang/Index/IndexDataStore.h b/include/clang/Index/IndexDataStore.h
new file mode 100644
index 0000000..714ccdd
--- /dev/null
+++ b/include/clang/Index/IndexDataStore.h
@@ -0,0 +1,102 @@
+//===--- IndexDataStore.h - Index data store info -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXDATASTORE_H
+#define LLVM_CLANG_INDEX_INDEXDATASTORE_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include <functional>
+#include <memory>
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace index {
+
+class AbstractDirectoryWatcher {
+public:
+  enum class EventKind {
+    /// A file was added.
+    Added,
+    /// A file was removed.
+    Removed,
+    /// A file was modified.
+    Modified,
+    /// The watched directory got deleted. No more events will follow.
+    DirectoryDeleted,
+  };
+
+  struct Event {
+    EventKind Kind;
+    std::string Filename;
+    timespec ModTime;
+  };
+
+  typedef std::function<void(ArrayRef<Event> Events, bool isInitial)> EventReceiver;
+  typedef std::unique_ptr<AbstractDirectoryWatcher>(CreateFnTy)
+    (StringRef Path, EventReceiver Receiver, bool waitInitialSync, std::string &Error);
+
+  virtual ~AbstractDirectoryWatcher() {}
+};
+
+class IndexDataStore {
+public:
+  ~IndexDataStore();
+
+  static std::unique_ptr<IndexDataStore>
+    create(StringRef IndexStorePath, std::string &Error);
+
+  StringRef getFilePath() const;
+  bool foreachUnitName(bool sorted,
+                       llvm::function_ref<bool(StringRef unitName)> receiver);
+
+  static unsigned getFormatVersion();
+
+  enum class UnitEventKind {
+    Added,
+    Removed,
+    Modified,
+    /// The directory got deleted. No more events will follow.
+    DirectoryDeleted,
+  };
+  struct UnitEvent {
+    UnitEventKind Kind;
+    StringRef UnitName;
+    timespec ModTime;
+  };
+  struct UnitEventNotification {
+    bool IsInitial;
+    ArrayRef<UnitEvent> Events;
+  };
+  typedef std::function<void(UnitEventNotification)> UnitEventHandler;
+
+  void setUnitEventHandler(UnitEventHandler Handler);
+  /// \returns true if an error occurred.
+  bool startEventListening(llvm::function_ref<AbstractDirectoryWatcher::CreateFnTy> createFn,
+                           bool waitInitialSync, std::string &Error);
+  void stopEventListening();
+
+  void discardUnit(StringRef UnitName);
+  void discardRecord(StringRef RecordName);
+
+  void purgeStaleData();
+
+private:
+  IndexDataStore(void *Impl) : Impl(Impl) {}
+
+  void *Impl; // An IndexDataStoreImpl.
+};
+
+} // namespace index
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/IndexDataStoreSymbolUtils.h b/include/clang/Index/IndexDataStoreSymbolUtils.h
new file mode 100644
index 0000000..e1d982d
--- /dev/null
+++ b/include/clang/Index/IndexDataStoreSymbolUtils.h
@@ -0,0 +1,53 @@
+//===--- IndexDataStoreSymbolUtils.h - Utilities for indexstore symbols ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXDATASTORESYMBOLUTILS_H
+#define LLVM_CLANG_INDEX_INDEXDATASTORESYMBOLUTILS_H
+
+#include "indexstore/indexstore.h"
+#include "clang/Index/IndexSymbol.h"
+
+namespace clang {
+namespace index {
+
+/// Map an indexstore_symbol_kind_t to a SymbolKind, handling unknown values.
+SymbolKind getSymbolKind(indexstore_symbol_kind_t K);
+
+SymbolSubKind getSymbolSubKind(indexstore_symbol_subkind_t K);
+
+/// Map an indexstore_symbol_language_t to a SymbolLanguage, handling unknown
+/// values.
+SymbolLanguage getSymbolLanguage(indexstore_symbol_language_t L);
+
+/// Map an indexstore representation to a SymbolPropertySet, handling
+/// unknown values.
+SymbolPropertySet getSymbolProperties(uint64_t Props);
+
+/// Map an indexstore representation to a SymbolRoleSet, handling unknown
+/// values.
+SymbolRoleSet getSymbolRoles(uint64_t Roles);
+
+/// Map a SymbolLanguage to a indexstore_symbol_language_t.
+indexstore_symbol_kind_t getIndexStoreKind(SymbolKind K);
+
+indexstore_symbol_subkind_t getIndexStoreSubKind(SymbolSubKind K);
+
+/// Map a SymbolLanguage to a indexstore_symbol_language_t.
+indexstore_symbol_language_t getIndexStoreLang(SymbolLanguage L);
+
+/// Map a SymbolPropertySet to its indexstore representation.
+uint64_t getIndexStoreProperties(SymbolPropertySet Props);
+
+/// Map a SymbolRoleSet to its indexstore representation.
+uint64_t getIndexStoreRoles(SymbolRoleSet Roles);
+
+} // end namespace index
+} // end namespace clang
+
+#endif // LLVM_CLANG_INDEX_INDEXDATASTORESYMBOLUTILS_H
diff --git a/include/clang/Index/IndexRecordReader.h b/include/clang/Index/IndexRecordReader.h
new file mode 100644
index 0000000..ef8edff
--- /dev/null
+++ b/include/clang/Index/IndexRecordReader.h
@@ -0,0 +1,109 @@
+//===--- IndexRecordReader.h - Index record deserialization ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXRECORDREADER_H
+#define LLVM_CLANG_INDEX_INDEXRECORDREADER_H
+
+#include "clang/Index/IndexSymbol.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include <memory>
+
+namespace llvm {
+  class MemoryBuffer;
+}
+
+namespace clang {
+namespace index {
+
+struct IndexRecordDecl {
+  unsigned DeclID;
+  SymbolInfo SymInfo;
+  SymbolRoleSet Roles;
+  SymbolRoleSet RelatedRoles;
+  StringRef Name;
+  StringRef USR;
+  StringRef CodeGenName;
+};
+
+struct IndexRecordRelation {
+  SymbolRoleSet Roles;
+  const IndexRecordDecl *Dcl = nullptr;
+
+  IndexRecordRelation() = default;
+  IndexRecordRelation(SymbolRoleSet Roles, const IndexRecordDecl *Dcl)
+    : Roles(Roles), Dcl(Dcl) {}
+};
+
+struct IndexRecordOccurrence {
+  const IndexRecordDecl *Dcl;
+  SmallVector<IndexRecordRelation, 4> Relations;
+  SymbolRoleSet Roles;
+  unsigned Line;
+  unsigned Column;
+};
+
+class IndexRecordReader {
+  IndexRecordReader();
+
+public:
+  static std::unique_ptr<IndexRecordReader>
+    createWithRecordFilename(StringRef RecordFilename, StringRef StorePath,
+                             std::string &Error);
+  static std::unique_ptr<IndexRecordReader>
+    createWithFilePath(StringRef FilePath, std::string &Error);
+  static std::unique_ptr<IndexRecordReader>
+    createWithBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer,
+                     std::string &Error);
+
+  ~IndexRecordReader();
+
+  struct DeclSearchReturn {
+    bool AcceptDecl;
+    bool ContinueSearch;
+  };
+  typedef DeclSearchReturn(DeclSearchCheck)(const IndexRecordDecl &);
+
+  /// Goes through and passes record decls, after filtering using a \c Checker
+  /// function.
+  ///
+  /// Resulting decls can be used as filter for \c foreachOccurrence. This
+  /// allows allocating memory only for the record decls that the caller is
+  /// interested in.
+  bool searchDecls(llvm::function_ref<DeclSearchCheck> Checker,
+                   llvm::function_ref<void(const IndexRecordDecl *)> Receiver);
+
+  /// \param NoCache if true, avoids allocating memory for the decls.
+  /// Useful when the caller does not intend to keep \c IndexRecordReader
+  /// for more queries.
+  bool foreachDecl(bool NoCache,
+                   llvm::function_ref<bool(const IndexRecordDecl *)> Receiver);
+
+  /// \param DeclsFilter if non-empty indicates the list of decls that we want
+  /// to get occurrences for. An empty array indicates that we want occurrences
+  /// for all decls.
+  /// \param RelatedDeclsFilter Same as \c DeclsFilter but for related decls.
+  bool foreachOccurrence(ArrayRef<const IndexRecordDecl *> DeclsFilter,
+                         ArrayRef<const IndexRecordDecl *> RelatedDeclsFilter,
+              llvm::function_ref<bool(const IndexRecordOccurrence &)> Receiver);
+  bool foreachOccurrence(
+              llvm::function_ref<bool(const IndexRecordOccurrence &)> Receiver);
+
+  bool foreachOccurrenceInLineRange(unsigned lineStart, unsigned lineCount,
+              llvm::function_ref<bool(const IndexRecordOccurrence &)> Receiver);
+
+  struct Implementation;
+private:
+  Implementation &Impl;
+};
+
+} // namespace index
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/IndexRecordWriter.h b/include/clang/Index/IndexRecordWriter.h
new file mode 100644
index 0000000..8a9720a
--- /dev/null
+++ b/include/clang/Index/IndexRecordWriter.h
@@ -0,0 +1,102 @@
+//===--- IndexRecordWriter.h - Index record serialization -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXRECORDWRITER_H
+#define LLVM_CLANG_INDEX_INDEXRECORDWRITER_H
+
+#include "clang/Index/IndexSymbol.h"
+#include "llvm/ADT/SmallString.h"
+
+namespace clang {
+namespace index {
+
+namespace writer {
+/// An opaque pointer to a declaration or other symbol used by the
+/// IndexRecordWriter to identify when two occurrences refer to the same symbol,
+/// and as a token for getting information about a symbol from the caller.
+typedef const void *OpaqueDecl;
+
+/// An indexer symbol suitable for serialization.
+///
+/// This includes all the information about the symbol that will be serialized
+/// except for roles, which are synthesized by looking at all the occurrences.
+///
+/// \seealso IndexRecordDecl
+/// \note this struct is generally accompanied by a buffer that owns the string
+/// storage.  It should not be stored permanently.
+struct Symbol {
+  SymbolInfo SymInfo;
+  StringRef Name;
+  StringRef USR;
+  StringRef CodeGenName;
+};
+
+/// An relation to an opaque symbol.
+/// \seealso IndexRecordRelation
+struct SymbolRelation {
+  OpaqueDecl RelatedSymbol;
+  SymbolRoleSet Roles;
+};
+
+typedef llvm::function_ref<Symbol(OpaqueDecl, SmallVectorImpl<char> &Scratch)>
+    SymbolWriterCallback;
+} // end namespace writer
+
+/// A language-independent utility for serializing index record files.
+///
+/// Internally, this class is a small state machine.  Users should first call
+/// beginRecord, and if the file does not already exist, then proceed to add
+/// all symbol occurrences (addOccurrence) and finally finish with endRecord.
+class IndexRecordWriter {
+  SmallString<64> RecordsPath; ///< The records directory path.
+  void *Record = nullptr;      ///< The state of the current record.
+public:
+  IndexRecordWriter(StringRef IndexPath);
+
+  enum class Result {
+    Success,
+    Failure,
+    AlreadyExists,
+  };
+
+  /// Begin writing a record for the file \p Filename with contents uniquely
+  /// identified by \p RecordHash.
+  ///
+  /// \param Filename the name of the file this is a record for.
+  /// \param RecordHash the unique hash of the record contents.
+  /// \param Error on failure, set to the error message.
+  /// \param RecordFile if non-null, this is set to the name of the record file.
+  ///
+  /// \returns Success if we should continue writing this record, AlreadyExists
+  /// if the record file has already been written, or Failure if there was an
+  /// error, in which case \p Error will be set.
+  Result beginRecord(StringRef Filename, llvm::hash_code RecordHash,
+                     std::string &Error, std::string *RecordFile = nullptr);
+
+  /// Finish writing the record file.
+  ///
+  /// \param Error on failure, set to the error message.
+  /// \param GetSymbolForDecl a callback mapping an writer::OpaqueDecl to its
+  /// writer::Symbol. This is how the language-specific symbol information is
+  /// provided to the IndexRecordWriter. The scratch parameter can be used for
+  /// any necessary storage.
+  ///
+  /// \return Success, or Failure and sets \p Error.
+  Result endRecord(std::string &Error,
+                   writer::SymbolWriterCallback GetSymbolForDecl);
+
+  /// Add an occurrence of the symbol \p D with the given \p Roles and location.
+  void addOccurrence(writer::OpaqueDecl D, SymbolRoleSet Roles, unsigned Line,
+                     unsigned Column, ArrayRef<writer::SymbolRelation> Related);
+};
+
+} // end namespace index
+} // end namespace clang
+
+#endif // LLVM_CLANG_INDEX_INDEXRECORDWRITER_H
diff --git a/include/clang/Index/IndexSymbol.h b/include/clang/Index/IndexSymbol.h
index abb132f..2aa9b6b 100644
--- a/include/clang/Index/IndexSymbol.h
+++ b/include/clang/Index/IndexSymbol.h
@@ -53,6 +53,9 @@
   ConversionFunction,
 
   Parameter,
+  Using,
+
+  CommentTag,
 };
 
 enum class SymbolLanguage {
@@ -69,6 +72,28 @@
   CXXMoveConstructor,
   AccessorGetter,
   AccessorSetter,
+  UsingTypename,
+  UsingValue,
+
+  // Swift sub-kinds
+
+  SwiftAccessorWillSet,
+  SwiftAccessorDidSet,
+  SwiftAccessorAddressor,
+  SwiftAccessorMutableAddressor,
+
+  SwiftExtensionOfStruct,
+  SwiftExtensionOfClass,
+  SwiftExtensionOfEnum,
+  SwiftExtensionOfProtocol,
+
+  SwiftPrefixOperator,
+  SwiftPostfixOperator,
+  SwiftInfixOperator,
+
+  SwiftSubscript,
+  SwiftAssociatedType,
+  SwiftGenericTypeParam,
 };
 
 /// Set of properties that provide additional info about a symbol.
diff --git a/include/clang/Index/IndexUnitReader.h b/include/clang/Index/IndexUnitReader.h
new file mode 100644
index 0000000..ccd2dce
--- /dev/null
+++ b/include/clang/Index/IndexUnitReader.h
@@ -0,0 +1,85 @@
+//===--- IndexUnitReader.h - Index unit deserialization -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXUNITREADER_H
+#define LLVM_CLANG_INDEX_INDEXUNITREADER_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Chrono.h"
+
+namespace clang {
+namespace index {
+
+class IndexUnitReader {
+public:
+  enum class DependencyKind {
+    Unit,
+    Record,
+    File,
+  };
+
+  ~IndexUnitReader();
+
+  static std::unique_ptr<IndexUnitReader>
+    createWithUnitFilename(StringRef UnitFilename, StringRef StorePath,
+                           std::string &Error);
+  static std::unique_ptr<IndexUnitReader>
+    createWithFilePath(StringRef FilePath, std::string &Error);
+
+  static Optional<llvm::sys::TimePoint<>>
+    getModificationTimeForUnit(StringRef UnitFilename, StringRef StorePath,
+                               std::string &Error);
+
+  StringRef getProviderIdentifier() const;
+  StringRef getProviderVersion() const;
+
+  llvm::sys::TimePoint<> getModificationTime() const;
+  StringRef getWorkingDirectory() const;
+  StringRef getOutputFile() const;
+  StringRef getSysrootPath() const;
+  StringRef getMainFilePath() const;
+  StringRef getModuleName() const;
+  StringRef getTarget() const;
+  bool hasMainFile() const;
+  bool isSystemUnit() const;
+  bool isModuleUnit() const;
+  bool isDebugCompilation() const;
+
+  struct DependencyInfo {
+    DependencyKind Kind;
+    bool IsSystem;
+    StringRef UnitOrRecordName;
+    StringRef FilePath;
+    StringRef ModuleName;
+    size_t FileSize;
+    time_t ModTime;
+  };
+  struct IncludeInfo {
+    StringRef SourcePath;
+    unsigned SourceLine;
+    StringRef TargetPath;
+  };
+  /// Unit dependencies are provided ahead of record ones, record ones
+  /// ahead of the file ones.
+  bool foreachDependency(llvm::function_ref<bool(const DependencyInfo &Info)> Receiver);
+
+  bool foreachInclude(llvm::function_ref<bool(const IncludeInfo &Info)> Receiver);
+
+private:
+  IndexUnitReader(void *Impl) : Impl(Impl) {}
+
+  void *Impl; // An IndexUnitReaderImpl.
+};
+
+} // namespace index
+} // namespace clang
+
+#endif
diff --git a/include/clang/Index/IndexUnitWriter.h b/include/clang/Index/IndexUnitWriter.h
new file mode 100644
index 0000000..40d2c11
--- /dev/null
+++ b/include/clang/Index/IndexUnitWriter.h
@@ -0,0 +1,140 @@
+//===--- IndexUnitWriter.h - Index unit serialization ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_INDEXUNITWRITER_H
+#define LLVM_CLANG_INDEX_INDEXUNITWRITER_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/SmallString.h"
+#include <string>
+#include <vector>
+
+namespace llvm {
+  class BitstreamWriter;
+}
+
+namespace clang {
+  class FileEntry;
+  class FileManager;
+
+namespace index {
+
+namespace writer {
+/// An opaque pointer to a module used by the IndexUnitWriter to associate
+/// record and file dependencies with a module, and as a token for getting
+/// information about the module from the caller.
+typedef const void *OpaqueModule;
+
+/// Module info suitable for serialization.
+///
+/// This is used for top-level modules and sub-modules.
+struct ModuleInfo {
+  /// Full, dot-separate, module name.
+  StringRef Name;
+};
+
+typedef llvm::function_ref<ModuleInfo(OpaqueModule, SmallVectorImpl<char> &Scratch)>
+    ModuleInfoWriterCallback;
+} // end namespace writer
+
+class IndexUnitWriter {
+  FileManager &FileMgr;
+  SmallString<64> UnitsPath;
+  std::string ProviderIdentifier;
+  std::string ProviderVersion;
+  std::string OutputFile;
+  std::string ModuleName;
+  const FileEntry *MainFile;
+  bool IsSystemUnit;
+  bool IsModuleUnit;
+  bool IsDebugCompilation;
+  std::string TargetTriple;
+  std::string WorkDir;
+  std::string SysrootPath;
+  std::function<writer::ModuleInfo(writer::OpaqueModule,
+                            SmallVectorImpl<char> &Scratch)> GetInfoForModuleFn;
+  struct FileInclude {
+    int Index;
+    unsigned Line;
+  };
+  struct FileEntryData {
+    const FileEntry *File;
+    bool IsSystem;
+    int ModuleIndex;
+    std::vector<FileInclude> Includes;
+  };
+  std::vector<FileEntryData> Files;
+  std::vector<writer::OpaqueModule> Modules;
+  llvm::DenseMap<const FileEntry *, int> IndexByFile;
+  llvm::DenseMap<writer::OpaqueModule, int> IndexByModule;
+  llvm::DenseSet<const FileEntry *> SeenASTFiles;
+  struct RecordOrUnitData {
+    std::string Name;
+    int FileIndex;
+    int ModuleIndex;
+    bool IsSystem;
+  };
+  std::vector<RecordOrUnitData> Records;
+  std::vector<RecordOrUnitData> ASTFileUnits;
+
+public:
+  /// \param MainFile the main file for a compiled source file. This should be
+  /// null for PCH and module units.
+  /// \param IsSystem true for system module units, false otherwise.
+  IndexUnitWriter(FileManager &FileMgr,
+                  StringRef StorePath,
+                  StringRef ProviderIdentifier, StringRef ProviderVersion,
+                  StringRef OutputFile,
+                  StringRef ModuleName,
+                  const FileEntry *MainFile,
+                  bool IsSystem,
+                  bool IsModuleUnit,
+                  bool IsDebugCompilation,
+                  StringRef TargetTriple,
+                  StringRef SysrootPath,
+                  writer::ModuleInfoWriterCallback GetInfoForModule);
+  ~IndexUnitWriter();
+
+  int addFileDependency(const FileEntry *File, bool IsSystem,
+                        writer::OpaqueModule Mod);
+  void addRecordFile(StringRef RecordFile, const FileEntry *File, bool IsSystem,
+                     writer::OpaqueModule Mod);
+  void addASTFileDependency(const FileEntry *File, bool IsSystem,
+                            writer::OpaqueModule Mod, bool withoutUnitName = false);
+  void addUnitDependency(StringRef UnitFile, const FileEntry *File, bool IsSystem,
+                         writer::OpaqueModule Mod);
+  bool addInclude(const FileEntry *Source, unsigned Line, const FileEntry *Target);
+
+  bool write(std::string &Error);
+
+  void getUnitNameForOutputFile(StringRef FilePath, SmallVectorImpl<char> &Str);
+  void getUnitPathForOutputFile(StringRef FilePath, SmallVectorImpl<char> &Str);
+  /// If the unit file exists and \p timeCompareFilePath is provided, it will
+  /// return true if \p timeCompareFilePath is older than the unit file.
+  Optional<bool> isUnitUpToDateForOutputFile(StringRef FilePath,
+                                             Optional<StringRef> TimeCompareFilePath,
+                                             std::string &Error);
+  static void getUnitNameForAbsoluteOutputFile(StringRef FilePath, SmallVectorImpl<char> &Str);
+  static bool initIndexDirectory(StringRef StorePath, std::string &Error);
+
+private:
+  class PathStorage;
+  int addModule(writer::OpaqueModule Mod);
+  void writeUnitInfo(llvm::BitstreamWriter &Stream, PathStorage &PathStore);
+  void writeDependencies(llvm::BitstreamWriter &Stream, PathStorage &PathStore);
+  void writeIncludes(llvm::BitstreamWriter &Stream, PathStorage &PathStore);
+  void writePaths(llvm::BitstreamWriter &Stream, PathStorage &PathStore);
+  void writeModules(llvm::BitstreamWriter &Stream);
+};
+
+} // end namespace index
+} // end namespace clang
+
+#endif
diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h
index fb703be..6095e67 100644
--- a/include/clang/Index/IndexingAction.h
+++ b/include/clang/Index/IndexingAction.h
@@ -13,13 +13,17 @@
 #include "clang/Basic/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
 #include <memory>
+#include <string>
 
 namespace clang {
   class ASTContext;
   class ASTReader;
   class ASTUnit;
+  class CompilerInstance;
   class Decl;
   class FrontendAction;
+  class FrontendOptions;
+  class Module;
 
 namespace serialization {
   class ModuleFile;
@@ -27,6 +31,7 @@
 
 namespace index {
   class IndexDataConsumer;
+  class IndexUnitWriter;
 
 struct IndexingOptions {
   enum class SystemSymbolFilterKind {
@@ -40,6 +45,19 @@
   bool IndexFunctionLocals = false;
 };
 
+struct RecordingOptions {
+  enum class IncludesRecordingKind {
+    None,
+    UserOnly, // only record includes inside non-system files.
+    All,
+  };
+
+  std::string DataDirPath;
+  bool RecordSymbolCodeGenName = false;
+  bool RecordSystemDependencies = true;
+  IncludesRecordingKind RecordIncludes = IncludesRecordingKind::UserOnly;
+};
+
 /// \param WrappedAction another frontend action to wrap over or null.
 std::unique_ptr<FrontendAction>
 createIndexingAction(std::shared_ptr<IndexDataConsumer> DataConsumer,
@@ -58,6 +76,18 @@
                      std::shared_ptr<IndexDataConsumer> DataConsumer,
                      IndexingOptions Opts);
 
+/// \param WrappedAction another frontend action to wrap over or null.
+std::unique_ptr<FrontendAction>
+createIndexDataRecordingAction(const FrontendOptions &FEOpts,
+                               std::unique_ptr<FrontendAction> WrappedAction);
+
+/// Checks if the unit file exists for the module file, if it doesn't it
+/// generates index data for it.
+///
+/// \returns true if the index data were generated, false otherwise.
+bool emitIndexDataForModuleFile(const Module *Mod, const CompilerInstance &CI,
+                                IndexUnitWriter &ParentUnitWriter);
+
 } // namespace index
 } // namespace clang
 
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 3be7331..2a229f6 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.
@@ -460,6 +462,14 @@
                                          const LangOptions &LangOpts,
                                          bool SkipTrailingWhitespaceAndNewLine);
 
+  /// \brief Returns the source location of the token that comes after the
+  /// token located at the given location \p Loc (excluding any comments and
+  /// whitespace). The returned source location will be invalid if the location
+  /// is inside a macro.
+  static SourceLocation
+  findNextTokenLocationAfterTokenAt(SourceLocation Loc, const SourceManager &SM,
+                                    const LangOptions &LangOpts);
+
   /// \brief Returns true if the given character could appear in an identifier.
   static bool isIdentifierBodyChar(char c, const LangOptions &LangOpts);
 
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index d25431b..47f10d6 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -510,6 +510,9 @@
     ID.AddPointer(II);
   }
 
+  /// Get the name of the macro.
+  IdentifierInfo *getName() const { return II; }
+
   /// Get the ID of the module that exports this macro.
   Module *getOwningModule() const { return OwningModule; }
 
diff --git a/include/clang/Lex/ModuleMap.h b/include/clang/Lex/ModuleMap.h
index 1150693..eb224a6 100644
--- a/include/clang/Lex/ModuleMap.h
+++ b/include/clang/Lex/ModuleMap.h
@@ -93,7 +93,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.
@@ -186,6 +186,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()
@@ -200,6 +209,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;
@@ -340,6 +352,8 @@
             const LangOptions &LangOpts, const TargetInfo *Target,
             HeaderSearch &HeaderInfo);
 
+  const LangOptions &getLangOpts() const { return LangOpts; }
+
   /// \brief Destroy the module map.
   ///
   ~ModuleMap();
@@ -486,6 +500,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/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 81c3bd7..512a32e 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -266,7 +266,10 @@
   /// \brief Hook called when a source range is skipped.
   /// \param Range The SourceRange that was skipped. The range begins at the
   /// \#if/\#else directive and ends after the \#endif/\#else directive.
-  virtual void SourceRangeSkipped(SourceRange Range) {
+  /// \param EndifLoc The end location of the 'endif' token, which may precede
+  /// the range skipped by the directive (e.g excluding comments after an
+  /// 'endif').
+  virtual void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) {
   }
 
   enum ConditionValueKind {
@@ -462,9 +465,9 @@
     Second->Defined(MacroNameTok, MD, Range);
   }
 
-  void SourceRangeSkipped(SourceRange Range) override {
-    First->SourceRangeSkipped(Range);
-    Second->SourceRangeSkipped(Range);
+  void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
+    First->SourceRangeSkipped(Range, EndifLoc);
+    Second->SourceRangeSkipped(Range, EndifLoc);
   }
 
   /// \brief Hook called whenever an \#if is seen.
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index fc2c507..882b8ae 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -504,7 +504,8 @@
     void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
                  SourceRange Range) override;
 
-    void SourceRangeSkipped(SourceRange Range) override;
+    void SourceRangeSkipped(SourceRange Range,
+                            SourceLocation EndifLoc) override;
 
     void addMacroExpansion(const Token &Id, const MacroInfo *MI,
                            SourceRange Range);
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index dba4b80..7107cc9 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -1836,7 +1836,8 @@
   /// \p FoundElse is false, then \#else directives are ok, if not, then we have
   /// already seen one so a \#else directive is a duplicate.  When this returns,
   /// the caller can lex the first valid token.
-  void SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
+  void SkipExcludedConditionalBlock(const Token &HashToken,
+                                    SourceLocation IfTokenLoc,
                                     bool FoundNonSkipPortion, bool FoundElse,
                                     SourceLocation ElseLoc = SourceLocation());
 
@@ -2030,12 +2031,13 @@
   void HandleUndefDirective();
 
   // Conditional Inclusion.
-  void HandleIfdefDirective(Token &Tok, bool isIfndef,
-                            bool ReadAnyTokensBeforeDirective);
-  void HandleIfDirective(Token &Tok, bool ReadAnyTokensBeforeDirective);
+  void HandleIfdefDirective(Token &Tok, const Token &HashToken,
+                            bool isIfndef, bool ReadAnyTokensBeforeDirective);
+  void HandleIfDirective(Token &Tok, const Token &HashToken,
+                         bool ReadAnyTokensBeforeDirective);
   void HandleEndifDirective(Token &Tok);
-  void HandleElseDirective(Token &Tok);
-  void HandleElifDirective(Token &Tok);
+  void HandleElseDirective(Token &Tok, const Token &HashToken);
+  void HandleElifDirective(Token &Tok, const Token &HashToken);
 
   // Pragmas.
   void HandlePragmaDirective(SourceLocation IntroducerLoc,
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 21d699e..91f7028 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -2362,6 +2362,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,
@@ -2784,7 +2792,19 @@
   //===--------------------------------------------------------------------===//
   // C++11/G++: Type Traits [Type-Traits.html in the GCC manual]
   ExprResult ParseTypeTrait();
-  
+
+  /// Parse the given string as a type.
+  ///
+  /// This is a dangerous utility function currently employed only by API notes.
+  /// It is not a general entry-point for safely parsing types from strings.
+  ///
+  /// \param typeStr The string to be parsed as a type.
+  /// \param context The name of the context in which this string is being
+  /// parsed, which will be used in diagnostics.
+  /// \param includeLoc The location at which this parse was triggered.
+  TypeResult parseTypeFromString(StringRef typeStr, StringRef context,
+                                 SourceLocation includeLoc);
+
   //===--------------------------------------------------------------------===//
   // Embarcadero: Arary and Expression Traits
   ExprResult ParseArrayTypeTrait();
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 5a70854..239017d 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -28,6 +28,7 @@
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/StmtCXX.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"
@@ -55,6 +56,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include <deque>
+#include <functional>
 #include <memory>
 #include <string>
 #include <vector>
@@ -306,6 +308,7 @@
   ASTConsumer &Consumer;
   DiagnosticsEngine &Diags;
   SourceManager &SourceMgr;
+  api_notes::APINotesManager APINotes;
 
   /// \brief Flag indicating whether or not to collect detailed statistics.
   bool CollectStats;
@@ -618,6 +621,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 {
@@ -1499,6 +1506,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);
@@ -1920,6 +1945,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,
@@ -2411,6 +2438,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);
@@ -3256,6 +3286,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
@@ -3311,11 +3347,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,
@@ -8156,6 +8197,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);
@@ -8507,6 +8554,11 @@
   /// is performed.
   bool isOpenMPPrivateDecl(ValueDecl *D, unsigned Level);
 
+  /// Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.)
+  /// for \p FD based on DSA for the provided corresponding captured declaration
+  /// \p D.
+  void setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level);
+
   /// \brief Check if the specified variable is captured  by 'target' directive.
   /// \param Level Relative level of nested OpenMP construct for that the check
   /// is performed.
@@ -10396,6 +10448,7 @@
 
   /// The struct behind the CFErrorRef pointer.
   RecordDecl *CFError = nullptr;
+  bool isCFError(RecordDecl *D);
 
   /// Retrieve the identifier "NSError".
   IdentifierInfo *getNSErrorIdent();
@@ -10446,6 +10499,36 @@
   SmallVector<CXXRecordDecl*, 4> DelayedDllExportClasses;
 
 private:
+  class SavePendingParsedClassStateRAII {
+  public:
+    SavePendingParsedClassStateRAII(Sema &S) : S(S) { swapSavedState(); }
+
+    ~SavePendingParsedClassStateRAII() {
+      assert(S.DelayedExceptionSpecChecks.empty() &&
+             "there shouldn't be any pending delayed exception spec checks");
+      assert(S.DelayedDefaultedMemberExceptionSpecs.empty() &&
+             "there shouldn't be any pending delayed defaulted member "
+             "exception specs");
+      assert(S.DelayedDllExportClasses.empty() &&
+             "there shouldn't be any pending delayed DLL export classes");
+      swapSavedState();
+    }
+
+  private:
+    Sema &S;
+    decltype(DelayedExceptionSpecChecks) SavedExceptionSpecChecks;
+    decltype(DelayedDefaultedMemberExceptionSpecs)
+        SavedDefaultedMemberExceptionSpecs;
+    decltype(DelayedDllExportClasses) SavedDllExportClasses;
+
+    void swapSavedState() {
+      SavedExceptionSpecChecks.swap(S.DelayedExceptionSpecChecks);
+      SavedDefaultedMemberExceptionSpecs.swap(
+          S.DelayedDefaultedMemberExceptionSpecs);
+      SavedDllExportClasses.swap(S.DelayedDllExportClasses);
+    }
+  };
+
   /// \brief Helper class that collects misaligned member designations and
   /// their location info for delayed diagnostics.
   struct MisalignedMember {
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 9227b33..f0f17c9 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -716,6 +716,9 @@
       /// \brief Specifies some declarations with initializers that must be
       /// emitted to initialize the module.
       SUBMODULE_INITIALIZERS = 16,
+      /// \brief Specifies the name of the module that will eventually
+      /// re-export the entities in this module.
+      SUBMODULE_EXPORT_AS = 17,
     };
 
     /// \brief Record types used within a comments block.
diff --git a/include/clang/Tooling/Core/RefactoringDiagnostic.h b/include/clang/Tooling/Core/RefactoringDiagnostic.h
new file mode 100644
index 0000000..a179260
--- /dev/null
+++ b/include/clang/Tooling/Core/RefactoringDiagnostic.h
@@ -0,0 +1,29 @@
+//===--- RefactoringDiagnostic.h - ------------------------------*- 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_TOOLING_CORE_REFACTORINGSTARTDIAGNOSTIC_H
+#define LLVM_CLANG_TOOLING_CORE_REFACTORINGSTARTDIAGNOSTIC_H
+
+#include "clang/Basic/Diagnostic.h"
+
+namespace clang {
+namespace diag {
+enum {
+#define DIAG(ENUM, FLAGS, DEFAULT_MAPPING, DESC, GROUP, SFINAE, NOWERROR,      \
+             SHOWINSYSHEADER, CATEGORY)                                        \
+  ENUM,
+#define REFACTORINGSTART
+#include "clang/Basic/DiagnosticRefactoringKinds.inc"
+#undef DIAG
+  NUM_BUILTIN_REFACTORING_DIAGNOSTICS
+};
+} // end namespace diag
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_CORE_REFACTORINGSTARTDIAGNOSTIC_H
diff --git a/include/clang/Tooling/Refactor/IndexerQuery.h b/include/clang/Tooling/Refactor/IndexerQuery.h
new file mode 100644
index 0000000..4872893
--- /dev/null
+++ b/include/clang/Tooling/Refactor/IndexerQuery.h
@@ -0,0 +1,310 @@
+//===--- IndexerQuery.h - A set of indexer query interfaces ---------------===//
+//
+//                     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 base indexer queries that can be used with
+// refactoring continuations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_INDEXER_QUERY_H
+#define LLVM_CLANG_TOOLING_REFACTOR_INDEXER_QUERY_H
+
+#include "clang/Tooling/Refactor/RefactoringOperationState.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Error.h"
+#include <vector>
+
+namespace clang {
+namespace tooling {
+namespace indexer {
+
+/// Represents an abstract indexer query.
+class IndexerQuery {
+public:
+  const char *BaseUID;
+  const char *NameUID;
+
+  IndexerQuery(const char *BaseUID, const char *NameUID)
+      : BaseUID(BaseUID), NameUID(NameUID) {}
+  virtual ~IndexerQuery() {}
+
+  virtual void invalidateTUSpecificState() = 0;
+
+  /// Checks if this query was satisfied. Returns true if it wasn't and reports
+  /// appropriate errors.
+  virtual bool verify(ASTContext &) { return false; }
+
+  // Mainly used for testing.
+  static llvm::Error loadResultsFromYAML(StringRef Source,
+                                         ArrayRef<IndexerQuery *> Queries);
+
+  static bool classof(const IndexerQuery *) { return true; }
+};
+
+/// An abstract AST query that can produce an AST unit in which the refactoring
+/// continuation will run.
+class ASTProducerQuery : public IndexerQuery {
+  static const char *BaseUIDString;
+
+public:
+  /// Deriving AST producer queries can redefine this type to generate custom
+  /// results that are then passed into the refactoring continuations.
+  using ResultTy = void;
+
+  ASTProducerQuery(const char *NameUID)
+      : IndexerQuery(BaseUIDString, NameUID) {}
+
+  static bool classof(const IndexerQuery *Q) {
+    return Q->BaseUID == BaseUIDString;
+  }
+};
+
+/// A query that finds a file that contains/should contain the implementation of
+/// some declaration.
+class ASTUnitForImplementationOfDeclarationQuery final
+    : public ASTProducerQuery {
+  static const char *NameUIDString;
+
+  const Decl *D;
+  PersistentFileID Result;
+
+public:
+  ASTUnitForImplementationOfDeclarationQuery(const Decl *D)
+      : ASTProducerQuery(NameUIDString), D(D), Result("") {}
+
+  using ResultTy = FileID;
+
+  const Decl *getDecl() const { return D; }
+
+  void invalidateTUSpecificState() override { D = nullptr; }
+
+  void setResult(PersistentFileID File) { Result = std::move(File); }
+
+  bool verify(ASTContext &Context) override;
+
+  const PersistentFileID &getResult() const { return Result; }
+
+  static bool classof(const IndexerQuery *D) {
+    return D->NameUID == NameUIDString;
+  }
+};
+
+/// Returns an indexer query that will allow a refactoring continuation to run
+/// in an AST unit that contains a file that should contain the implementation
+/// of the given declaration \p D.
+///
+/// The continuation function will receive \c FileID that corresponds to the
+/// implementation file. The indexer can decide which file should be used as an
+/// implementation of a declaration based on a number of different heuristics.
+/// It does not guarantee that the file will actually have any declarations that
+/// correspond to the implementation of \p D yet, as the indexer may decide to
+/// point to a file that it thinks will have the implementation declarations in
+/// the future.
+std::unique_ptr<ASTUnitForImplementationOfDeclarationQuery>
+fileThatShouldContainImplementationOf(const Decl *D);
+
+/// A declaration predicate operates.
+struct DeclPredicate {
+  const char *Name;
+
+  DeclPredicate(const char *Name) : Name(Name) {}
+
+  bool operator==(const DeclPredicate &P) const {
+    return StringRef(Name) == P.Name;
+  }
+  bool operator!=(const DeclPredicate &P) const {
+    return StringRef(Name) != P.Name;
+  }
+};
+
+/// Represents a declaration predicate that will evaluate to either 'true' or
+/// 'false' in an indexer query.
+struct BoolDeclPredicate {
+  DeclPredicate Predicate;
+  bool IsInverted;
+
+  BoolDeclPredicate(DeclPredicate Predicate, bool IsInverted = false)
+      : Predicate(Predicate), IsInverted(IsInverted) {}
+
+  BoolDeclPredicate operator!() const {
+    return BoolDeclPredicate(Predicate, /*IsInverted=*/!IsInverted);
+  }
+};
+
+namespace detail {
+
+/// AST-like representation for decl predicates.
+class DeclPredicateNode {
+public:
+  const char *NameUID;
+  DeclPredicateNode(const char *NameUID) : NameUID(NameUID) {}
+
+  static std::unique_ptr<DeclPredicateNode>
+  create(const DeclPredicate &Predicate);
+  static std::unique_ptr<DeclPredicateNode>
+  create(const BoolDeclPredicate &Predicate);
+
+  static bool classof(const DeclPredicateNode *) { return true; }
+};
+
+class DeclPredicateNodePredicate : public DeclPredicateNode {
+  static const char *NameUIDString;
+
+  DeclPredicate Predicate;
+
+public:
+  DeclPredicateNodePredicate(const DeclPredicate &Predicate)
+      : DeclPredicateNode(NameUIDString), Predicate(Predicate) {}
+
+  const DeclPredicate &getPredicate() const { return Predicate; }
+
+  static bool classof(const DeclPredicateNode *P) {
+    return P->NameUID == NameUIDString;
+  }
+};
+
+class DeclPredicateNotPredicate : public DeclPredicateNode {
+  static const char *NameUIDString;
+
+  std::unique_ptr<DeclPredicateNode> Child;
+
+public:
+  DeclPredicateNotPredicate(std::unique_ptr<DeclPredicateNode> Child)
+      : DeclPredicateNode(NameUIDString), Child(std::move(Child)) {}
+
+  const DeclPredicateNode &getChild() const { return *Child; }
+
+  static bool classof(const DeclPredicateNode *P) {
+    return P->NameUID == NameUIDString;
+  }
+};
+
+} // end namespace detail
+
+enum class QueryBoolResult {
+  Unknown,
+  Yes,
+  No,
+};
+
+// FIXME: Check that 'T' is either a PersistentDeclRef<> or a Decl *.
+template <typename T> struct Indexed {
+  T Decl;
+  // FIXME: Generalize better in the new refactoring engine.
+  QueryBoolResult IsNotDefined;
+
+  Indexed(T Decl, QueryBoolResult IsNotDefined = QueryBoolResult::Unknown)
+      : Decl(Decl), IsNotDefined(IsNotDefined) {}
+
+  Indexed(Indexed<T> &&Other) = default;
+  Indexed &operator=(Indexed<T> &&Other) = default;
+  Indexed(const Indexed<T> &Other) = default;
+  Indexed &operator=(const Indexed<T> &Other) = default;
+
+  /// True iff the declaration is not defined in the entire project.
+  bool isNotDefined() const {
+    // FIXME: This is hack. Need a better system in the new engine.
+    return IsNotDefined == QueryBoolResult::Yes;
+  }
+};
+
+/// Transforms one set of declarations into another using some predicate.
+class DeclarationsQuery : public IndexerQuery {
+  static const char *BaseUIDString;
+
+  std::vector<const Decl *> Input;
+  std::unique_ptr<detail::DeclPredicateNode> Predicate;
+
+protected:
+  std::vector<Indexed<PersistentDeclRef<Decl>>> Output;
+
+public:
+  DeclarationsQuery(std::vector<const Decl *> Input,
+                    std::unique_ptr<detail::DeclPredicateNode> Predicate)
+      : IndexerQuery(BaseUIDString, nullptr), Input(std::move(Input)),
+        Predicate(std::move(Predicate)) {
+    assert(!this->Input.empty() && "empty declarations list!");
+  }
+
+  ArrayRef<const Decl *> getInputs() const { return Input; }
+
+  void invalidateTUSpecificState() override { Input.clear(); }
+
+  bool verify(ASTContext &Context) override;
+
+  void setOutput(std::vector<Indexed<PersistentDeclRef<Decl>>> Output) {
+    this->Output = Output;
+  }
+
+  const detail::DeclPredicateNode &getPredicateNode() const {
+    return *Predicate;
+  }
+
+  static bool classof(const IndexerQuery *Q) {
+    return Q->BaseUID == BaseUIDString;
+  }
+};
+
+/// The \c DeclEntity class acts as a proxy for the entity that represents a
+/// declaration in the indexer. It defines a set of declaration predicates that
+/// can be used in indexer queries.
+struct DeclEntity {
+  /// The indexer will evaluate this predicate to 'true' when a certain
+  /// declaration has a corresponding definition.
+  BoolDeclPredicate isDefined() const {
+    return BoolDeclPredicate("decl.isDefined");
+  }
+};
+
+template <typename T>
+class ManyToManyDeclarationsQuery final
+    : public std::enable_if<std::is_base_of<Decl, T>::value,
+                            DeclarationsQuery>::type {
+public:
+  ManyToManyDeclarationsQuery(
+      ArrayRef<const T *> Input,
+      std::unique_ptr<detail::DeclPredicateNode> Predicate)
+      : DeclarationsQuery(std::vector<const Decl *>(Input.begin(), Input.end()),
+                          std::move(Predicate)) {}
+
+  std::vector<Indexed<PersistentDeclRef<T>>> getOutput() const {
+    std::vector<Indexed<PersistentDeclRef<T>>> Results;
+    for (const auto &Ref : DeclarationsQuery::Output)
+      Results.push_back(Indexed<PersistentDeclRef<T>>(
+          PersistentDeclRef<T>(Ref.Decl.USR), Ref.IsNotDefined));
+    return Results;
+  }
+};
+
+/// Returns an indexer query that will pass a filtered list of declarations to
+/// a refactoring continuation.
+///
+/// The filtering is done based on predicates that are available on the \c
+/// DeclEntity types. For example, you can use the following invocation to
+/// find a set of declarations that are defined in the entire project:
+///
+/// \code
+/// filter({ MyDeclA, MyDeclB }, [] (const DeclEntity &D) { return D.isDefined()
+/// })
+/// \endcode
+template <typename T>
+std::unique_ptr<ManyToManyDeclarationsQuery<T>>
+filter(ArrayRef<const T *> Declarations,
+       BoolDeclPredicate (*Fn)(const DeclEntity &),
+       typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+           nullptr) {
+  return llvm::make_unique<ManyToManyDeclarationsQuery<T>>(
+      Declarations, detail::DeclPredicateNode::create(Fn(DeclEntity())));
+}
+
+} // end namespace indexer
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_INDEXER_QUERY_H
diff --git a/include/clang/Tooling/Refactor/RefactoringActionFinder.h b/include/clang/Tooling/Refactor/RefactoringActionFinder.h
new file mode 100644
index 0000000..395d78c
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RefactoringActionFinder.h
@@ -0,0 +1,60 @@
+//===--- RefactoringActionFinder.h - Clang refactoring library ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Provides methods to find the refactoring actions that can be
+/// performed at specific locations / source ranges in a translation unit.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_FINDER_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_FINDER_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Refactor/RefactoringActions.h"
+#include "llvm/ADT/StringSet.h"
+#include <vector>
+
+namespace clang {
+
+class NamedDecl;
+class ASTContext;
+
+namespace tooling {
+
+/// Contains a set of a refactoring actions.
+struct RefactoringActionSet {
+  /// A set of refactoring actions that can be performed at some specific
+  /// location in a source file.
+  ///
+  /// The actions in the action set are ordered by their priority: most
+  /// important actions are placed before the less important ones.
+  std::vector<RefactoringActionType> Actions;
+
+  RefactoringActionSet() {}
+
+  RefactoringActionSet(RefactoringActionSet &&) = default;
+  RefactoringActionSet &operator=(RefactoringActionSet &&) = default;
+};
+
+/// \brief Returns a \c RefactoringActionSet that contains the set of actions
+/// that can be performed at the given location.
+RefactoringActionSet findActionSetAt(SourceLocation Loc,
+                                     SourceRange SelectionRange,
+                                     ASTContext &Context);
+
+/// \brief Returns a set of USRs that correspond to the given declaration.
+llvm::StringSet<> findSymbolsUSRSet(const NamedDecl *FoundDecl,
+                                    ASTContext &Context);
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTION_FINDER_H
diff --git a/include/clang/Tooling/Refactor/RefactoringActions.def b/include/clang/Tooling/Refactor/RefactoringActions.def
new file mode 100644
index 0000000..f5c2f66
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RefactoringActions.def
@@ -0,0 +1,62 @@
+//===--- RefactoringActions.def - The list of refactoring actions  --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef REFACTORING_ACTION
+#define REFACTORING_ACTION(Name, Spelling)
+#endif
+
+#ifndef REFACTORING_SUB_ACTION
+#define REFACTORING_SUB_ACTION(Name, Parent, Spelling) \
+  REFACTORING_ACTION(Parent##_##Name, Spelling)
+#endif
+
+#ifndef REFACTORING_OPERATION_ACTION
+#define REFACTORING_OPERATION_ACTION(Name, Spelling, Command)\
+  REFACTORING_ACTION(Name, Spelling)
+#endif
+
+#ifndef REFACTORING_OPERATION_SUB_ACTION
+#define REFACTORING_OPERATION_SUB_ACTION(Name, Parent, Spelling, Command)\
+  REFACTORING_SUB_ACTION(Name, Parent, Spelling)
+#endif
+
+REFACTORING_ACTION(Rename, "Rename")
+REFACTORING_SUB_ACTION(Local, Rename, "Rename")
+
+REFACTORING_OPERATION_ACTION(Extract, "Extract Function", "extract")
+REFACTORING_OPERATION_SUB_ACTION(Method, Extract, "Extract Method",
+                                 "extract-method")
+REFACTORING_OPERATION_SUB_ACTION(Expression, Extract, "Extract Expression",
+                                 "extract-expression")
+
+REFACTORING_OPERATION_ACTION(IfSwitchConversion, "Convert to Switch",
+                             "if-switch-conversion")
+REFACTORING_OPERATION_ACTION(FillInEnumSwitchCases, "Add Missing Switch Cases",
+                             "fill-in-enum-switch-cases")
+REFACTORING_OPERATION_ACTION(FillInMissingProtocolStubs,
+                             "Add Missing Protocol Requirements",
+                             "fill-in-missing-protocol-stubs")
+REFACTORING_OPERATION_ACTION(LocalizeObjCStringLiteral,
+                             "Wrap in NSLocalizedString",
+                             "localize-objc-string-literal")
+REFACTORING_OPERATION_ACTION(ExtractRepeatedExpressionIntoVariable,
+                             "Extract Repeated Expression",
+                             "extract-repeated-expr-into-var")
+REFACTORING_OPERATION_ACTION(FillInMissingMethodStubsFromAbstractClasses,
+                             "Add Missing Abstract Class Overrides",
+                             "fill-in-missing-abstract-methods")
+ // FIXME: For ObjC this should say 'Methods':
+REFACTORING_OPERATION_ACTION(ImplementDeclaredMethods,
+                             "Generate Missing Function Definitions",
+                             "implement-declared-methods")
+
+#undef REFACTORING_OPERATION_SUB_ACTION
+#undef REFACTORING_OPERATION_ACTION
+#undef REFACTORING_SUB_ACTION
+#undef REFACTORING_ACTION
diff --git a/include/clang/Tooling/Refactor/RefactoringActions.h b/include/clang/Tooling/Refactor/RefactoringActions.h
new file mode 100644
index 0000000..f9d9c6c
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RefactoringActions.h
@@ -0,0 +1,34 @@
+//===--- RefactoringActions.h - Clang refactoring library -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Contains a list of all the supported refactoring actions.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTIONS_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTIONS_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace clang {
+namespace tooling {
+
+enum class RefactoringActionType {
+#define REFACTORING_ACTION(Name, Spelling) Name,
+#include "clang/Tooling/Refactor/RefactoringActions.def"
+};
+
+StringRef getRefactoringActionTypeName(RefactoringActionType Action);
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_ACTIONS_H
diff --git a/include/clang/Tooling/Refactor/RefactoringOperation.h b/include/clang/Tooling/Refactor/RefactoringOperation.h
new file mode 100644
index 0000000..3332178
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RefactoringOperation.h
@@ -0,0 +1,160 @@
+//===--- RefactoringOperations.h - Defines a refactoring operation --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPERATION_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPERATION_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Refactor/RefactoringActions.h"
+#include "clang/Tooling/Refactor/RefactoringOptionSet.h"
+#include "clang/Tooling/Refactor/RefactoringReplacement.h"
+#include "clang/Tooling/Refactor/SymbolOperation.h"
+#include "llvm/ADT/None.h"
+#include "llvm/Support/Error.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class Preprocessor;
+class Stmt;
+
+namespace tooling {
+
+class RefactoringContinuation;
+
+/// A refactoring result contains the source replacements produced by the
+/// refactoring operation and the optional refactoring continuation.
+struct RefactoringResult {
+  std::vector<RefactoringReplacement> Replacements;
+  std::vector<std::unique_ptr<RefactoringResultAssociatedSymbol>>
+      AssociatedSymbols;
+  std::unique_ptr<RefactoringContinuation> Continuation;
+
+  RefactoringResult(
+      std::vector<RefactoringReplacement> Replacements,
+      std::unique_ptr<RefactoringContinuation> Continuation = nullptr)
+      : Replacements(std::move(Replacements)),
+        Continuation(std::move(Continuation)) {}
+
+  RefactoringResult(std::unique_ptr<RefactoringContinuation> Continuation)
+      : Replacements(), Continuation(std::move(Continuation)) {}
+
+  RefactoringResult(RefactoringResult &&) = default;
+  RefactoringResult &operator=(RefactoringResult &&) = default;
+};
+
+namespace indexer {
+
+class IndexerQuery;
+class ASTProducerQuery;
+
+} // end namespace indexer
+
+/// Refactoring continuations allow refactoring operations to run in external
+/// AST units with some results that were obtained after querying the indexer.
+///
+/// The state of the refactoring operation is automatically managed by the
+/// refactoring engine:
+///   - Declaration references are converted to declaration references in
+///     an external translation unit.
+class RefactoringContinuation {
+public:
+  virtual ~RefactoringContinuation() {}
+
+  virtual indexer::ASTProducerQuery *getASTUnitIndexerQuery() = 0;
+
+  virtual std::vector<indexer::IndexerQuery *>
+  getAdditionalIndexerQueries() = 0;
+
+  /// Converts the TU-specific state in the continuation to a TU-independent
+  /// state.
+  ///
+  /// This function is called before the initiation AST unit is freed.
+  virtual void persistTUSpecificState() = 0;
+
+  /// Invokes the continuation with the indexer query results and the state
+  /// values in the context of another AST unit.
+  virtual llvm::Expected<RefactoringResult>
+  runInExternalASTUnit(ASTContext &Context) = 0;
+};
+
+// TODO: Remove in favour of diagnostics.
+class RefactoringOperationError
+    : public llvm::ErrorInfo<RefactoringOperationError> {
+public:
+  static char ID;
+  StringRef FailureReason;
+
+  RefactoringOperationError(StringRef FailureReason)
+      : FailureReason(FailureReason) {}
+
+  void log(raw_ostream &OS) const override;
+
+  std::error_code convertToErrorCode() const override;
+};
+
+/// Represents an abstract refactoring operation.
+class RefactoringOperation {
+public:
+  virtual ~RefactoringOperation() {}
+
+  virtual const Stmt *getTransformedStmt() const { return nullptr; }
+
+  virtual const Stmt *getLastTransformedStmt() const { return nullptr; }
+
+  virtual const Decl *getTransformedDecl() const { return nullptr; }
+
+  virtual const Decl *getLastTransformedDecl() const { return nullptr; }
+
+  virtual std::vector<std::string> getRefactoringCandidates() { return {}; }
+
+  virtual std::vector<RefactoringActionType> getAvailableSubActions() {
+    return {};
+  }
+
+  virtual llvm::Expected<RefactoringResult>
+  perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex = 0) = 0;
+};
+
+/// A wrapper around a unique pointer to a \c RefactoringOperation or \c
+/// SymbolOperation that determines if the operation was successfully initiated
+/// or not, even if the operation itself wasn't created.
+struct RefactoringOperationResult {
+  std::unique_ptr<RefactoringOperation> RefactoringOp;
+  std::unique_ptr<SymbolOperation> SymbolOp;
+  bool Initiated;
+  StringRef FailureReason;
+
+  RefactoringOperationResult() : Initiated(false) {}
+  RefactoringOperationResult(llvm::NoneType) : Initiated(false) {}
+  explicit RefactoringOperationResult(StringRef FailureReason)
+      : Initiated(false), FailureReason(FailureReason) {}
+};
+
+/// Initiate a specific refactoring operation.
+RefactoringOperationResult initiateRefactoringOperationAt(
+    SourceLocation Location, SourceRange SelectionRange, ASTContext &Context,
+    RefactoringActionType ActionType, bool CreateOperation = true);
+
+/// Initiate a specific refactoring operation on a declaration that corresponds
+/// to the given \p DeclUSR.
+RefactoringOperationResult
+initiateRefactoringOperationOnDecl(StringRef DeclUSR, ASTContext &Context,
+                                   RefactoringActionType ActionType);
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPERATION_H
diff --git a/include/clang/Tooling/Refactor/RefactoringOperationState.h b/include/clang/Tooling/Refactor/RefactoringOperationState.h
new file mode 100644
index 0000000..76ee7d4
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RefactoringOperationState.h
@@ -0,0 +1,66 @@
+//===--- RefactoringOperationState.h - Serializable operation state -------===//
+//
+//                     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 refactoring operation state types that represent the
+// TU-independent state that is used for refactoring continuations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPERATION_STATE_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPERATION_STATE_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/Refactor/USRFinder.h"
+#include <string>
+#include <type_traits>
+
+namespace clang {
+namespace tooling {
+
+namespace detail {
+
+struct PersistentDeclRefBase {};
+
+} // end namespace detail
+
+/// Declaration references are persisted across translation units by using
+/// USRs.
+template <typename T>
+struct PersistentDeclRef : std::enable_if<std::is_base_of<Decl, T>::value,
+                                          detail::PersistentDeclRefBase>::type {
+  std::string USR;
+  // FIXME: We can improve the efficiency of conversion to Decl * by storing the
+  // decl kind.
+
+  PersistentDeclRef(std::string USR) : USR(std::move(USR)) {}
+  PersistentDeclRef(PersistentDeclRef &&Other) = default;
+  PersistentDeclRef &operator=(PersistentDeclRef &&Other) = default;
+  PersistentDeclRef(const PersistentDeclRef &Other) = default;
+  PersistentDeclRef &operator=(const PersistentDeclRef &Other) = default;
+
+  static PersistentDeclRef<T> create(const Decl *D) {
+    // FIXME: Move the getUSRForDecl method somewhere else.
+    return PersistentDeclRef<T>(rename::getUSRForDecl(D));
+  }
+};
+
+/// FileIDs are persisted across translation units by using filenames.
+struct PersistentFileID {
+  std::string Filename;
+
+  PersistentFileID(std::string Filename) : Filename(std::move(Filename)) {}
+  PersistentFileID(PersistentFileID &&Other) = default;
+  PersistentFileID &operator=(PersistentFileID &&Other) = default;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPERATION_STATE_H
diff --git a/include/clang/Tooling/Refactor/RefactoringOptionSet.h b/include/clang/Tooling/Refactor/RefactoringOptionSet.h
new file mode 100644
index 0000000..c3f05ac
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RefactoringOptionSet.h
@@ -0,0 +1,80 @@
+//===--- RefactoringOptionSet.h - A container for the refactoring options -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_SET_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_SET_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+namespace yaml {
+class IO;
+} // end namespace yaml
+} // end namespace llvm
+
+namespace clang {
+namespace tooling {
+
+struct RefactoringOption {
+  virtual ~RefactoringOption() = default;
+
+  struct SerializationContext {
+    llvm::yaml::IO &IO;
+
+    SerializationContext(llvm::yaml::IO &IO) : IO(IO) {}
+  };
+
+  virtual void serialize(const SerializationContext &Context);
+};
+
+/// \brief A set of refactoring options that can be given to a refactoring
+/// operation.
+class RefactoringOptionSet final {
+  llvm::StringMap<std::unique_ptr<RefactoringOption>> Options;
+
+public:
+  RefactoringOptionSet() {}
+  template <typename T> RefactoringOptionSet(const T &Option) { add(Option); }
+
+  RefactoringOptionSet(RefactoringOptionSet &&) = default;
+  RefactoringOptionSet &operator=(RefactoringOptionSet &&) = default;
+
+  RefactoringOptionSet(const RefactoringOptionSet &) = delete;
+  RefactoringOptionSet &operator=(const RefactoringOptionSet &) = delete;
+
+  template <typename T> void add(const T &Option) {
+    auto It = Options.try_emplace(StringRef(T::Name), nullptr);
+    if (It.second)
+      It.first->getValue().reset(new T(Option));
+  }
+
+  template <typename T> const T *get() const {
+    auto It = Options.find(StringRef(T::Name));
+    if (It == Options.end())
+      return nullptr;
+    return static_cast<const T *>(It->getValue().get());
+  }
+
+  template <typename T> const T &get(const T &Default) const {
+    const auto *Ptr = get<T>();
+    return Ptr ? *Ptr : Default;
+  }
+
+  void print(llvm::raw_ostream &OS) const;
+
+  static llvm::Expected<RefactoringOptionSet> parse(StringRef Source);
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTION_SET_H
diff --git a/include/clang/Tooling/Refactor/RefactoringOptions.h b/include/clang/Tooling/Refactor/RefactoringOptions.h
new file mode 100644
index 0000000..f0ce4ba
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RefactoringOptions.h
@@ -0,0 +1,59 @@
+//===--- RefactoringOptions.h - A set of all the refactoring options ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a set of all possible refactoring options that can be
+// given to the refactoring operations.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTIONS_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTIONS_H
+
+#include "clang/AST/DeclBase.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/Refactor/RefactoringOptionSet.h"
+
+namespace clang {
+namespace tooling {
+namespace option {
+
+namespace detail {
+
+struct BoolOptionBase : RefactoringOption {
+protected:
+  bool Value = false;
+  void serializeImpl(const SerializationContext &Context, const char *Name);
+
+public:
+  operator bool() const { return Value; }
+};
+
+template <typename Option> struct BoolOption : BoolOptionBase {
+  void serialize(const SerializationContext &Context) override {
+    serializeImpl(Context, Option::Name);
+  }
+
+  static Option getTrue() {
+    Option Result;
+    Result.Value = true;
+    return Result;
+  }
+};
+
+} // end namespace detail
+
+struct AvoidTextualMatches final : detail::BoolOption<AvoidTextualMatches> {
+  static constexpr const char *Name = "rename.avoid.textual.matches";
+};
+
+} // end namespace option
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_OPTIONS_H
diff --git a/include/clang/Tooling/Refactor/RefactoringReplacement.h b/include/clang/Tooling/Refactor/RefactoringReplacement.h
new file mode 100644
index 0000000..4aed8ab
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RefactoringReplacement.h
@@ -0,0 +1,85 @@
+//===--- RefactoringReplacement.h - ------------------------*- 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_TOOLING_REFACTOR_REFACTORING_REPLACEMENT_H
+#define LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_REPLACEMENT_H
+
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Refactor/SymbolName.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSet.h"
+#include <string>
+
+namespace clang {
+namespace tooling {
+
+/// \brief Represent a symbol that can be used for an additional refactoring
+/// action that associated.
+class RefactoringResultAssociatedSymbol {
+  SymbolName Name;
+
+public:
+  RefactoringResultAssociatedSymbol(SymbolName Name) : Name(std::move(Name)) {}
+
+  const SymbolName &getName() const { return Name; }
+};
+
+/// \brief A replacement range.
+class RefactoringReplacement {
+public:
+  SourceRange Range;
+  std::string ReplacementString;
+
+  /// \brief Represents a symbol that is contained in the replacement string
+  /// of this replacement.
+  struct AssociatedSymbolLocation {
+    /// These offsets point into the ReplacementString.
+    llvm::SmallVector<unsigned, 4> Offsets;
+    bool IsDeclaration;
+
+    AssociatedSymbolLocation(ArrayRef<unsigned> Offsets,
+                             bool IsDeclaration = false)
+        : Offsets(Offsets.begin(), Offsets.end()),
+          IsDeclaration(IsDeclaration) {}
+  };
+  llvm::SmallDenseMap<const RefactoringResultAssociatedSymbol *,
+                      AssociatedSymbolLocation>
+      SymbolLocations;
+
+  RefactoringReplacement(SourceRange Range) : Range(Range) {}
+
+  RefactoringReplacement(SourceRange Range, StringRef ReplacementString)
+      : Range(Range), ReplacementString(ReplacementString.str()) {}
+  RefactoringReplacement(SourceRange Range, std::string ReplacementString)
+      : Range(Range), ReplacementString(std::move(ReplacementString)) {}
+
+  RefactoringReplacement(SourceRange Range, StringRef ReplacementString,
+                         const RefactoringResultAssociatedSymbol *Symbol,
+                         const AssociatedSymbolLocation &Loc)
+      : Range(Range), ReplacementString(ReplacementString.str()) {
+    SymbolLocations.insert(std::make_pair(Symbol, Loc));
+  }
+
+  RefactoringReplacement(const FixItHint &Hint) {
+    Range = Hint.RemoveRange.getAsRange();
+    ReplacementString = Hint.CodeToInsert;
+  }
+
+  RefactoringReplacement(RefactoringReplacement &&) = default;
+  RefactoringReplacement &operator=(RefactoringReplacement &&) = default;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_REFACTORING_REPLACEMENT_H
diff --git a/include/clang/Tooling/Refactor/RenameIndexedFile.h b/include/clang/Tooling/Refactor/RenameIndexedFile.h
new file mode 100644
index 0000000..d598259
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RenameIndexedFile.h
@@ -0,0 +1,83 @@
+//===--- RenameIndexedFile.h - -----------------------------*- 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_TOOLING_REFACTOR_RENAME_INDEXED_FILE_H
+#define LLVM_CLANG_TOOLING_REFACTOR_RENAME_INDEXED_FILE_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Tooling/Refactor/RenamedSymbol.h"
+#include "clang/Tooling/Refactor/SymbolName.h"
+#include "llvm/ADT/ArrayRef.h"
+
+namespace clang {
+namespace tooling {
+
+class RefactoringOptionSet;
+
+namespace rename {
+
+/// An already known occurrence of the symbol that's being renamed.
+struct IndexedOccurrence {
+  /// The location of this occurrence in the indexed file.
+  unsigned Line, Column;
+  enum OccurrenceKind {
+    IndexedSymbol,
+    IndexedObjCMessageSend,
+    InclusionDirective
+  };
+  OccurrenceKind Kind;
+};
+
+struct IndexedSymbol {
+  SymbolName Name;
+  std::vector<IndexedOccurrence> IndexedOccurrences;
+  /// Whether this symbol is an Objective-C selector.
+  bool IsObjCSelector;
+
+  IndexedSymbol(SymbolName Name,
+                std::vector<IndexedOccurrence> IndexedOccurrences,
+                bool IsObjCSelector)
+      : Name(std::move(Name)),
+        IndexedOccurrences(std::move(IndexedOccurrences)),
+        IsObjCSelector(IsObjCSelector) {}
+  IndexedSymbol(IndexedSymbol &&Other) = default;
+  IndexedSymbol &operator=(IndexedSymbol &&Other) = default;
+};
+
+/// Consumes the \c SymbolOccurrences found by \c IndexedFileOccurrenceProducer.
+class IndexedFileOccurrenceConsumer {
+public:
+  virtual ~IndexedFileOccurrenceConsumer() {}
+  virtual void handleOccurrence(const SymbolOccurrence &Occurrence,
+                                SourceManager &SM,
+                                const LangOptions &LangOpts) = 0;
+};
+
+/// Finds the renamed \c SymbolOccurrences in an already indexed files.
+class IndexedFileOccurrenceProducer final : public PreprocessorFrontendAction {
+  bool IsMultiPiece;
+  ArrayRef<IndexedSymbol> Symbols;
+  IndexedFileOccurrenceConsumer &Consumer;
+  const RefactoringOptionSet *Options;
+
+public:
+  IndexedFileOccurrenceProducer(ArrayRef<IndexedSymbol> Symbols,
+                                IndexedFileOccurrenceConsumer &Consumer,
+                                const RefactoringOptionSet *Options = nullptr);
+
+private:
+  void ExecuteAction() override;
+};
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAME_INDEXED_FILE_H
diff --git a/include/clang/Tooling/Refactor/RenamedSymbol.h b/include/clang/Tooling/Refactor/RenamedSymbol.h
new file mode 100644
index 0000000..d54c497
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RenamedSymbol.h
@@ -0,0 +1,143 @@
+//===--- RenamedSymbol.h - ---------------------------------*- 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_TOOLING_REFACTOR_RENAMED_SYMBOL_H
+#define LLVM_CLANG_TOOLING_REFACTOR_RENAMED_SYMBOL_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Tooling/Refactor/SymbolName.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringSet.h"
+
+namespace clang {
+
+class NamedDecl;
+
+namespace tooling {
+namespace rename {
+
+/// \brief A symbol that has to be renamed.
+class Symbol {
+public:
+  SymbolName Name;
+  /// The index of this symbol in a \c SymbolOperation.
+  unsigned SymbolIndex;
+  /// The declaration that was used to initiate a refactoring operation for this
+  /// symbol. May not be the most canonical declaration.
+  const NamedDecl *FoundDecl;
+  /// An optional Objective-C selector.
+  llvm::Optional<Selector> ObjCSelector;
+
+  Symbol(const NamedDecl *FoundDecl, unsigned SymbolIndex,
+         const LangOptions &LangOpts);
+
+  Symbol(Symbol &&) = default;
+  Symbol &operator=(Symbol &&) = default;
+};
+
+/// \brief An occurrence of a renamed symbol.
+///
+/// Provides information about an occurrence of symbol that helps renaming tools
+/// determine if they can rename this symbol automatically and which source
+/// ranges they have to replace.
+///
+/// A single occurrence of a symbol can span more than one source range to
+/// account for things like Objective-C selectors.
+// TODO: Rename
+class SymbolOccurrence {
+  /// The source locations that correspond to the occurence of the symbol.
+  SmallVector<SourceLocation, 4> Locations;
+
+public:
+  enum OccurrenceKind {
+    /// \brief This occurrence is an exact match and can be renamed
+    /// automatically.
+    MatchingSymbol,
+
+    /// \brief This is an occurrence of a matching selector. It can't be renamed
+    /// automatically unless the indexer proves that this selector refers only
+    /// to the declarations that correspond to the renamed symbol.
+    MatchingSelector,
+
+    /// \brief This is an occurrence of an implicit property that uses the
+    /// renamed method.
+    MatchingImplicitProperty,
+
+    /// \brief This is a textual occurrence of a symbol in a comment.
+    MatchingComment,
+
+    /// \brief This is a textual occurrence of a symbol in a doc comment.
+    MatchingDocComment,
+
+    /// \brief This is an occurrence of a symbol in an inclusion directive.
+    MatchingFilename
+  };
+
+  OccurrenceKind Kind;
+  /// Whether or not this occurrence is inside a macro. When this is true, the
+  /// locations of the occurrence contain just one location that points to
+  /// the location of the macro expansion.
+  bool IsMacroExpansion;
+  /// The index of the symbol stored in a \c SymbolOperation which matches this
+  /// occurrence.
+  unsigned SymbolIndex;
+
+  SymbolOccurrence()
+      : Kind(MatchingSymbol), IsMacroExpansion(false), SymbolIndex(0) {}
+
+  SymbolOccurrence(OccurrenceKind Kind, bool IsMacroExpansion,
+                   unsigned SymbolIndex, ArrayRef<SourceLocation> Locations)
+      : Locations(Locations.begin(), Locations.end()), Kind(Kind),
+        IsMacroExpansion(IsMacroExpansion), SymbolIndex(SymbolIndex) {
+    assert(!Locations.empty() && "Renamed occurence without locations!");
+  }
+
+  SymbolOccurrence(SymbolOccurrence &&) = default;
+  SymbolOccurrence &operator=(SymbolOccurrence &&) = default;
+
+  ArrayRef<SourceLocation> locations() const {
+    if (Kind == MatchingImplicitProperty && Locations.size() == 2)
+      return llvm::makeArrayRef(Locations).drop_back();
+    return Locations;
+  }
+
+  /// Return the source range that corresponds to an individual source location
+  /// in this occurrence.
+  SourceRange getLocationRange(SourceLocation Loc, size_t OldNameSize) const {
+    SourceLocation EndLoc;
+    // Implicit property references might store the end as the second location
+    // to take into account the match for 'prop' when the old name is 'setProp'.
+    if (Kind == MatchingImplicitProperty && Locations.size() == 2) {
+      assert(Loc == Locations[0] && "invalid loc");
+      EndLoc = Locations[1];
+    } else
+      EndLoc = IsMacroExpansion ? Loc : Loc.getLocWithOffset(OldNameSize);
+    return SourceRange(Loc, EndLoc);
+  }
+
+  friend bool operator<(const SymbolOccurrence &LHS,
+                        const SymbolOccurrence &RHS);
+  friend bool operator==(const SymbolOccurrence &LHS,
+                         const SymbolOccurrence &RHS);
+};
+
+/// \brief Less-than operator between the two renamed symbol occurrences.
+bool operator<(const SymbolOccurrence &LHS, const SymbolOccurrence &RHS);
+
+/// \brief Equal-to operator between the two renamed symbol occurrences.
+bool operator==(const SymbolOccurrence &LHS, const SymbolOccurrence &RHS);
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAMED_SYMBOL_H
diff --git a/include/clang/Tooling/Refactor/RenamingOperation.h b/include/clang/Tooling/Refactor/RenamingOperation.h
new file mode 100644
index 0000000..bb360a0
--- /dev/null
+++ b/include/clang/Tooling/Refactor/RenamingOperation.h
@@ -0,0 +1,43 @@
+//===--- RenamingOperation.h - -----------------------------*- 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_TOOLING_REFACTOR_RENAMING_OPERATION_H
+#define LLVM_CLANG_TOOLING_REFACTOR_RENAMING_OPERATION_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/Refactor/SymbolName.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class IdentifierTable;
+
+namespace tooling {
+
+class SymbolOperation;
+
+namespace rename {
+
+/// Return true if the new name is a valid language identifier.
+bool isNewNameValid(const SymbolName &NewName, bool IsSymbolObjCSelector,
+                    IdentifierTable &IDs, const LangOptions &LangOpts);
+bool isNewNameValid(const SymbolName &NewName, const SymbolOperation &Operation,
+                    IdentifierTable &IDs, const LangOptions &LangOpts);
+
+/// \brief Finds the set of new names that apply to the symbols in the given
+/// \c SymbolOperation.
+void determineNewNames(SymbolName NewName, const SymbolOperation &Operation,
+                       SmallVectorImpl<SymbolName> &NewNames,
+                       const LangOptions &LangOpts);
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_RENAMING_OPERATION_H
diff --git a/include/clang/Tooling/Refactor/SymbolName.h b/include/clang/Tooling/Refactor/SymbolName.h
new file mode 100644
index 0000000..f348a02
--- /dev/null
+++ b/include/clang/Tooling/Refactor/SymbolName.h
@@ -0,0 +1,74 @@
+//===--- SymbolName.h - Clang refactoring library ----------*- 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_TOOLING_REFACTOR_SYMBOL_NAME_H
+#define LLVM_CLANG_TOOLING_REFACTOR_SYMBOL_NAME_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class LangOptions;
+
+namespace tooling {
+
+/// \brief A name of a declaration that's used in the refactoring process.
+///
+/// Names can be composed of multiple string, to account for things like
+/// Objective-C selectors.
+class SymbolName {
+public:
+  SymbolName() {}
+
+  /// \brief Creates a \c SymbolName by decomposing the given \p Name using
+  /// language specific logic.
+  SymbolName(StringRef Name, const LangOptions &LangOpts);
+  SymbolName(StringRef Name, bool IsObjectiveCSelector);
+  explicit SymbolName(ArrayRef<StringRef> Name);
+
+  SymbolName(SymbolName &&) = default;
+  SymbolName &operator=(SymbolName &&) = default;
+
+  SymbolName(const SymbolName &) = default;
+  SymbolName &operator=(const SymbolName &) = default;
+
+  bool empty() const { return Strings.empty(); }
+
+  /// \brief Returns the number of the strings that make up the given name.
+  size_t size() const { return Strings.size(); }
+
+  /// \brief Returns the string at the given index.
+  StringRef operator[](size_t I) const { return Strings[I]; }
+
+  ArrayRef<std::string> strings() const { return Strings; }
+
+  bool containsEmptyPiece() const {
+    for (const auto &String : Strings) {
+      if (String.empty())
+        return true;
+    }
+    return false;
+  }
+
+  void print(raw_ostream &OS) const;
+
+private:
+  std::vector<std::string> Strings;
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const SymbolName &N);
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_SYMBOL_NAME_H
diff --git a/include/clang/Tooling/Refactor/SymbolOccurrenceFinder.h b/include/clang/Tooling/Refactor/SymbolOccurrenceFinder.h
new file mode 100644
index 0000000..6ecc23b
--- /dev/null
+++ b/include/clang/Tooling/Refactor/SymbolOccurrenceFinder.h
@@ -0,0 +1,37 @@
+//===--- SymbolOccurrenceFinder.h - Clang refactoring library -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Provides functionality for finding all occurrences of a USR in a
+/// given AST.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_SYMBOL_OCCURRENCE_FINDER_H
+#define LLVM_CLANG_TOOLING_REFACTOR_SYMBOL_OCCURRENCE_FINDER_H
+
+#include "clang/AST/AST.h"
+#include "clang/Tooling/Refactor/SymbolOperation.h"
+#include "llvm/ADT/StringRef.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+namespace tooling {
+namespace rename {
+
+// FIXME: make this an AST matcher. Wouldn't that be awesome??? I agree!
+std::vector<SymbolOccurrence>
+findSymbolOccurrences(const SymbolOperation &Operation, Decl *Decl);
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_SYMBOL_OCCURRENCE_FINDER_H
diff --git a/include/clang/Tooling/Refactor/SymbolOperation.h b/include/clang/Tooling/Refactor/SymbolOperation.h
new file mode 100644
index 0000000..7616aa3
--- /dev/null
+++ b/include/clang/Tooling/Refactor/SymbolOperation.h
@@ -0,0 +1,91 @@
+//===--- SymbolOperation.h - -------------------------------*- 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_TOOLING_REFACTOR_SYMBOL_OPERATION_H
+#define LLVM_CLANG_TOOLING_REFACTOR_SYMBOL_OPERATION_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Tooling/Refactor/RenamedSymbol.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+
+namespace clang {
+
+class ASTContext;
+class NamedDecl;
+
+namespace tooling {
+
+/// \brief A refactoring operation that deals with occurrences of symbols.
+class SymbolOperation {
+  /// Contains the symbols that are required for this operation.
+  SmallVector<rename::Symbol, 4> Symbols;
+
+  /// Maps from a USR to an index in the \c Symbol array.
+  /// Contains all of the USRs that correspond to the declarations which use
+  /// the symbols in this operation.
+  llvm::StringMap<unsigned> USRToSymbol;
+
+  /// True if all the symbols in this operation occur only in the translation
+  /// unit that defines them.
+  bool IsLocal;
+
+  /// The declaration whose implementation is needed for the correct initiation
+  /// of a symbol operation.
+  const NamedDecl *DeclThatRequiresImplementationTU;
+
+public:
+  SymbolOperation(const NamedDecl *FoundDecl, ASTContext &Context);
+
+  SymbolOperation(SymbolOperation &&) = default;
+  SymbolOperation &operator=(SymbolOperation &&) = default;
+
+  /// Return the symbol that corresponds to the given USR, or null if this USR
+  /// isn't interesting from the perspective of this operation.
+  const rename::Symbol *getSymbolForUSR(StringRef USR) const {
+    auto It = USRToSymbol.find(USR);
+    if (It != USRToSymbol.end())
+      return &Symbols[It->getValue()];
+    return nullptr;
+  }
+
+  /// The symbols that this operation is working on.
+  ///
+  /// Symbol operations, like rename, usually just work on just one symbol.
+  /// However, there are certain language constructs that require more than
+  /// one symbol in order for them to be renamed correctly. Property
+  /// declarations in Objective-C are the perfect example: in addition to the
+  /// actual property, renaming has to rename the corresponding getters and
+  /// setters, as well as the backing ivar.
+  ArrayRef<rename::Symbol> symbols() const { return Symbols; }
+
+  /// True if all the symbols in this operation occur only in the translation
+  /// unit that defines them.
+  bool isLocal() const { return IsLocal; }
+
+  /// True if the declaration that was found in the initial TU needs to be
+  /// examined in the TU that implemented it.
+  bool requiresImplementationTU() const {
+    return DeclThatRequiresImplementationTU;
+  }
+
+  /// Returns the declaration whose implementation is needed for the correct
+  /// initiation of a symbol operation.
+  const NamedDecl *declThatRequiresImplementationTU() const {
+    return DeclThatRequiresImplementationTU;
+  }
+};
+
+/// Return true if the given declaration corresponds to a local symbol.
+bool isLocalSymbol(const NamedDecl *D, const LangOptions &LangOpts);
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_SYMBOL_OPERATION_H
diff --git a/include/clang/Tooling/Refactor/USRFinder.h b/include/clang/Tooling/Refactor/USRFinder.h
new file mode 100644
index 0000000..0a83f30
--- /dev/null
+++ b/include/clang/Tooling/Refactor/USRFinder.h
@@ -0,0 +1,85 @@
+//===--- USRFinder.h - Clang refactoring library --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Methods for determining the USR of a symbol at a location in source
+/// code.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_USR_FINDER_H
+#define LLVM_CLANG_TOOLING_REFACTOR_USR_FINDER_H
+
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include <string>
+#include <vector>
+
+namespace clang {
+
+class ASTContext;
+class Decl;
+class SourceLocation;
+class NamedDecl;
+
+namespace tooling {
+namespace rename {
+
+using llvm::StringRef;
+using namespace clang::ast_matchers;
+
+// Given an AST context and a point, returns a NamedDecl identifying the symbol
+// at the point. Returns null if nothing is found at the point.
+const NamedDecl *getNamedDeclAt(const ASTContext &Context,
+                                SourceLocation Point);
+
+/// Returns a \c NamedDecl that corresponds to the given \p USR in the given
+/// AST context. Returns null if there's no declaration that matches the given
+/// \p USR.
+const NamedDecl *getNamedDeclWithUSR(const ASTContext &Context, StringRef USR);
+
+// Converts a Decl into a USR.
+std::string getUSRForDecl(const Decl *Decl);
+
+// FIXME: Implement RecursiveASTVisitor<T>::VisitNestedNameSpecifier instead.
+class NestedNameSpecifierLocFinder : public MatchFinder::MatchCallback {
+public:
+  explicit NestedNameSpecifierLocFinder(ASTContext &Context)
+      : Context(Context) {}
+
+  ArrayRef<NestedNameSpecifierLoc> getNestedNameSpecifierLocations() {
+    addMatchers();
+    Finder.matchAST(Context);
+    return Locations;
+  }
+
+private:
+  void addMatchers() {
+    const auto NestedNameSpecifierLocMatcher =
+        nestedNameSpecifierLoc().bind("nestedNameSpecifierLoc");
+    Finder.addMatcher(NestedNameSpecifierLocMatcher, this);
+  }
+
+  void run(const MatchFinder::MatchResult &Result) override {
+    const auto *NNS = Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
+        "nestedNameSpecifierLoc");
+    Locations.push_back(*NNS);
+  }
+
+  ASTContext &Context;
+  std::vector<NestedNameSpecifierLoc> Locations;
+  MatchFinder Finder;
+};
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_USR_FINDER_H
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
index d850bd5..abb8b10 100644
--- a/include/clang/module.modulemap
+++ b/include/clang/module.modulemap
@@ -138,4 +138,7 @@
   // importing the AST matchers library gives a link dependency on the AST
   // matchers (and thus the AST), which clang-format should not have.
   exclude header "Tooling/RefactoringCallbacks.h"
+  exclude header "Tooling/Refactor/USRFinder.h"
+
+  textual header "Tooling/Refactor/RefactoringActions.def"
 }
diff --git a/include/indexstore/IndexStoreCXX.h b/include/indexstore/IndexStoreCXX.h
new file mode 100644
index 0000000..addaa86
--- /dev/null
+++ b/include/indexstore/IndexStoreCXX.h
@@ -0,0 +1,502 @@
+//===--- IndexStoreCXX.h - C++ wrapper for the Index Store C API. ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Header-only C++ wrapper for the Index Store C API.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEXSTORE_INDEXSTORECXX_H
+#define LLVM_CLANG_INDEXSTORE_INDEXSTORECXX_H
+
+#include "indexstore/indexstore.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include <ctime>
+
+namespace indexstore {
+  using llvm::ArrayRef;
+  using llvm::Optional;
+  using llvm::StringRef;
+
+static inline StringRef stringFromIndexStoreStringRef(indexstore_string_ref_t str) {
+  return StringRef(str.data, str.length);
+}
+
+class IndexRecordSymbol {
+  indexstore_symbol_t obj;
+  friend class IndexRecordReader;
+
+public:
+  IndexRecordSymbol(indexstore_symbol_t obj) : obj(obj) {}
+
+  indexstore_symbol_language_t getLanguage() {
+    return indexstore_symbol_get_language(obj);
+  }
+  indexstore_symbol_kind_t getKind() { return indexstore_symbol_get_kind(obj); }
+  indexstore_symbol_subkind_t getSubKind() { return indexstore_symbol_get_subkind(obj); }
+  uint64_t getProperties() {
+    return indexstore_symbol_get_properties(obj);
+  }
+  uint64_t getRoles() { return indexstore_symbol_get_roles(obj); }
+  uint64_t getRelatedRoles() { return indexstore_symbol_get_related_roles(obj); }
+  StringRef getName() { return stringFromIndexStoreStringRef(indexstore_symbol_get_name(obj)); }
+  StringRef getUSR() { return stringFromIndexStoreStringRef(indexstore_symbol_get_usr(obj)); }
+  StringRef getCodegenName() { return stringFromIndexStoreStringRef(indexstore_symbol_get_codegen_name(obj)); }
+};
+
+class IndexSymbolRelation {
+  indexstore_symbol_relation_t obj;
+
+public:
+  IndexSymbolRelation(indexstore_symbol_relation_t obj) : obj(obj) {}
+
+  uint64_t getRoles() { return indexstore_symbol_relation_get_roles(obj); }
+  IndexRecordSymbol getSymbol() { return indexstore_symbol_relation_get_symbol(obj); }
+};
+
+class IndexRecordOccurrence {
+  indexstore_occurrence_t obj;
+
+public:
+  IndexRecordOccurrence(indexstore_occurrence_t obj) : obj(obj) {}
+
+  IndexRecordSymbol getSymbol() { return indexstore_occurrence_get_symbol(obj); }
+  uint64_t getRoles() { return indexstore_occurrence_get_roles(obj); }
+
+  bool foreachRelation(llvm::function_ref<bool(IndexSymbolRelation)> receiver) {
+#if INDEXSTORE_HAS_BLOCKS
+    return indexstore_occurrence_relations_apply(obj, ^bool(indexstore_symbol_relation_t sym_rel) {
+      return receiver(sym_rel);
+    });
+#else
+    return false;
+#endif
+  }
+
+  std::pair<unsigned, unsigned> getLineCol() {
+    unsigned line, col;
+    indexstore_occurrence_get_line_col(obj, &line, &col);
+    return std::make_pair(line, col);
+  }
+};
+
+class IndexStore;
+typedef std::shared_ptr<IndexStore> IndexStoreRef;
+
+class IndexStore {
+  indexstore_t obj;
+  friend class IndexRecordReader;
+  friend class IndexUnitReader;
+
+public:
+  IndexStore(StringRef path, std::string &error) {
+    llvm::SmallString<64> buf = path;
+    indexstore_error_t c_err = nullptr;
+    obj = indexstore_store_create(buf.c_str(), &c_err);
+    if (c_err) {
+      error = indexstore_error_get_description(c_err);
+      indexstore_error_dispose(c_err);
+    }
+  }
+
+  IndexStore(IndexStore &&other) : obj(other.obj) {
+    other.obj = nullptr;
+  }
+
+  ~IndexStore() {
+    indexstore_store_dispose(obj);
+  }
+
+  static IndexStoreRef create(StringRef path, std::string &error) {
+    auto storeRef = std::make_shared<IndexStore>(path, error);
+    if (storeRef->isInvalid())
+      return nullptr;
+    return storeRef;
+  }
+
+  static unsigned formatVersion() {
+    return indexstore_format_version();
+  }
+
+  bool isValid() const { return obj; }
+  bool isInvalid() const { return !isValid(); }
+  explicit operator bool() const { return isValid(); }
+
+  bool foreachUnit(bool sorted, llvm::function_ref<bool(StringRef unitName)> receiver) {
+#if INDEXSTORE_HAS_BLOCKS
+    return indexstore_store_units_apply(obj, sorted, ^bool(indexstore_string_ref_t unit_name) {
+      return receiver(stringFromIndexStoreStringRef(unit_name));
+    });
+#else
+    return false;
+#endif
+  }
+
+  class UnitEvent {
+    indexstore_unit_event_t obj;
+  public:
+    UnitEvent(indexstore_unit_event_t obj) : obj(obj) {}
+
+    enum class Kind {
+      Added,
+      Removed,
+      Modified,
+      DirectoryDeleted,
+    };
+    Kind getKind() const {
+      indexstore_unit_event_kind_t c_k = indexstore_unit_event_get_kind(obj);
+      Kind K;
+      switch (c_k) {
+      case INDEXSTORE_UNIT_EVENT_ADDED: K = Kind::Added; break;
+      case INDEXSTORE_UNIT_EVENT_REMOVED: K = Kind::Removed; break;
+      case INDEXSTORE_UNIT_EVENT_MODIFIED: K = Kind::Modified; break;
+      case INDEXSTORE_UNIT_EVENT_DIRECTORY_DELETED: K = Kind::DirectoryDeleted; break;
+      }
+      return K;
+    }
+
+    StringRef getUnitName() const {
+      return stringFromIndexStoreStringRef(indexstore_unit_event_get_unit_name(obj));
+    }
+
+    timespec getModificationTime() const { return indexstore_unit_event_get_modification_time(obj); }
+  };
+
+  class UnitEventNotification {
+    indexstore_unit_event_notification_t obj;
+  public:
+    UnitEventNotification(indexstore_unit_event_notification_t obj) : obj(obj) {}
+
+    bool isInitial() const { return indexstore_unit_event_notification_is_initial(obj); }
+    size_t getEventsCount() const { return indexstore_unit_event_notification_get_events_count(obj); }
+    UnitEvent getEvent(size_t index) const { return indexstore_unit_event_notification_get_event(obj, index); }
+  };
+
+  typedef std::function<void(UnitEventNotification)> UnitEventHandler;
+
+  void setUnitEventHandler(UnitEventHandler handler) {
+#if INDEXSTORE_HAS_BLOCKS
+    if (!handler) {
+      indexstore_store_set_unit_event_handler(obj, nullptr);
+      return;
+    }
+
+    indexstore_store_set_unit_event_handler(obj, ^(indexstore_unit_event_notification_t evt_note) {
+      handler(UnitEventNotification(evt_note));
+    });
+#endif
+  }
+
+  bool startEventListening(bool waitInitialSync, std::string &error) {
+    indexstore_unit_event_listen_options_t opts;
+    opts.wait_initial_sync = waitInitialSync;
+    indexstore_error_t c_err = nullptr;
+    bool ret = indexstore_store_start_unit_event_listening(obj, &opts, sizeof(opts), &c_err);
+    if (c_err) {
+      error = indexstore_error_get_description(c_err);
+      indexstore_error_dispose(c_err);
+    }
+    return ret;
+  }
+
+  void stopEventListening() {
+    return indexstore_store_stop_unit_event_listening(obj);
+  }
+
+  void discardUnit(StringRef UnitName) {
+    llvm::SmallString<64> buf = UnitName;
+    indexstore_store_discard_unit(obj, buf.c_str());
+  }
+
+  void discardRecord(StringRef RecordName) {
+    llvm::SmallString<64> buf = RecordName;
+    indexstore_store_discard_record(obj, buf.c_str());
+  }
+
+  void getUnitNameFromOutputPath(StringRef outputPath, llvm::SmallVectorImpl<char> &nameBuf) {
+    llvm::SmallString<256> buf = outputPath;
+    size_t nameLen = indexstore_store_get_unit_name_from_output_path(obj, buf.c_str(), nameBuf.data(), nameBuf.size());
+    if (nameLen+1 > nameBuf.size()) {
+      nameBuf.resize(nameLen+1);
+      indexstore_store_get_unit_name_from_output_path(obj, buf.c_str(), nameBuf.data(), nameBuf.size());
+    }
+  }
+
+  llvm::Optional<timespec>
+  getUnitModificationTime(StringRef unitName, std::string &error) {
+    llvm::SmallString<64> buf = unitName;
+    int64_t seconds, nanoseconds;
+    indexstore_error_t c_err = nullptr;
+    bool err = indexstore_store_get_unit_modification_time(obj, buf.c_str(),
+      &seconds, &nanoseconds, &c_err);
+    if (err && c_err) {
+      error = indexstore_error_get_description(c_err);
+      indexstore_error_dispose(c_err);
+      return llvm::None;
+    }
+    timespec ts;
+    ts.tv_sec = seconds;
+    ts.tv_nsec = nanoseconds;
+    return ts;
+  }
+
+  void purgeStaleData() {
+    indexstore_store_purge_stale_data(obj);
+  }
+};
+
+class IndexRecordReader {
+  indexstore_record_reader_t obj;
+
+public:
+  IndexRecordReader(IndexStore &store, StringRef recordName, std::string &error) {
+    llvm::SmallString<64> buf = recordName;
+    indexstore_error_t c_err = nullptr;
+    obj = indexstore_record_reader_create(store.obj, buf.c_str(), &c_err);
+    if (c_err) {
+      error = indexstore_error_get_description(c_err);
+      indexstore_error_dispose(c_err);
+    }
+  }
+
+  IndexRecordReader(IndexRecordReader &&other) : obj(other.obj) {
+    other.obj = nullptr;
+  }
+
+  ~IndexRecordReader() {
+    indexstore_record_reader_dispose(obj);
+  }
+
+  bool isValid() const { return obj; }
+  bool isInvalid() const { return !isValid(); }
+  explicit operator bool() const { return isValid(); }
+
+  /// Goes through and passes record decls, after filtering using a \c Checker
+  /// function.
+  ///
+  /// Resulting decls can be used as filter for \c foreachOccurrence. This
+  /// allows allocating memory only for the record decls that the caller is
+  /// interested in.
+  bool searchSymbols(llvm::function_ref<bool(IndexRecordSymbol, bool &stop)> filter,
+                     llvm::function_ref<void(IndexRecordSymbol)> receiver) {
+#if INDEXSTORE_HAS_BLOCKS
+    return indexstore_record_reader_search_symbols(obj, ^bool(indexstore_symbol_t symbol, bool *stop) {
+      return filter(symbol, *stop);
+    }, ^(indexstore_symbol_t symbol) {
+      receiver(symbol);
+    });
+#else
+    return false;
+#endif
+  }
+
+  bool foreachSymbol(bool noCache, llvm::function_ref<bool(IndexRecordSymbol)> receiver) {
+#if INDEXSTORE_HAS_BLOCKS
+    return indexstore_record_reader_symbols_apply(obj, noCache, ^bool(indexstore_symbol_t sym) {
+      return receiver(sym);
+    });
+#else
+    return false;
+#endif
+  }
+
+  /// \param DeclsFilter if non-empty indicates the list of decls that we want
+  /// to get occurrences for. An empty array indicates that we want occurrences
+  /// for all decls.
+  /// \param RelatedDeclsFilter Same as \c DeclsFilter but for related decls.
+  bool foreachOccurrence(ArrayRef<IndexRecordSymbol> symbolsFilter,
+                         ArrayRef<IndexRecordSymbol> relatedSymbolsFilter,
+              llvm::function_ref<bool(IndexRecordOccurrence)> receiver) {
+#if INDEXSTORE_HAS_BLOCKS
+    llvm::SmallVector<indexstore_symbol_t, 16> c_symbolsFilter;
+    c_symbolsFilter.reserve(symbolsFilter.size());
+    for (IndexRecordSymbol sym : symbolsFilter) {
+      c_symbolsFilter.push_back(sym.obj);
+    }
+    llvm::SmallVector<indexstore_symbol_t, 16> c_relatedSymbolsFilter;
+    c_relatedSymbolsFilter.reserve(relatedSymbolsFilter.size());
+    for (IndexRecordSymbol sym : relatedSymbolsFilter) {
+      c_relatedSymbolsFilter.push_back(sym.obj);
+    }
+    return indexstore_record_reader_occurrences_of_symbols_apply(obj,
+                                c_symbolsFilter.data(), c_symbolsFilter.size(),
+                                c_relatedSymbolsFilter.data(),
+                                c_relatedSymbolsFilter.size(),
+                                ^bool(indexstore_occurrence_t occur) {
+                                  return receiver(occur);
+                                });
+#else
+    return false;
+#endif
+  }
+
+  bool foreachOccurrence(
+              llvm::function_ref<bool(IndexRecordOccurrence)> receiver) {
+#if INDEXSTORE_HAS_BLOCKS
+    return indexstore_record_reader_occurrences_apply(obj, ^bool(indexstore_occurrence_t occur) {
+      return receiver(occur);
+    });
+#else
+    return false;
+#endif
+  }
+
+  bool foreachOccurrenceInLineRange(unsigned lineStart, unsigned lineEnd,
+              llvm::function_ref<bool(IndexRecordOccurrence)> receiver) {
+#if INDEXSTORE_HAS_BLOCKS
+    return indexstore_record_reader_occurrences_in_line_range_apply(obj,
+                                                                    lineStart,
+                                                                    lineEnd,
+                                          ^bool(indexstore_occurrence_t occur) {
+      return receiver(occur);
+    });
+#else
+    return false;
+#endif
+  }
+};
+
+class IndexUnitDependency {
+  indexstore_unit_dependency_t obj;
+  friend class IndexUnitReader;
+
+public:
+  IndexUnitDependency(indexstore_unit_dependency_t obj) : obj(obj) {}
+
+  enum class DependencyKind {
+    Unit,
+    Record,
+    File,
+  };
+  DependencyKind getKind() {
+    switch (indexstore_unit_dependency_get_kind(obj)) {
+    case INDEXSTORE_UNIT_DEPENDENCY_UNIT: return DependencyKind::Unit;
+    case INDEXSTORE_UNIT_DEPENDENCY_RECORD: return DependencyKind::Record;
+    case INDEXSTORE_UNIT_DEPENDENCY_FILE: return DependencyKind::File;
+    }
+  }
+  bool isSystem() { return indexstore_unit_dependency_is_system(obj); }
+  StringRef getName() { return stringFromIndexStoreStringRef(indexstore_unit_dependency_get_name(obj)); }
+  StringRef getFilePath() { return stringFromIndexStoreStringRef(indexstore_unit_dependency_get_filepath(obj)); }
+  StringRef getModuleName() { return stringFromIndexStoreStringRef(indexstore_unit_dependency_get_modulename(obj)); }
+  time_t getModificationTime() { return indexstore_unit_dependency_get_modification_time(obj); }
+  size_t getFileSize() { return indexstore_unit_dependency_get_file_size(obj); }
+
+};
+
+class IndexUnitInclude {
+  indexstore_unit_include_t obj;
+  friend class IndexUnitReader;
+
+public:
+  IndexUnitInclude(indexstore_unit_include_t obj) : obj(obj) {}
+
+  StringRef getSourcePath() {
+    return stringFromIndexStoreStringRef(indexstore_unit_include_get_source_path(obj));
+  }
+  StringRef getTargetPath() {
+    return stringFromIndexStoreStringRef(indexstore_unit_include_get_target_path(obj));
+  }
+  unsigned getSourceLine() {
+    return indexstore_unit_include_get_source_line(obj);
+  }
+};
+
+class IndexUnitReader {
+  indexstore_unit_reader_t obj;
+
+public:
+  IndexUnitReader(IndexStore &store, StringRef unitName, std::string &error) {
+    llvm::SmallString<64> buf = unitName;
+    indexstore_error_t c_err = nullptr;
+    obj = indexstore_unit_reader_create(store.obj, buf.c_str(), &c_err);
+    if (c_err) {
+      error = indexstore_error_get_description(c_err);
+      indexstore_error_dispose(c_err);
+    }
+  }
+
+  IndexUnitReader(IndexUnitReader &&other) : obj(other.obj) {
+    other.obj = nullptr;
+  }
+
+  ~IndexUnitReader() {
+    indexstore_unit_reader_dispose(obj);
+  }
+
+  bool isValid() const { return obj; }
+  bool isInvalid() const { return !isValid(); }
+  explicit operator bool() const { return isValid(); }
+
+  StringRef getProviderIdentifier() {
+    return stringFromIndexStoreStringRef(indexstore_unit_reader_get_provider_identifier(obj));
+  }
+  StringRef getProviderVersion() {
+    return stringFromIndexStoreStringRef(indexstore_unit_reader_get_provider_version(obj));
+  }
+
+  timespec getModificationTime() {
+    int64_t seconds, nanoseconds;
+    indexstore_unit_reader_get_modification_time(obj, &seconds, &nanoseconds);
+    timespec ts;
+    ts.tv_sec = seconds;
+    ts.tv_nsec = nanoseconds;
+    return ts;
+  }
+
+  bool isSystemUnit() { return indexstore_unit_reader_is_system_unit(obj); }
+  bool isModuleUnit() { return indexstore_unit_reader_is_module_unit(obj); }
+  bool isDebugCompilation() { return indexstore_unit_reader_is_debug_compilation(obj); }
+  bool hasMainFile() { return indexstore_unit_reader_has_main_file(obj); }
+
+  StringRef getMainFilePath() {
+    return stringFromIndexStoreStringRef(indexstore_unit_reader_get_main_file(obj));
+  }
+  StringRef getModuleName() {
+    return stringFromIndexStoreStringRef(indexstore_unit_reader_get_module_name(obj));
+  }
+  StringRef getWorkingDirectory() {
+    return stringFromIndexStoreStringRef(indexstore_unit_reader_get_working_dir(obj));
+  }
+  StringRef getOutputFile() {
+    return stringFromIndexStoreStringRef(indexstore_unit_reader_get_output_file(obj));
+  }
+  StringRef getSysrootPath() {
+    return stringFromIndexStoreStringRef(indexstore_unit_reader_get_sysroot_path(obj));
+  }
+  StringRef getTarget() {
+    return stringFromIndexStoreStringRef(indexstore_unit_reader_get_target(obj));
+  }
+
+  bool foreachDependency(llvm::function_ref<bool(IndexUnitDependency)> receiver) {
+#if INDEXSTORE_HAS_BLOCKS
+    return indexstore_unit_reader_dependencies_apply(obj, ^bool(indexstore_unit_dependency_t dep) {
+      return receiver(dep);
+    });
+#else
+    return false;
+#endif
+  }
+
+  bool foreachInclude(llvm::function_ref<bool(IndexUnitInclude)> receiver) {
+#if INDEXSTORE_HAS_BLOCKS
+    return indexstore_unit_reader_includes_apply(obj, ^bool(indexstore_unit_include_t inc) {
+      return receiver(inc);
+    });
+#else
+    return false;
+#endif
+  }
+};
+
+} // namespace indexstore
+
+#endif
diff --git a/include/indexstore/indexstore.h b/include/indexstore/indexstore.h
new file mode 100644
index 0000000..f4f41db
--- /dev/null
+++ b/include/indexstore/indexstore.h
@@ -0,0 +1,490 @@
+/*===-- indexstore/indexstore.h - Index Store C API ----------------- C -*-===*\
+|*                                                                            *|
+|*                     The LLVM Compiler Infrastructure                       *|
+|*                                                                            *|
+|* This file is distributed under the University of Illinois Open Source      *|
+|* License. See LICENSE.TXT for details.                                      *|
+|*                                                                            *|
+|*===----------------------------------------------------------------------===*|
+|*                                                                            *|
+|* This header provides a C API for the index store.                          *|
+|*                                                                            *|
+\*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_CLANG_C_INDEXSTORE_INDEXSTORE_H
+#define LLVM_CLANG_C_INDEXSTORE_INDEXSTORE_H
+
+#include <stdint.h>
+#include <stddef.h>
+#include <ctime>
+
+/**
+ * \brief The version constants for the Index Store C API.
+ * INDEXSTORE_VERSION_MINOR should increase when there are API additions.
+ * INDEXSTORE_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
+ */
+#define INDEXSTORE_VERSION_MAJOR 0
+#define INDEXSTORE_VERSION_MINOR 9
+
+#define INDEXSTORE_VERSION_ENCODE(major, minor) ( \
+      ((major) * 10000)                           \
+    + ((minor) *     1))
+
+#define INDEXSTORE_VERSION INDEXSTORE_VERSION_ENCODE( \
+    INDEXSTORE_VERSION_MAJOR,                         \
+    INDEXSTORE_VERSION_MINOR )
+
+#define INDEXSTORE_VERSION_STRINGIZE_(major, minor)   \
+    #major"."#minor
+#define INDEXSTORE_VERSION_STRINGIZE(major, minor)    \
+    INDEXSTORE_VERSION_STRINGIZE_(major, minor)
+
+#define INDEXSTORE_VERSION_STRING INDEXSTORE_VERSION_STRINGIZE( \
+    INDEXSTORE_VERSION_MAJOR,                                   \
+    INDEXSTORE_VERSION_MINOR)
+
+#ifdef  __cplusplus
+# define INDEXSTORE_BEGIN_DECLS  extern "C" {
+# define INDEXSTORE_END_DECLS    }
+#else
+# define INDEXSTORE_BEGIN_DECLS
+# define INDEXSTORE_END_DECLS
+#endif
+
+#ifndef INDEXSTORE_PUBLIC
+# if defined (_MSC_VER)
+#  define INDEXSTORE_PUBLIC __declspec(dllimport)
+# else
+#  define INDEXSTORE_PUBLIC
+# endif
+#endif
+
+#ifndef __has_feature
+# define __has_feature(x) 0
+#endif
+
+#if __has_feature(blocks)
+# define INDEXSTORE_HAS_BLOCKS 1
+#else
+# define INDEXSTORE_HAS_BLOCKS 0
+#endif
+
+INDEXSTORE_BEGIN_DECLS
+
+typedef void *indexstore_error_t;
+
+INDEXSTORE_PUBLIC const char *
+indexstore_error_get_description(indexstore_error_t);
+
+INDEXSTORE_PUBLIC void
+indexstore_error_dispose(indexstore_error_t);
+
+typedef struct {
+  const char *data;
+  size_t length;
+} indexstore_string_ref_t;
+
+INDEXSTORE_PUBLIC unsigned
+indexstore_format_version(void);
+
+typedef void *indexstore_t;
+
+INDEXSTORE_PUBLIC indexstore_t
+indexstore_store_create(const char *store_path, indexstore_error_t *error);
+
+INDEXSTORE_PUBLIC void
+indexstore_store_dispose(indexstore_t);
+
+#if INDEXSTORE_HAS_BLOCKS
+INDEXSTORE_PUBLIC bool
+indexstore_store_units_apply(indexstore_t, unsigned sorted,
+                             bool(^applier)(indexstore_string_ref_t unit_name));
+#endif
+
+typedef void *indexstore_unit_event_notification_t;
+typedef void *indexstore_unit_event_t;
+
+INDEXSTORE_PUBLIC size_t
+indexstore_unit_event_notification_get_events_count(indexstore_unit_event_notification_t);
+
+INDEXSTORE_PUBLIC indexstore_unit_event_t
+indexstore_unit_event_notification_get_event(indexstore_unit_event_notification_t, size_t index);
+
+INDEXSTORE_PUBLIC bool
+indexstore_unit_event_notification_is_initial(indexstore_unit_event_notification_t);
+
+typedef enum {
+  INDEXSTORE_UNIT_EVENT_ADDED = 1,
+  INDEXSTORE_UNIT_EVENT_REMOVED = 2,
+  INDEXSTORE_UNIT_EVENT_MODIFIED = 3,
+  INDEXSTORE_UNIT_EVENT_DIRECTORY_DELETED = 4,
+} indexstore_unit_event_kind_t;
+
+INDEXSTORE_PUBLIC indexstore_unit_event_kind_t
+indexstore_unit_event_get_kind(indexstore_unit_event_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_event_get_unit_name(indexstore_unit_event_t);
+
+INDEXSTORE_PUBLIC timespec
+indexstore_unit_event_get_modification_time(indexstore_unit_event_t);
+
+#if INDEXSTORE_HAS_BLOCKS
+typedef void (^indexstore_unit_event_handler_t)(indexstore_unit_event_notification_t);
+
+INDEXSTORE_PUBLIC void
+indexstore_store_set_unit_event_handler(indexstore_t,
+                                        indexstore_unit_event_handler_t handler);
+#endif
+
+typedef struct {
+  /// If true, \c indexstore_store_start_unit_event_listening will block until
+  /// the initial set of units is passed to the unit event handler, otherwise
+  /// the function will return and the initial set will be passed asynchronously.
+  bool wait_initial_sync;
+} indexstore_unit_event_listen_options_t;
+
+INDEXSTORE_PUBLIC bool
+indexstore_store_start_unit_event_listening(indexstore_t,
+                                            indexstore_unit_event_listen_options_t *,
+                                            size_t listen_options_struct_size,
+                                            indexstore_error_t *error);
+
+INDEXSTORE_PUBLIC void
+indexstore_store_stop_unit_event_listening(indexstore_t);
+
+INDEXSTORE_PUBLIC void
+indexstore_store_discard_unit(indexstore_t, const char *unit_name);
+
+INDEXSTORE_PUBLIC void
+indexstore_store_discard_record(indexstore_t, const char *record_name);
+
+INDEXSTORE_PUBLIC void
+indexstore_store_purge_stale_data(indexstore_t);
+
+/// Determines the unit name from the \c output_path and writes it out in the
+/// \c name_buf buffer. It doesn't write more than \c buf_size.
+/// \returns the length of the name. If this is larger than \c buf_size, the
+/// caller should call the function again with a buffer of the appropriate size.
+INDEXSTORE_PUBLIC size_t
+indexstore_store_get_unit_name_from_output_path(indexstore_t store,
+                                                const char *output_path,
+                                                char *name_buf,
+                                                size_t buf_size);
+
+/// \returns true if an error occurred, false otherwise.
+INDEXSTORE_PUBLIC bool
+indexstore_store_get_unit_modification_time(indexstore_t store,
+                                            const char *unit_name,
+                                            int64_t *seconds,
+                                            int64_t *nanoseconds,
+                                            indexstore_error_t *error);
+
+typedef void *indexstore_symbol_t;
+
+typedef enum {
+  INDEXSTORE_SYMBOL_KIND_UNKNOWN = 0,
+  INDEXSTORE_SYMBOL_KIND_MODULE = 1,
+  INDEXSTORE_SYMBOL_KIND_NAMESPACE = 2,
+  INDEXSTORE_SYMBOL_KIND_NAMESPACEALIAS = 3,
+  INDEXSTORE_SYMBOL_KIND_MACRO = 4,
+  INDEXSTORE_SYMBOL_KIND_ENUM = 5,
+  INDEXSTORE_SYMBOL_KIND_STRUCT = 6,
+  INDEXSTORE_SYMBOL_KIND_CLASS = 7,
+  INDEXSTORE_SYMBOL_KIND_PROTOCOL = 8,
+  INDEXSTORE_SYMBOL_KIND_EXTENSION = 9,
+  INDEXSTORE_SYMBOL_KIND_UNION = 10,
+  INDEXSTORE_SYMBOL_KIND_TYPEALIAS = 11,
+  INDEXSTORE_SYMBOL_KIND_FUNCTION = 12,
+  INDEXSTORE_SYMBOL_KIND_VARIABLE = 13,
+  INDEXSTORE_SYMBOL_KIND_FIELD = 14,
+  INDEXSTORE_SYMBOL_KIND_ENUMCONSTANT = 15,
+  INDEXSTORE_SYMBOL_KIND_INSTANCEMETHOD = 16,
+  INDEXSTORE_SYMBOL_KIND_CLASSMETHOD = 17,
+  INDEXSTORE_SYMBOL_KIND_STATICMETHOD = 18,
+  INDEXSTORE_SYMBOL_KIND_INSTANCEPROPERTY = 19,
+  INDEXSTORE_SYMBOL_KIND_CLASSPROPERTY = 20,
+  INDEXSTORE_SYMBOL_KIND_STATICPROPERTY = 21,
+  INDEXSTORE_SYMBOL_KIND_CONSTRUCTOR = 22,
+  INDEXSTORE_SYMBOL_KIND_DESTRUCTOR = 23,
+  INDEXSTORE_SYMBOL_KIND_CONVERSIONFUNCTION = 24,
+  INDEXSTORE_SYMBOL_KIND_PARAMETER = 25,
+  INDEXSTORE_SYMBOL_KIND_USING = 26,
+
+  INDEXSTORE_SYMBOL_KIND_COMMENTTAG = 1000,
+} indexstore_symbol_kind_t;
+
+typedef enum {
+  INDEXSTORE_SYMBOL_SUBKIND_NONE = 0,
+  INDEXSTORE_SYMBOL_SUBKIND_CXXCOPYCONSTRUCTOR = 1,
+  INDEXSTORE_SYMBOL_SUBKIND_CXXMOVECONSTRUCTOR = 2,
+  INDEXSTORE_SYMBOL_SUBKIND_ACCESSORGETTER = 3,
+  INDEXSTORE_SYMBOL_SUBKIND_ACCESSORSETTER = 4,
+  INDEXSTORE_SYMBOL_SUBKIND_USINGTYPENAME = 5,
+  INDEXSTORE_SYMBOL_SUBKIND_USINGVALUE = 6,
+
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORWILLSET = 1000,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORDIDSET = 1001,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORADDRESSOR = 1002,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORMUTABLEADDRESSOR = 1003,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFSTRUCT = 1004,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFCLASS = 1005,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFENUM = 1006,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFPROTOCOL = 1007,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTPREFIXOPERATOR = 1008,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTPOSTFIXOPERATOR = 1009,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTINFIXOPERATOR = 1010,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTSUBSCRIPT = 1011,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTASSOCIATEDTYPE = 1012,
+  INDEXSTORE_SYMBOL_SUBKIND_SWIFTGENERICTYPEPARAM = 1013,
+} indexstore_symbol_subkind_t;
+
+typedef enum {
+  INDEXSTORE_SYMBOL_PROPERTY_GENERIC                          = 1 << 0,
+  INDEXSTORE_SYMBOL_PROPERTY_TEMPLATE_PARTIAL_SPECIALIZATION  = 1 << 1,
+  INDEXSTORE_SYMBOL_PROPERTY_TEMPLATE_SPECIALIZATION          = 1 << 2,
+  INDEXSTORE_SYMBOL_PROPERTY_UNITTEST                         = 1 << 3,
+  INDEXSTORE_SYMBOL_PROPERTY_IBANNOTATED                      = 1 << 4,
+  INDEXSTORE_SYMBOL_PROPERTY_IBOUTLETCOLLECTION               = 1 << 5,
+  INDEXSTORE_SYMBOL_PROPERTY_GKINSPECTABLE                    = 1 << 6,
+  INDEXSTORE_SYMBOL_PROPERTY_LOCAL                            = 1 << 7,
+} indexstore_symbol_property_t;
+
+typedef enum {
+  INDEXSTORE_SYMBOL_LANG_C = 0,
+  INDEXSTORE_SYMBOL_LANG_OBJC = 1,
+  INDEXSTORE_SYMBOL_LANG_CXX = 2,
+
+  INDEXSTORE_SYMBOL_LANG_SWIFT = 100,
+} indexstore_symbol_language_t;
+
+typedef enum {
+  INDEXSTORE_SYMBOL_ROLE_DECLARATION = 1 << 0,
+  INDEXSTORE_SYMBOL_ROLE_DEFINITION  = 1 << 1,
+  INDEXSTORE_SYMBOL_ROLE_REFERENCE   = 1 << 2,
+  INDEXSTORE_SYMBOL_ROLE_READ        = 1 << 3,
+  INDEXSTORE_SYMBOL_ROLE_WRITE       = 1 << 4,
+  INDEXSTORE_SYMBOL_ROLE_CALL        = 1 << 5,
+  INDEXSTORE_SYMBOL_ROLE_DYNAMIC     = 1 << 6,
+  INDEXSTORE_SYMBOL_ROLE_ADDRESSOF   = 1 << 7,
+  INDEXSTORE_SYMBOL_ROLE_IMPLICIT    = 1 << 8,
+
+  // Relation roles.
+  INDEXSTORE_SYMBOL_ROLE_REL_CHILDOF     = 1 << 9,
+  INDEXSTORE_SYMBOL_ROLE_REL_BASEOF      = 1 << 10,
+  INDEXSTORE_SYMBOL_ROLE_REL_OVERRIDEOF  = 1 << 11,
+  INDEXSTORE_SYMBOL_ROLE_REL_RECEIVEDBY  = 1 << 12,
+  INDEXSTORE_SYMBOL_ROLE_REL_CALLEDBY    = 1 << 13,
+  INDEXSTORE_SYMBOL_ROLE_REL_EXTENDEDBY  = 1 << 14,
+  INDEXSTORE_SYMBOL_ROLE_REL_ACCESSOROF  = 1 << 15,
+  INDEXSTORE_SYMBOL_ROLE_REL_CONTAINEDBY = 1 << 16,
+  INDEXSTORE_SYMBOL_ROLE_REL_IBTYPEOF    = 1 << 17,
+  INDEXSTORE_SYMBOL_ROLE_REL_SPECIALIZATIONOF = 1 << 18,
+} indexstore_symbol_role_t;
+
+INDEXSTORE_PUBLIC indexstore_symbol_language_t
+indexstore_symbol_get_language(indexstore_symbol_t);
+
+INDEXSTORE_PUBLIC indexstore_symbol_kind_t
+indexstore_symbol_get_kind(indexstore_symbol_t);
+
+INDEXSTORE_PUBLIC indexstore_symbol_subkind_t
+indexstore_symbol_get_subkind(indexstore_symbol_t);
+
+INDEXSTORE_PUBLIC uint64_t
+indexstore_symbol_get_properties(indexstore_symbol_t);
+
+INDEXSTORE_PUBLIC uint64_t
+indexstore_symbol_get_roles(indexstore_symbol_t);
+
+INDEXSTORE_PUBLIC uint64_t
+indexstore_symbol_get_related_roles(indexstore_symbol_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_symbol_get_name(indexstore_symbol_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_symbol_get_usr(indexstore_symbol_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_symbol_get_codegen_name(indexstore_symbol_t);
+
+typedef void *indexstore_symbol_relation_t;
+
+INDEXSTORE_PUBLIC uint64_t
+indexstore_symbol_relation_get_roles(indexstore_symbol_relation_t);
+
+INDEXSTORE_PUBLIC indexstore_symbol_t
+indexstore_symbol_relation_get_symbol(indexstore_symbol_relation_t);
+
+typedef void *indexstore_occurrence_t;
+
+INDEXSTORE_PUBLIC indexstore_symbol_t
+indexstore_occurrence_get_symbol(indexstore_occurrence_t);
+
+#if INDEXSTORE_HAS_BLOCKS
+INDEXSTORE_PUBLIC bool
+indexstore_occurrence_relations_apply(indexstore_occurrence_t,
+                      bool(^applier)(indexstore_symbol_relation_t symbol_rel));
+#endif
+
+INDEXSTORE_PUBLIC uint64_t
+indexstore_occurrence_get_roles(indexstore_occurrence_t);
+
+INDEXSTORE_PUBLIC void
+indexstore_occurrence_get_line_col(indexstore_occurrence_t,
+                              unsigned *line, unsigned *column);
+
+typedef void *indexstore_record_reader_t;
+
+INDEXSTORE_PUBLIC indexstore_record_reader_t
+indexstore_record_reader_create(indexstore_t store, const char *record_name,
+                                indexstore_error_t *error);
+
+INDEXSTORE_PUBLIC void
+indexstore_record_reader_dispose(indexstore_record_reader_t);
+
+#if INDEXSTORE_HAS_BLOCKS
+/// Goes through the symbol data and passes symbols to \c receiver, for the
+/// symbol data that \c filter returns true on.
+///
+/// This allows allocating memory only for the record symbols that the caller is
+/// interested in.
+INDEXSTORE_PUBLIC bool
+indexstore_record_reader_search_symbols(indexstore_record_reader_t,
+    bool(^filter)(indexstore_symbol_t symbol, bool *stop),
+    void(^receiver)(indexstore_symbol_t symbol));
+
+/// \param nocache if true, avoids allocating memory for the symbols.
+/// Useful when the caller does not intend to keep \c indexstore_record_reader_t
+/// for more queries.
+INDEXSTORE_PUBLIC bool
+indexstore_record_reader_symbols_apply(indexstore_record_reader_t,
+                                       bool nocache,
+                                    bool(^applier)(indexstore_symbol_t symbol));
+
+INDEXSTORE_PUBLIC bool
+indexstore_record_reader_occurrences_apply(indexstore_record_reader_t,
+                                 bool(^applier)(indexstore_occurrence_t occur));
+
+INDEXSTORE_PUBLIC bool
+indexstore_record_reader_occurrences_in_line_range_apply(indexstore_record_reader_t,
+                                                         unsigned line_start,
+                                                         unsigned line_count,
+                                 bool(^applier)(indexstore_occurrence_t occur));
+
+/// \param symbols if non-zero \c symbols_count, indicates the list of symbols
+/// that we want to get occurrences for. An empty array indicates that we want
+/// occurrences for all symbols.
+/// \param related_symbols Same as \c symbols but for related symbols.
+INDEXSTORE_PUBLIC bool
+indexstore_record_reader_occurrences_of_symbols_apply(indexstore_record_reader_t,
+        indexstore_symbol_t *symbols, size_t symbols_count,
+        indexstore_symbol_t *related_symbols, size_t related_symbols_count,
+        bool(^applier)(indexstore_occurrence_t occur));
+#endif
+
+
+typedef void *indexstore_unit_reader_t;
+
+INDEXSTORE_PUBLIC indexstore_unit_reader_t
+indexstore_unit_reader_create(indexstore_t store, const char *unit_name,
+                              indexstore_error_t *error);
+
+INDEXSTORE_PUBLIC void
+indexstore_unit_reader_dispose(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_reader_get_provider_identifier(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_reader_get_provider_version(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC void
+indexstore_unit_reader_get_modification_time(indexstore_unit_reader_t,
+                                             int64_t *seconds,
+                                             int64_t *nanoseconds);
+
+INDEXSTORE_PUBLIC bool
+indexstore_unit_reader_is_system_unit(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC bool
+indexstore_unit_reader_is_module_unit(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC bool
+indexstore_unit_reader_is_debug_compilation(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC bool
+indexstore_unit_reader_has_main_file(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_reader_get_main_file(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_reader_get_module_name(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_reader_get_working_dir(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_reader_get_output_file(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_reader_get_sysroot_path(indexstore_unit_reader_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_reader_get_target(indexstore_unit_reader_t);
+
+typedef void *indexstore_unit_dependency_t;
+typedef void *indexstore_unit_include_t;
+
+typedef enum {
+  INDEXSTORE_UNIT_DEPENDENCY_UNIT = 1,
+  INDEXSTORE_UNIT_DEPENDENCY_RECORD = 2,
+  INDEXSTORE_UNIT_DEPENDENCY_FILE = 3,
+} indexstore_unit_dependency_kind_t;
+
+INDEXSTORE_PUBLIC indexstore_unit_dependency_kind_t
+indexstore_unit_dependency_get_kind(indexstore_unit_dependency_t);
+
+INDEXSTORE_PUBLIC bool
+indexstore_unit_dependency_is_system(indexstore_unit_dependency_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_dependency_get_filepath(indexstore_unit_dependency_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_dependency_get_modulename(indexstore_unit_dependency_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_dependency_get_name(indexstore_unit_dependency_t);
+
+INDEXSTORE_PUBLIC time_t
+indexstore_unit_dependency_get_modification_time(indexstore_unit_dependency_t);
+
+INDEXSTORE_PUBLIC size_t
+indexstore_unit_dependency_get_file_size(indexstore_unit_dependency_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_include_get_source_path(indexstore_unit_include_t);
+
+INDEXSTORE_PUBLIC indexstore_string_ref_t
+indexstore_unit_include_get_target_path(indexstore_unit_include_t);
+
+INDEXSTORE_PUBLIC unsigned
+indexstore_unit_include_get_source_line(indexstore_unit_include_t);
+
+#if INDEXSTORE_HAS_BLOCKS
+INDEXSTORE_PUBLIC bool
+indexstore_unit_reader_dependencies_apply(indexstore_unit_reader_t,
+                             bool(^applier)(indexstore_unit_dependency_t));
+
+INDEXSTORE_PUBLIC bool
+indexstore_unit_reader_includes_apply(indexstore_unit_reader_t,
+                             bool(^applier)(indexstore_unit_include_t));
+
+#endif
+
+INDEXSTORE_END_DECLS
+
+#endif
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..6fc0fda
--- /dev/null
+++ b/lib/APINotes/APINotesManager.cpp
@@ -0,0 +1,426 @@
+//===--- 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");
+
+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) { }
+
+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];
+}
+
+std::unique_ptr<APINotesReader>
+APINotesManager::loadAPINotes(const FileEntry *apiNotesFile) {
+  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);
+  }
+
+  // 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.
+  // FIXME: We don't even really need to go through the binary format at all;
+  // we're just going to immediately deserialize it again.
+  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()));
+  }
+
+  // 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..a5dd24d
--- /dev/null
+++ b/lib/APINotes/APINotesReader.cpp
@@ -0,0 +1,1879 @@
+//===--- 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)) {
+
+  assert(!Results.empty());
+  assert(std::is_sorted(Results.begin(), Results.end(),
+                        [](const std::pair<VersionTuple, T> &left,
+                           const std::pair<VersionTuple, T> &right) -> bool {
+    assert(left.first != right.first && "two entries for the same version");
+    return left.first < right.first;
+  }));
+
+  Selected = Results.size();
+  for (unsigned i = 0, n = Results.size(); i != n; ++i) {
+    if (version && Results[i].first >= version) {
+      // If the current version is "4", then entries for 4 are better than
+      // entries for 5, but both are valid. Because entries are sorted, we get
+      // that behavior by picking the first match.
+      Selected = i;
+      break;
+    }
+  }
+
+  // If we didn't find a match but we have an unversioned result, use the
+  // unversioned result. This will always be the first entry because we encode
+  // it as version 0.
+  if (Selected == Results.size() && Results[0].first.empty())
+    Selected = 0;
+}
+
+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..b178e25
--- /dev/null
+++ b/lib/APINotes/APINotesWriter.cpp
@@ -0,0 +1,1328 @@
+//===--- 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,
+         SmallVectorImpl<std::pair<VersionTuple, T>> &infoArray,
+         llvm::function_ref<void(raw_ostream &out,
+                                 const typename MakeDependent<T>::Type& info)>
+           emitInfo) {
+    std::sort(infoArray.begin(), infoArray.end(),
+              [](const std::pair<VersionTuple, T> &left,
+                 const std::pair<VersionTuple, T> &right) -> bool {
+      assert(left.first != right.first && "two entries for the same version");
+      return left.first < right.first;
+    });
+    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 = 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/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index c60373c..a7d673c 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4080,11 +4080,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 =
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 92ed7da..57b9b09 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -1711,6 +1711,8 @@
 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) {
   dumpName(D);
   dumpDeclRef(D->getClassInterface());
+  OS << " ";
+  dumpLocation(D->getClassInterfaceLoc());
 }
 
 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 2c0bb11..6e33b98 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -956,16 +956,12 @@
     ToData.HasUninitializedFields = FromData.HasUninitializedFields;
     ToData.HasInheritedConstructor = FromData.HasInheritedConstructor;
     ToData.HasInheritedAssignment = FromData.HasInheritedAssignment;
-    ToData.NeedOverloadResolutionForCopyConstructor
-      = FromData.NeedOverloadResolutionForCopyConstructor;
     ToData.NeedOverloadResolutionForMoveConstructor
       = FromData.NeedOverloadResolutionForMoveConstructor;
     ToData.NeedOverloadResolutionForMoveAssignment
       = FromData.NeedOverloadResolutionForMoveAssignment;
     ToData.NeedOverloadResolutionForDestructor
       = FromData.NeedOverloadResolutionForDestructor;
-    ToData.DefaultedCopyConstructorIsDeleted
-      = FromData.DefaultedCopyConstructorIsDeleted;
     ToData.DefaultedMoveConstructorIsDeleted
       = FromData.DefaultedMoveConstructorIsDeleted;
     ToData.DefaultedMoveAssignmentIsDeleted
@@ -977,7 +973,6 @@
       = FromData.HasConstexprNonCopyMoveConstructor;
     ToData.HasDefaultedDefaultConstructor
       = FromData.HasDefaultedDefaultConstructor;
-    ToData.CanPassInRegisters = FromData.CanPassInRegisters;
     ToData.DefaultedDefaultConstructorIsConstexpr
       = FromData.DefaultedDefaultConstructorIsConstexpr;
     ToData.HasConstexprDefaultConstructor
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 5782b7b..1caceab 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -55,18 +55,15 @@
       HasOnlyCMembers(true), HasInClassInitializer(false),
       HasUninitializedReferenceMember(false), HasUninitializedFields(false),
       HasInheritedConstructor(false), HasInheritedAssignment(false),
-      NeedOverloadResolutionForCopyConstructor(false),
       NeedOverloadResolutionForMoveConstructor(false),
       NeedOverloadResolutionForMoveAssignment(false),
       NeedOverloadResolutionForDestructor(false),
-      DefaultedCopyConstructorIsDeleted(false),
       DefaultedMoveConstructorIsDeleted(false),
       DefaultedMoveAssignmentIsDeleted(false),
       DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All),
       DeclaredNonTrivialSpecialMembers(0), HasIrrelevantDestructor(true),
       HasConstexprNonCopyMoveConstructor(false),
       HasDefaultedDefaultConstructor(false),
-      CanPassInRegisters(true),
       DefaultedDefaultConstructorIsConstexpr(true),
       HasConstexprDefaultConstructor(false),
       HasNonLiteralTypeFieldsOrBases(false), ComputedVisibleConversions(false),
@@ -355,10 +352,8 @@
       setHasVolatileMember(true);
 
     // Keep track of the presence of mutable fields.
-    if (BaseClassDecl->hasMutableFields()) {
+    if (BaseClassDecl->hasMutableFields())
       data().HasMutableFields = true;
-      data().NeedOverloadResolutionForCopyConstructor = true;
-    }
 
     if (BaseClassDecl->hasUninitializedReferenceMember())
       data().HasUninitializedReferenceMember = true;
@@ -411,8 +406,6 @@
   //    -- a direct or virtual base class B that cannot be copied/moved [...]
   //    -- a non-static data member of class type M (or array thereof)
   //       that cannot be copied or moved [...]
-  if (!Subobj->hasSimpleCopyConstructor())
-    data().NeedOverloadResolutionForCopyConstructor = true;
   if (!Subobj->hasSimpleMoveConstructor())
     data().NeedOverloadResolutionForMoveConstructor = true;
 
@@ -433,7 +426,6 @@
   //    -- any non-static data member has a type with a destructor
   //       that is deleted or inaccessible from the defaulted [ctor or dtor].
   if (!Subobj->hasSimpleDestructor()) {
-    data().NeedOverloadResolutionForCopyConstructor = true;
     data().NeedOverloadResolutionForMoveConstructor = true;
     data().NeedOverloadResolutionForDestructor = true;
   }
@@ -719,10 +711,8 @@
       data().IsStandardLayout = false;
 
     // Keep track of the presence of mutable fields.
-    if (Field->isMutable()) {
+    if (Field->isMutable())
       data().HasMutableFields = true;
-      data().NeedOverloadResolutionForCopyConstructor = true;
-    }
 
     // C++11 [class.union]p8, DR1460:
     //   If X is a union, a non-static data member of X that is not an anonymous
@@ -766,12 +756,6 @@
       //   A standard-layout class is a class that:
       //    -- has no non-static data members of type [...] reference,
       data().IsStandardLayout = false;
-
-      // C++1z [class.copy.ctor]p10:
-      //   A defaulted copy constructor for a class X is defined as deleted if X has:
-      //    -- a non-static data member of rvalue reference type
-      if (T->isRValueReferenceType())
-        data().DefaultedCopyConstructorIsDeleted = true;
     }
 
     if (!Field->hasInClassInitializer() && !Field->isMutable()) {
@@ -825,10 +809,6 @@
         // We may need to perform overload resolution to determine whether a
         // field can be moved if it's const or volatile qualified.
         if (T.getCVRQualifiers() & (Qualifiers::Const | Qualifiers::Volatile)) {
-          // We need to care about 'const' for the copy constructor because an
-          // implicit copy constructor might be declared with a non-const
-          // parameter.
-          data().NeedOverloadResolutionForCopyConstructor = true;
           data().NeedOverloadResolutionForMoveConstructor = true;
           data().NeedOverloadResolutionForMoveAssignment = true;
         }
@@ -839,8 +819,6 @@
         //    -- X is a union-like class that has a variant member with a
         //       non-trivial [corresponding special member]
         if (isUnion()) {
-          if (FieldRec->hasNonTrivialCopyConstructor())
-            data().DefaultedCopyConstructorIsDeleted = true;
           if (FieldRec->hasNonTrivialMoveConstructor())
             data().DefaultedMoveConstructorIsDeleted = true;
           if (FieldRec->hasNonTrivialMoveAssignment())
@@ -852,8 +830,6 @@
         // For an anonymous union member, our overload resolution will perform
         // overload resolution for its members.
         if (Field->isAnonymousStructOrUnion()) {
-          data().NeedOverloadResolutionForCopyConstructor |=
-              FieldRec->data().NeedOverloadResolutionForCopyConstructor;
           data().NeedOverloadResolutionForMoveConstructor |=
               FieldRec->data().NeedOverloadResolutionForMoveConstructor;
           data().NeedOverloadResolutionForMoveAssignment |=
@@ -939,10 +915,8 @@
         }
         
         // Keep track of the presence of mutable fields.
-        if (FieldRec->hasMutableFields()) {
+        if (FieldRec->hasMutableFields())
           data().HasMutableFields = true;
-          data().NeedOverloadResolutionForCopyConstructor = true;
-        }
 
         // C++11 [class.copy]p13:
         //   If the implicitly-defined constructor would satisfy the
@@ -1476,7 +1450,7 @@
 
 void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
   RecordDecl::completeDefinition();
-
+  
   // If the class may be abstract (but hasn't been marked as such), check for
   // any pure final overriders.
   if (mayBeAbstract()) {
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index d8bdb63..2fb95eb 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -1338,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,
@@ -2157,18 +2153,19 @@
 
 void ObjCCompatibleAliasDecl::anchor() { }
 
-ObjCCompatibleAliasDecl *
-ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC,
-                                SourceLocation L,
-                                IdentifierInfo *Id,
-                                ObjCInterfaceDecl* AliasedClass) {
-  return new (C, DC) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass);
+ObjCCompatibleAliasDecl *ObjCCompatibleAliasDecl::Create(
+    ASTContext &C, DeclContext *DC, SourceLocation NameLoc, IdentifierInfo *Id,
+    ObjCInterfaceDecl *AliasedClass, SourceLocation AliasedClassLoc,
+    SourceLocation AtLoc) {
+  return new (C, DC) ObjCCompatibleAliasDecl(DC, NameLoc, Id, AliasedClass,
+                                             AliasedClassLoc, AtLoc);
 }
 
 ObjCCompatibleAliasDecl *
 ObjCCompatibleAliasDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
-  return new (C, ID) ObjCCompatibleAliasDecl(nullptr, SourceLocation(),
-                                             nullptr, nullptr);
+  return new (C, ID)
+      ObjCCompatibleAliasDecl(nullptr, SourceLocation(), nullptr, nullptr,
+                              SourceLocation(), SourceLocation());
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index 6eeba88..7b7a8b9 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -28,6 +28,7 @@
   class DeclPrinter : public DeclVisitor<DeclPrinter> {
     raw_ostream &Out;
     PrintingPolicy Policy;
+    const ASTContext &Context;
     unsigned Indentation;
     bool PrintInstantiation;
 
@@ -48,9 +49,10 @@
 
   public:
     DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
-                unsigned Indentation = 0, bool PrintInstantiation = false)
-      : Out(Out), Policy(Policy), Indentation(Indentation),
-        PrintInstantiation(PrintInstantiation) { }
+                const ASTContext &Context, unsigned Indentation = 0,
+                bool PrintInstantiation = false)
+        : Out(Out), Policy(Policy), Context(Context), Indentation(Indentation),
+          PrintInstantiation(PrintInstantiation) {}
 
     void VisitDeclContext(DeclContext *DC, bool Indent = true);
 
@@ -115,10 +117,19 @@
 
 void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
                  unsigned Indentation, bool PrintInstantiation) const {
-  DeclPrinter Printer(Out, Policy, Indentation, PrintInstantiation);
+  DeclPrinter Printer(Out, Policy, getASTContext(), Indentation,
+                      PrintInstantiation);
   Printer.Visit(const_cast<Decl*>(this));
 }
 
+void TemplateParameterList::print(raw_ostream &Out,
+                                  const PrintingPolicy &Policy,
+                                  const ASTContext &Context,
+                                  unsigned Indentation) const {
+  DeclPrinter Printer(Out, Policy, Context, Indentation);
+  Printer.printTemplateParameters(this);
+}
+
 static QualType GetBaseType(QualType T) {
   // FIXME: This should be on the Type class!
   QualType BaseType = T;
@@ -192,7 +203,7 @@
     DC = DC->getParent();
   
   ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
-  DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), 0);
+  DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), Ctx, 0);
   Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
 }
 
@@ -467,7 +478,7 @@
   prettyPrintAttributes(D);
   if (Expr *Init = D->getInitExpr()) {
     Out << " = ";
-    Init->printPretty(Out, nullptr, Policy, Indentation);
+    Init->printPretty(Out, nullptr, Policy, Indentation, &Context);
   }
 }
 
@@ -488,13 +499,15 @@
   CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
   CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
   if (!Policy.SuppressSpecifiers) {
-    switch (D->getStorageClass()) {
-    case SC_None: break;
-    case SC_Extern: Out << "extern "; break;
-    case SC_Static: Out << "static "; break;
-    case SC_PrivateExtern: Out << "__private_extern__ "; break;
-    case SC_Auto: case SC_Register:
-      llvm_unreachable("invalid for functions");
+    if (!Policy.SupressStorageClassSpecifiers) {
+      switch (D->getStorageClass()) {
+      case SC_None: break;
+      case SC_Extern: Out << "extern "; break;
+      case SC_Static: Out << "static "; break;
+      case SC_PrivateExtern: Out << "__private_extern__ "; break;
+      case SC_Auto: case SC_Register:
+        llvm_unreachable("invalid for functions");
+      }
     }
 
     if (D->isInlineSpecified())  Out << "inline ";
@@ -521,7 +534,7 @@
     Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
   if (const TemplateArgumentList *TArgs = D->getTemplateSpecializationArgs()) {
     llvm::raw_string_ostream POut(Proto);
-    DeclPrinter TArgPrinter(POut, SubPolicy, Indentation);
+    DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
     TArgPrinter.printTemplateArguments(*TArgs);
   }
 
@@ -539,7 +552,7 @@
     Proto += "(";
     if (FT) {
       llvm::raw_string_ostream POut(Proto);
-      DeclPrinter ParamPrinter(POut, SubPolicy, Indentation);
+      DeclPrinter ParamPrinter(POut, SubPolicy, Context, Indentation);
       for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
         if (i) POut << ", ";
         ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
@@ -695,7 +708,7 @@
         // This is a K&R function definition, so we need to print the
         // parameters.
         Out << '\n';
-        DeclPrinter ParamPrinter(Out, SubPolicy, Indentation);
+        DeclPrinter ParamPrinter(Out, SubPolicy, Context, Indentation);
         Indentation += Policy.Indentation;
         for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
           Indent();
@@ -1261,6 +1274,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/Expr.cpp b/lib/AST/Expr.cpp
index afc7fa8..ef47639 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1695,6 +1695,26 @@
   }
 }
 
+const FieldDecl *CastExpr::getTargetFieldForToUnionCast(QualType unionType,
+                                                        QualType opType) {
+  auto RD = unionType->castAs<RecordType>()->getDecl();
+  return getTargetFieldForToUnionCast(RD, opType);
+}
+
+const FieldDecl *CastExpr::getTargetFieldForToUnionCast(const RecordDecl *RD,
+                                                        QualType OpType) {
+  auto &Ctx = RD->getASTContext();
+  RecordDecl::field_iterator Field, FieldEnd;
+  for (Field = RD->field_begin(), FieldEnd = RD->field_end();
+       Field != FieldEnd; ++Field) {
+    if (Ctx.hasSameUnqualifiedType(Field->getType(), OpType) &&
+        !Field->isUnnamedBitfield()) {
+      return *Field;
+    }
+  }
+  return nullptr;
+}
+
 ImplicitCastExpr *ImplicitCastExpr::Create(const ASTContext &C, QualType T,
                                            CastKind Kind, Expr *Operand,
                                            const CXXCastPath *BasePath,
diff --git a/lib/AST/NestedNameSpecifier.cpp b/lib/AST/NestedNameSpecifier.cpp
index e2e0dbe..88ee526 100644
--- a/lib/AST/NestedNameSpecifier.cpp
+++ b/lib/AST/NestedNameSpecifier.cpp
@@ -691,3 +691,34 @@
   memcpy(Mem, Buffer, BufferSize);
   return NestedNameSpecifierLoc(Representation, Mem);
 }
+
+NestedNameSpecifier *NestedNameSpecifier::getRequiredQualification(
+    ASTContext &Context, const DeclContext *CurContext,
+    const DeclContext *TargetContext) {
+  SmallVector<const DeclContext *, 4> TargetParents;
+
+  for (const DeclContext *CommonAncestor = TargetContext;
+       CommonAncestor && !CommonAncestor->Encloses(CurContext);
+       CommonAncestor = CommonAncestor->getLookupParent()) {
+    if (CommonAncestor->isTransparentContext() ||
+        CommonAncestor->isFunctionOrMethod())
+      continue;
+
+    TargetParents.push_back(CommonAncestor);
+  }
+
+  NestedNameSpecifier *Result = nullptr;
+  while (!TargetParents.empty()) {
+    const DeclContext *Parent = TargetParents.pop_back_val();
+
+    if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
+      if (!Namespace->getIdentifier())
+        continue;
+
+      Result = NestedNameSpecifier::Create(Context, Result, Namespace);
+    } else if (const TagDecl *TD = dyn_cast<TagDecl>(Parent))
+      Result = NestedNameSpecifier::Create(
+          Context, Result, false, Context.getTypeDeclType(TD).getTypePtr());
+  }
+  return Result;
+}
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 5ebaa32..89fd1b9 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -24,6 +24,7 @@
 #include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Basic/CharInfo.h"
+#include "clang/Lex/Lexer.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Format.h"
 using namespace clang;
@@ -38,12 +39,14 @@
     unsigned IndentLevel;
     clang::PrinterHelper* Helper;
     PrintingPolicy Policy;
+    const ASTContext *Context;
 
   public:
-    StmtPrinter(raw_ostream &os, PrinterHelper* helper,
-                const PrintingPolicy &Policy,
-                unsigned Indentation = 0)
-      : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy) {}
+    StmtPrinter(raw_ostream &os, PrinterHelper *helper,
+                const PrintingPolicy &Policy, unsigned Indentation = 0,
+                const ASTContext *Context = nullptr)
+        : OS(os), IndentLevel(Indentation), Helper(helper), Policy(Policy),
+          Context(Context) {}
 
     void PrintStmt(Stmt *S) {
       PrintStmt(S, Policy.Indentation);
@@ -1419,7 +1422,26 @@
   }
 }
 
+/// Prints the given expression using the original source text. Returns true on
+/// success, false otherwise.
+static bool printExprAsWritten(raw_ostream &OS, Expr *E,
+                               const ASTContext *Context) {
+  if (!Context)
+    return false;
+  bool Invalid = false;
+  StringRef Source = Lexer::getSourceText(
+      CharSourceRange::getTokenRange(E->getSourceRange()),
+      Context->getSourceManager(), Context->getLangOpts(), &Invalid);
+  if (!Invalid) {
+    OS << Source;
+    return true;
+  }
+  return false;
+}
+
 void StmtPrinter::VisitIntegerLiteral(IntegerLiteral *Node) {
+  if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
+    return;
   bool isSigned = Node->getType()->isSignedIntegerType();
   OS << Node->getValue().toString(10, isSigned);
 
@@ -1463,6 +1485,8 @@
 }
 
 void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
+  if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
+    return;
   PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
 }
 
@@ -2672,11 +2696,10 @@
   printPretty(llvm::errs(), nullptr, PrintingPolicy(Context.getLangOpts()));
 }
 
-void Stmt::printPretty(raw_ostream &OS,
-                       PrinterHelper *Helper,
-                       const PrintingPolicy &Policy,
-                       unsigned Indentation) const {
-  StmtPrinter P(OS, Helper, Policy, Indentation);
+void Stmt::printPretty(raw_ostream &OS, PrinterHelper *Helper,
+                       const PrintingPolicy &Policy, unsigned Indentation,
+                       const ASTContext *Context) const {
+  StmtPrinter P(OS, Helper, Policy, Indentation, Context);
   P.Visit(const_cast<Stmt*>(this));
 }
 
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index d21781d..fddd7db 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1081,24 +1081,13 @@
 
     // Replace an Objective-C type parameter reference with the corresponding
     // type argument.
-    if (const auto *OTPTy = dyn_cast<ObjCTypeParamType>(splitType.Ty)) {
-      if (auto *typeParam = dyn_cast<ObjCTypeParamDecl>(OTPTy->getDecl())) {
+    if (const auto *typedefTy = dyn_cast<TypedefType>(splitType.Ty)) {
+      if (auto *typeParam = dyn_cast<ObjCTypeParamDecl>(typedefTy->getDecl())) {
         // If we have type arguments, use them.
         if (!typeArgs.empty()) {
+          // FIXME: Introduce SubstObjCTypeParamType ?
           QualType argType = typeArgs[typeParam->getIndex()];
-          if (OTPTy->qual_empty())
-            return ctx.getQualifiedType(argType, splitType.Quals);
-
-          // Apply protocol lists if exists.
-          bool hasError;
-          SmallVector<ObjCProtocolDecl*, 8> protocolsVec;
-          protocolsVec.append(OTPTy->qual_begin(),
-                              OTPTy->qual_end());
-          ArrayRef<ObjCProtocolDecl *> protocolsToApply = protocolsVec;
-          QualType resultTy = ctx.applyObjCProtocolQualifiers(argType,
-              protocolsToApply, hasError, true/*allowOnPointerType*/);
-
-          return ctx.getQualifiedType(resultTy, splitType.Quals);
+          return ctx.getQualifiedType(argType, splitType.Quals);
         }
 
         switch (context) {
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 15c63bf..269abb2 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -84,11 +84,12 @@
     unsigned Indentation;
     bool HasEmptyPlaceHolder;
     bool InsideCCAttribute;
+    bool IgnoreFunctionProtoTypeConstQual;
 
   public:
     explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)
-      : Policy(Policy), Indentation(Indentation),
-        HasEmptyPlaceHolder(false), InsideCCAttribute(false) { }
+        : Policy(Policy), Indentation(Indentation), HasEmptyPlaceHolder(false),
+          InsideCCAttribute(false), IgnoreFunctionProtoTypeConstQual(false) {}
 
     void print(const Type *ty, Qualifiers qs, raw_ostream &OS,
                StringRef PlaceHolder);
@@ -689,8 +690,12 @@
   printFunctionAfter(Info, OS);
 
   if (unsigned quals = T->getTypeQuals()) {
-    OS << ' ';
-    AppendTypeQualList(OS, quals, Policy.Restrict);
+    if (IgnoreFunctionProtoTypeConstQual)
+      quals &= ~unsigned(Qualifiers::Const);
+    if (quals) {
+      OS << ' ';
+      AppendTypeQualList(OS, quals, Policy.Restrict);
+    }
   }
 
   switch (T->getRefQualifier()) {
@@ -1009,6 +1014,13 @@
   else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
     assert(Typedef->getIdentifier() && "Typedef without identifier?");
     OS << Typedef->getIdentifier()->getName();
+  } else if (Policy.UseStdFunctionForLambda && isa<CXXRecordDecl>(D) &&
+             cast<CXXRecordDecl>(D)->isLambda()) {
+    OS << "std::function<";
+    QualType T = cast<CXXRecordDecl>(D)->getLambdaCallOperator()->getType();
+    SaveAndRestore<bool> NoConst(IgnoreFunctionProtoTypeConstQual, true);
+    print(T, OS, "");
+    OS << '>';
   } else {
     // Make an unambiguous representation for anonymous types, e.g.
     //   (anonymous enum at /usr/include/string.h:120:9)
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index e971b55..36198af 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -98,6 +98,7 @@
   Sanitizers.cpp
   SourceLocation.cpp
   SourceManager.cpp
+  SourceMgrAdapter.cpp
   TargetInfo.cpp
   Targets.cpp
   TokenKinds.cpp
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index 0cdaf8e..c7e4133 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -43,7 +43,7 @@
   unsigned SFINAE : 2;
   unsigned WarnNoWerror : 1;
   unsigned WarnShowInSystemHeader : 1;
-  unsigned Category : 5;
+  unsigned Category : 6;
 
   uint16_t OptionGroupIndex;
 
@@ -88,6 +88,7 @@
 #include "clang/Basic/DiagnosticCommentKinds.inc"
 #include "clang/Basic/DiagnosticSemaKinds.inc"
 #include "clang/Basic/DiagnosticAnalysisKinds.inc"
+#include "clang/Basic/DiagnosticRefactoringKinds.inc"
 #undef DIAG
 };
 
@@ -137,6 +138,7 @@
 CATEGORY(COMMENT, AST)
 CATEGORY(SEMA, COMMENT)
 CATEGORY(ANALYSIS, SEMA)
+CATEGORY(REFACTORING, ANALYSIS)
 #undef CATEGORY
 
   // Avoid out of bounds reads.
diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp
index 1d96afd..3ac9679 100644
--- a/lib/Basic/Module.cpp
+++ b/lib/Basic/Module.cpp
@@ -32,7 +32,8 @@
       IsMissingRequirement(false), HasIncompatibleModuleFile(false),
       IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework),
       IsExplicit(IsExplicit), IsSystem(false), IsExternC(false),
-      IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false),
+      IsInferred(false), IsSwiftInferImportAsMember(false),
+      InferSubmodules(false), InferExplicitSubmodules(false),
       InferExportWildcard(false), ConfigMacrosExhaustive(false),
       NoUndeclaredIncludes(false), NameVisibility(Hidden) {
   if (Parent) {
@@ -85,11 +86,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) {
@@ -361,6 +367,8 @@
       OS << " [system]";
     if (IsExternC)
       OS << " [extern_c]";
+    if (IsSwiftInferImportAsMember)
+      OS << " [swift_infer_import_as_member]";
   }
 
   OS << " {\n";
@@ -440,6 +448,11 @@
     }
   }
 
+  if (!ExportAsModule.empty()) {
+    OS.indent(Indent + 2);
+    OS << "export_as" << ExportAsModule << "\n";
+  }
+  
   for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
        MI != MIEnd; ++MI)
     // Print inferred subframework modules so that we don't need to re-infer
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 915c161..b0dc0d2 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -4881,7 +4881,7 @@
 
     // x86-64 has atomics up to 16 bytes.
     MaxAtomicPromoteWidth = 128;
-    MaxAtomicInlineWidth = 128;
+    MaxAtomicInlineWidth = 64;
   }
   BuiltinVaListKind getBuiltinVaListKind() const override {
     return TargetInfo::X86_64ABIBuiltinVaList;
@@ -4938,6 +4938,13 @@
     return llvm::makeArrayRef(BuiltinInfoX86,
                               X86::LastTSBuiltin - Builtin::FirstTSBuiltin);
   }
+
+  void setMaxAtomicWidth() override {
+    if (hasFeature("cx16"))
+      MaxAtomicInlineWidth = 128;
+    return;
+  }
+
 };
 
 // x86-64 Windows target
@@ -10029,6 +10036,7 @@
 
   Target->setSupportedOpenCLOpts();
   Target->setOpenCLExtensionOpts();
+  Target->setMaxAtomicWidth();
 
   if (!Target->validateTarget(Diags))
     return nullptr;
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index dfd819a..5e291e5 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)
@@ -18,6 +19,7 @@
 add_subdirectory(FrontendTool)
 add_subdirectory(Tooling)
 add_subdirectory(Index)
+add_subdirectory(DirectoryWatcher)
 if(CLANG_ENABLE_STATIC_ANALYZER)
   add_subdirectory(StaticAnalyzer)
 endif()
diff --git a/lib/CodeGen/ABIInfo.h b/lib/CodeGen/ABIInfo.h
index 575506d..e4dce2f 100644
--- a/lib/CodeGen/ABIInfo.h
+++ b/lib/CodeGen/ABIInfo.h
@@ -24,7 +24,6 @@
 
 namespace clang {
   class ASTContext;
-  class CodeGenOptions;
   class TargetInfo;
 
 namespace CodeGen {
@@ -69,7 +68,6 @@
     llvm::LLVMContext &getVMContext() const;
     const llvm::DataLayout &getDataLayout() const;
     const TargetInfo &getTarget() const;
-    const CodeGenOptions &getCodeGenOpts() const;
 
     /// Return the calling convention to use for system runtime
     /// functions.
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 1810489..6cf7f71 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -16,6 +16,7 @@
 #include "CGObjCRuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "clang/CodeGen/ConstantInitBuilder.h"
 #include "clang/AST/DeclObjC.h"
 #include "llvm/ADT/SmallSet.h"
@@ -290,7 +291,7 @@
   const Expr *init = var->getInit();
   if (!init) return nullptr;
 
-  return CGM.EmitConstantInit(*var, CGF);
+  return ConstantEmitter(CGM, CGF).tryEmitAbstractForInitializer(*var);
 }
 
 /// Get the low bit of a nonzero character count.  This is the
@@ -724,12 +725,13 @@
   llvm::Constant *blockFn
     = CodeGenFunction(CGM, true).GenerateBlockFunction(CurGD, blockInfo,
                                                        LocalDeclMap,
-                                                       isLambdaConv);
+                                                       isLambdaConv,
+                                                       blockInfo.CanBeGlobal);
   blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy);
 
   // If there is nothing to capture, we can emit this as a global block.
   if (blockInfo.CanBeGlobal)
-    return buildGlobalBlock(CGM, blockInfo, blockFn);
+    return CGM.getAddrOfGlobalBlockIfEmitted(blockInfo.BlockExpression);
 
   // Otherwise, we have to emit this as a local block.
 
@@ -1113,17 +1115,14 @@
   computeBlockInfo(*this, nullptr, blockInfo);
 
   // Using that metadata, generate the actual block function.
-  llvm::Constant *blockFn;
   {
     CodeGenFunction::DeclMapTy LocalDeclMap;
-    blockFn = CodeGenFunction(*this).GenerateBlockFunction(GlobalDecl(),
-                                                           blockInfo,
-                                                           LocalDeclMap,
-                                                           false);
+    CodeGenFunction(*this).GenerateBlockFunction(
+        GlobalDecl(), blockInfo, LocalDeclMap,
+        /*IsLambdaConversionToBlock*/ false, /*BuildGlobalBlock*/ true);
   }
-  blockFn = llvm::ConstantExpr::getBitCast(blockFn, VoidPtrTy);
 
-  return buildGlobalBlock(*this, blockInfo, blockFn);
+  return getAddrOfGlobalBlockIfEmitted(BE);
 }
 
 static llvm::Constant *buildGlobalBlock(CodeGenModule &CGM,
@@ -1225,7 +1224,8 @@
 CodeGenFunction::GenerateBlockFunction(GlobalDecl GD,
                                        const CGBlockInfo &blockInfo,
                                        const DeclMapTy &ldm,
-                                       bool IsLambdaConversionToBlock) {
+                                       bool IsLambdaConversionToBlock,
+                                       bool BuildGlobalBlock) {
   const BlockDecl *blockDecl = blockInfo.getBlockDecl();
 
   CurGD = GD;
@@ -1284,6 +1284,10 @@
       fnLLVMType, llvm::GlobalValue::InternalLinkage, name, &CGM.getModule());
   CGM.SetInternalFunctionAttributes(blockDecl, fn, fnInfo);
 
+  if (BuildGlobalBlock)
+    buildGlobalBlock(CGM, blockInfo,
+                     llvm::ConstantExpr::getBitCast(fn, VoidPtrTy));
+
   // Begin generating the function.
   StartFunction(blockDecl, fnType->getReturnType(), fn, fnInfo, args,
                 blockDecl->getLocation(),
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index f3527b0..c43b0e5 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -16,6 +16,7 @@
 #include "CGOpenCLRuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -641,6 +642,26 @@
 };
 }
 
+Value *CodeGenFunction::EmitCheckedArgForBuiltin(const Expr *E,
+                                                 BuiltinCheckKind Kind) {
+  assert(Kind == BCK_CLZPassedZero ||
+         Kind == BCK_CTZPassedZero && "Unsupported builtin check kind");
+
+  Value *ArgValue = EmitScalarExpr(E);
+  if (!SanOpts.has(SanitizerKind::Builtin) || !getTarget().isCLZForZeroUndef())
+    return ArgValue;
+
+  SanitizerScope SanScope(this);
+  Value *Cond = Builder.CreateICmpNE(
+      ArgValue, llvm::Constant::getNullValue(ArgValue->getType()));
+  EmitCheck(std::make_pair(Cond, SanitizerKind::Builtin),
+            SanitizerHandler::InvalidBuiltin,
+            {EmitCheckSourceLocation(E->getExprLoc()),
+             llvm::ConstantInt::get(Builder.getInt8Ty(), Kind)},
+            None);
+  return ArgValue;
+}
+
 RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
                                         unsigned BuiltinID, const CallExpr *E,
                                         ReturnValueSlot ReturnValue) {
@@ -660,7 +681,7 @@
   default: break;  // Handle intrinsics and libm functions below.
   case Builtin::BI__builtin___CFStringMakeConstantString:
   case Builtin::BI__builtin___NSStringMakeConstantString:
-    return RValue::get(CGM.EmitConstantExpr(E, E->getType(), nullptr));
+    return RValue::get(ConstantEmitter(*this).emitAbstract(E, E->getType()));
   case Builtin::BI__builtin_stdarg_start:
   case Builtin::BI__builtin_va_start:
   case Builtin::BI__va_start:
@@ -792,7 +813,7 @@
   case Builtin::BI__builtin_ctz:
   case Builtin::BI__builtin_ctzl:
   case Builtin::BI__builtin_ctzll: {
-    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CTZPassedZero);
 
     llvm::Type *ArgType = ArgValue->getType();
     Value *F = CGM.getIntrinsic(Intrinsic::cttz, ArgType);
@@ -809,7 +830,7 @@
   case Builtin::BI__builtin_clz:
   case Builtin::BI__builtin_clzl:
   case Builtin::BI__builtin_clzll: {
-    Value *ArgValue = EmitScalarExpr(E->getArg(0));
+    Value *ArgValue = EmitCheckedArgForBuiltin(E->getArg(0), BCK_CLZPassedZero);
 
     llvm::Type *ArgType = ArgValue->getType();
     Value *F = CGM.getIntrinsic(Intrinsic::ctlz, ArgType);
@@ -1346,8 +1367,8 @@
                                       llvm::ConstantInt::get(Int32Ty, Offset)));
   }
   case Builtin::BI__builtin_return_address: {
-    Value *Depth =
-        CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this);
+    Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
+                                                   getContext().UnsignedIntTy);
     Value *F = CGM.getIntrinsic(Intrinsic::returnaddress);
     return RValue::get(Builder.CreateCall(F, Depth));
   }
@@ -1356,8 +1377,8 @@
     return RValue::get(Builder.CreateCall(F, Builder.getInt32(0)));
   }
   case Builtin::BI__builtin_frame_address: {
-    Value *Depth =
-        CGM.EmitConstantExpr(E->getArg(0), getContext().UnsignedIntTy, this);
+    Value *Depth = ConstantEmitter(*this).emitAbstract(E->getArg(0),
+                                                   getContext().UnsignedIntTy);
     Value *F = CGM.getIntrinsic(Intrinsic::frameaddress);
     return RValue::get(Builder.CreateCall(F, Depth));
   }
diff --git a/lib/CodeGen/CGCXXABI.cpp b/lib/CodeGen/CGCXXABI.cpp
index 0332586..e29e525 100644
--- a/lib/CodeGen/CGCXXABI.cpp
+++ b/lib/CodeGen/CGCXXABI.cpp
@@ -30,9 +30,38 @@
 }
 
 bool CGCXXABI::canCopyArgument(const CXXRecordDecl *RD) const {
+  // If RD has a non-trivial move or copy constructor, we cannot copy the
+  // argument.
+  if (RD->hasNonTrivialCopyConstructor() || RD->hasNonTrivialMoveConstructor())
+    return false;
+
+  // If RD has a non-trivial destructor, we cannot copy the argument.
+  if (RD->hasNonTrivialDestructor())
+    return false;
+
   // We can only copy the argument if there exists at least one trivial,
   // non-deleted copy or move constructor.
-  return RD->canPassInRegisters();
+  // FIXME: This assumes that all lazily declared copy and move constructors are
+  // not deleted.  This assumption might not be true in some corner cases.
+  bool CopyDeleted = false;
+  bool MoveDeleted = false;
+  for (const CXXConstructorDecl *CD : RD->ctors()) {
+    if (CD->isCopyConstructor() || CD->isMoveConstructor()) {
+      assert(CD->isTrivial());
+      // We had at least one undeleted trivial copy or move ctor.  Return
+      // directly.
+      if (!CD->isDeleted())
+        return true;
+      if (CD->isCopyConstructor())
+        CopyDeleted = true;
+      else
+        MoveDeleted = true;
+    }
+  }
+
+  // If all trivial copy and move constructors are deleted, we cannot copy the
+  // argument.
+  return !(CopyDeleted && MoveDeleted);
 }
 
 llvm::Constant *CGCXXABI::GetBogusMemberPointer(QualType T) {
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 18b1d10..fc354e6 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -18,6 +18,7 @@
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclFriend.h"
 #include "clang/AST/DeclObjC.h"
@@ -527,16 +528,15 @@
 
   // Create new compile unit.
   // FIXME - Eliminate TheCU.
+  auto &CGOpts = CGM.getCodeGenOpts();
   TheCU = DBuilder.createCompileUnit(
       LangTag,
       DBuilder.createFile(remapDIPath(MainFileName),
                           remapDIPath(getCurrentDirname()), CSKind, Checksum),
-      Producer, LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers,
-      CGM.getCodeGenOpts().EnableSplitDwarf
-          ? ""
-          : CGM.getCodeGenOpts().SplitDwarfFile,
-      EmissionKind, 0 /* DWOid */, CGM.getCodeGenOpts().SplitDwarfInlining,
-      CGM.getCodeGenOpts().DebugInfoForProfiling);
+      Producer, LO.Optimize || CGOpts.PrepareForLTO || CGOpts.EmitSummaryIndex,
+      CGOpts.DwarfDebugFlags, RuntimeVers,
+      CGOpts.EnableSplitDwarf ? "" : CGOpts.SplitDwarfFile, EmissionKind,
+      0 /* DWOid */, CGOpts.SplitDwarfInlining, CGOpts.DebugInfoForProfiling);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
@@ -1590,7 +1590,7 @@
       QualType T = E->getType();
       if (E->isGLValue())
         T = CGM.getContext().getLValueReferenceType(T);
-      llvm::Constant *V = CGM.EmitConstantExpr(E, T);
+      llvm::Constant *V = ConstantEmitter(CGM).emitAbstract(E, T);
       assert(V && "Expression in template argument isn't constant");
       llvm::DIType *TTy = getOrCreateType(T, Unit);
       TemplateParams.push_back(DBuilder.createTemplateValueParameter(
@@ -1766,6 +1766,29 @@
   return false;
 }
 
+/// Does a type definition exist in an imported clang module?
+static bool isDefinedInClangModule(const RecordDecl *RD) {
+  // Only definitions that where imported from an AST file come from a module.
+  if (!RD || !RD->isFromASTFile())
+    return false;
+  // Anonymous entities cannot be addressed. Treat them as not from module.
+  if (!RD->isExternallyVisible() && RD->getName().empty())
+    return false;
+  if (auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
+    if (!CXXDecl->isCompleteDefinition())
+      return false;
+    auto TemplateKind = CXXDecl->getTemplateSpecializationKind();
+    if (TemplateKind != TSK_Undeclared) {
+      // This is a template, check the origin of the first member.
+      if (CXXDecl->field_begin() == CXXDecl->field_end())
+        return TemplateKind == TSK_ExplicitInstantiationDeclaration;
+      if (!CXXDecl->field_begin()->isFromASTFile())
+        return false;
+    }
+  }
+  return true;
+}
+
 void CGDebugInfo::completeClassData(const RecordDecl *RD) {
   if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
     if (CXXRD->isDynamicClass() &&
@@ -1773,6 +1796,10 @@
             llvm::GlobalValue::AvailableExternallyLinkage &&
         !isClassOrMethodDLLImport(CXXRD))
       return;
+
+  if (DebugTypeExtRefs && isDefinedInClangModule(RD->getDefinition()))
+    return;
+
   completeClass(RD);
 }
 
@@ -1799,29 +1826,6 @@
   return false;
 }
 
-/// Does a type definition exist in an imported clang module?
-static bool isDefinedInClangModule(const RecordDecl *RD) {
-  // Only definitions that where imported from an AST file come from a module.
-  if (!RD || !RD->isFromASTFile())
-    return false;
-  // Anonymous entities cannot be addressed. Treat them as not from module.
-  if (!RD->isExternallyVisible() && RD->getName().empty())
-    return false;
-  if (auto *CXXDecl = dyn_cast<CXXRecordDecl>(RD)) {
-    if (!CXXDecl->isCompleteDefinition())
-      return false;
-    auto TemplateKind = CXXDecl->getTemplateSpecializationKind();
-    if (TemplateKind != TSK_Undeclared) {
-      // This is a template, check the origin of the first member.
-      if (CXXDecl->field_begin() == CXXDecl->field_end())
-        return TemplateKind == TSK_ExplicitInstantiationDeclaration;
-      if (!CXXDecl->field_begin()->isFromASTFile())
-        return false;
-    }
-  }
-  return true;
-}
-
 static bool shouldOmitDefinition(codegenoptions::DebugInfoKind DebugKind,
                                  bool DebugTypeExtRefs, const RecordDecl *RD,
                                  const LangOptions &LangOpts) {
@@ -3795,7 +3799,7 @@
   if (LocalAddr) {
     // Insert an llvm.dbg.value into the current block.
     DBuilder.insertDbgValueIntrinsic(
-        LocalAddr, 0, debugVar, DBuilder.createExpression(),
+        LocalAddr, debugVar, DBuilder.createExpression(),
         llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
         Builder.GetInsertBlock());
   }
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 2351786..75a1350 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -19,6 +19,7 @@
 #include "CGOpenMPRuntime.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
@@ -307,7 +308,8 @@
 llvm::GlobalVariable *
 CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
                                                llvm::GlobalVariable *GV) {
-  llvm::Constant *Init = CGM.EmitConstantInit(D, this);
+  ConstantEmitter emitter(*this);
+  llvm::Constant *Init = emitter.tryEmitForInitializer(D);
 
   // If constant emission failed, then this should be a C++ static
   // initializer.
@@ -355,6 +357,8 @@
   GV->setConstant(CGM.isTypeConstant(D.getType(), true));
   GV->setInitializer(Init);
 
+  emitter.finalize(GV);
+
   if (hasNontrivialDestruction(D.getType()) && HaveInsertPoint()) {
     // We have a constant initializer, but a nontrivial destructor. We still
     // need to perform a guarded "initialization" in order to register the
@@ -1236,7 +1240,7 @@
   llvm::Constant *constant = nullptr;
   if (emission.IsConstantAggregate || D.isConstexpr()) {
     assert(!capturedByInit && "constant init contains a capturing block?");
-    constant = CGM.EmitConstantInit(D, this);
+    constant = ConstantEmitter(*this).tryEmitAbstractForInitializer(D);
   }
 
   if (!constant) {
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 40ae092..709ed00 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -15,6 +15,7 @@
 #include "CGCXXABI.h"
 #include "CGCleanup.h"
 #include "CGObjCRuntime.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/Mangle.h"
 #include "clang/AST/StmtCXX.h"
@@ -1800,7 +1801,8 @@
   // "catch i8* null". We can't do this on x86 because the filter has to save
   // the exception code.
   llvm::Constant *C =
-      CGM.EmitConstantExpr(Except->getFilterExpr(), getContext().IntTy, this);
+    ConstantEmitter(*this).tryEmitAbstract(Except->getFilterExpr(),
+                                           getContext().IntTy);
   if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
       C->isOneValue()) {
     CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index bc37c9e..1a4b48a 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -20,6 +20,7 @@
 #include "CGRecordLayout.h"
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Attr.h"
@@ -356,7 +357,7 @@
     if (CGF.CGM.getCodeGenOpts().MergeAllConstants &&
         (Ty->isArrayType() || Ty->isRecordType()) &&
         CGF.CGM.isTypeConstant(Ty, true))
-      if (llvm::Constant *Init = CGF.CGM.EmitConstantExpr(Inner, Ty, &CGF)) {
+      if (auto Init = ConstantEmitter(CGF).tryEmitAbstract(Inner, Ty)) {
         if (auto AddrSpace = CGF.getTarget().getConstantAddressSpace()) {
           auto AS = AddrSpace.getValue();
           auto *GV = new llvm::GlobalVariable(
@@ -604,20 +605,23 @@
   auto PtrToAlloca =
       dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases());
 
+  llvm::Value *IsNonNull = nullptr;
+  bool IsGuaranteedNonNull =
+      SkippedChecks.has(SanitizerKind::Null) || PtrToAlloca;
   bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
                            TCK == TCK_UpcastToVirtualBase;
   if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
-      !SkippedChecks.has(SanitizerKind::Null) && !PtrToAlloca) {
+      !IsGuaranteedNonNull) {
     // The glvalue must not be an empty glvalue.
-    llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);
+    IsNonNull = Builder.CreateIsNotNull(Ptr);
 
     // The IR builder can constant-fold the null check if the pointer points to
     // a constant.
-    bool PtrIsNonNull =
+    IsGuaranteedNonNull =
         IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext());
 
     // Skip the null check if the pointer is known to be non-null.
-    if (!PtrIsNonNull) {
+    if (!IsGuaranteedNonNull) {
       if (AllowNullPointers) {
         // When performing pointer casts, it's OK if the value is null.
         // Skip the remaining checks in that case.
@@ -697,6 +701,18 @@
        TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||
        TCK == TCK_UpcastToVirtualBase) &&
       RD && RD->hasDefinition() && RD->isDynamicClass()) {
+    // Ensure that the pointer is non-null before loading it. If there is no
+    // compile-time guarantee, reuse the run-time null check or emit a new one.
+    if (!IsGuaranteedNonNull) {
+      if (!IsNonNull)
+        IsNonNull = Builder.CreateIsNotNull(Ptr);
+      if (!Done)
+        Done = createBasicBlock("vptr.null");
+      llvm::BasicBlock *VptrNotNull = createBasicBlock("vptr.not.null");
+      Builder.CreateCondBr(IsNonNull, VptrNotNull, Done);
+      EmitBlock(VptrNotNull);
+    }
+
     // Compute a hash of the mangled name of the type.
     //
     // FIXME: This is not guaranteed to be deterministic! Move to a
@@ -1303,7 +1319,8 @@
     return ConstantEmission();
 
   // Emit as a constant.
-  llvm::Constant *C = CGM.EmitConstantValue(result.Val, resultType, this);
+  auto C = ConstantEmitter(*this).emitAbstract(refExpr->getLocation(),
+                                               result.Val, resultType);
 
   // Make sure we emit a debug reference to the global variable.
   // This should probably fire even for
@@ -1322,6 +1339,25 @@
   return ConstantEmission::forValue(C);
 }
 
+static DeclRefExpr *tryToConvertMemberExprToDeclRefExpr(CodeGenFunction &CGF,
+                                                        const MemberExpr *ME) {
+  if (auto *VD = dyn_cast<VarDecl>(ME->getMemberDecl())) {
+    // Try to emit static variable member expressions as DREs.
+    return DeclRefExpr::Create(
+        CGF.getContext(), NestedNameSpecifierLoc(), SourceLocation(), VD,
+        /*RefersToEnclosingVariableOrCapture=*/false, ME->getExprLoc(),
+        ME->getType(), ME->getValueKind());
+  }
+  return nullptr;
+}
+
+CodeGenFunction::ConstantEmission
+CodeGenFunction::tryEmitAsConstant(const MemberExpr *ME) {
+  if (DeclRefExpr *DRE = tryToConvertMemberExprToDeclRefExpr(*this, ME))
+    return tryEmitAsConstant(DRE);
+  return ConstantEmission();
+}
+
 llvm::Value *CodeGenFunction::EmitLoadOfScalar(LValue lvalue,
                                                SourceLocation Loc) {
   return EmitLoadOfScalar(lvalue.getAddress(), lvalue.isVolatile(),
@@ -2268,7 +2304,9 @@
         !(E->refersToEnclosingVariableOrCapture() && CapturedStmtInfo &&
           LocalDeclMap.count(VD))) {
       llvm::Constant *Val =
-        CGM.EmitConstantValue(*VD->evaluateValue(), VD->getType(), this);
+        ConstantEmitter(*this).emitAbstract(E->getLocation(),
+                                            *VD->evaluateValue(),
+                                            VD->getType());
       assert(Val && "failed to emit reference constant expression");
       // FIXME: Eventually we will want to emit vector element references.
 
@@ -2685,13 +2723,16 @@
   assert(IsFatal || RecoverKind != CheckRecoverableKind::Unrecoverable);
   bool NeedsAbortSuffix =
       IsFatal && RecoverKind != CheckRecoverableKind::Unrecoverable;
+  bool MinimalRuntime = CGF.CGM.getCodeGenOpts().SanitizeMinimalRuntime;
   const SanitizerHandlerInfo &CheckInfo = SanitizerHandlers[CheckHandler];
   const StringRef CheckName = CheckInfo.Name;
-  std::string FnName =
-      ("__ubsan_handle_" + CheckName +
-       (CheckInfo.Version ? "_v" + llvm::utostr(CheckInfo.Version) : "") +
-       (NeedsAbortSuffix ? "_abort" : ""))
-          .str();
+  std::string FnName = "__ubsan_handle_" + CheckName.str();
+  if (CheckInfo.Version && !MinimalRuntime)
+    FnName += "_v" + llvm::utostr(CheckInfo.Version);
+  if (MinimalRuntime)
+    FnName += "_minimal";
+  if (NeedsAbortSuffix)
+    FnName += "_abort";
   bool MayReturn =
       !IsFatal || RecoverKind == CheckRecoverableKind::AlwaysRecoverable;
 
@@ -2778,24 +2819,26 @@
   // representing operand values.
   SmallVector<llvm::Value *, 4> Args;
   SmallVector<llvm::Type *, 4> ArgTypes;
-  Args.reserve(DynamicArgs.size() + 1);
-  ArgTypes.reserve(DynamicArgs.size() + 1);
+  if (!CGM.getCodeGenOpts().SanitizeMinimalRuntime) {
+    Args.reserve(DynamicArgs.size() + 1);
+    ArgTypes.reserve(DynamicArgs.size() + 1);
 
-  // Emit handler arguments and create handler function type.
-  if (!StaticArgs.empty()) {
-    llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
-    auto *InfoPtr =
-        new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
-                                 llvm::GlobalVariable::PrivateLinkage, Info);
-    InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
-    CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
-    Args.push_back(Builder.CreateBitCast(InfoPtr, Int8PtrTy));
-    ArgTypes.push_back(Int8PtrTy);
-  }
+    // Emit handler arguments and create handler function type.
+    if (!StaticArgs.empty()) {
+      llvm::Constant *Info = llvm::ConstantStruct::getAnon(StaticArgs);
+      auto *InfoPtr =
+          new llvm::GlobalVariable(CGM.getModule(), Info->getType(), false,
+                                   llvm::GlobalVariable::PrivateLinkage, Info);
+      InfoPtr->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
+      CGM.getSanitizerMetadata()->disableSanitizerForGlobal(InfoPtr);
+      Args.push_back(Builder.CreateBitCast(InfoPtr, Int8PtrTy));
+      ArgTypes.push_back(Int8PtrTy);
+    }
 
-  for (size_t i = 0, n = DynamicArgs.size(); i != n; ++i) {
-    Args.push_back(EmitCheckValue(DynamicArgs[i]));
-    ArgTypes.push_back(IntPtrTy);
+    for (size_t i = 0, n = DynamicArgs.size(); i != n; ++i) {
+      Args.push_back(EmitCheckValue(DynamicArgs[i]));
+      ArgTypes.push_back(IntPtrTy);
+    }
   }
 
   llvm::FunctionType *FnType =
@@ -3520,6 +3563,11 @@
 }
 
 LValue CodeGenFunction::EmitMemberExpr(const MemberExpr *E) {
+  if (DeclRefExpr *DRE = tryToConvertMemberExprToDeclRefExpr(*this, E)) {
+    EmitIgnoredExpr(E->getBase());
+    return EmitDeclRefLValue(DRE);
+  }
+
   Expr *BaseExpr = E->getBase();
   // If this is s.x, emit s as an lvalue.  If it is s->x, emit s as a scalar.
   LValue BaseLV;
@@ -3546,9 +3594,6 @@
     return LV;
   }
 
-  if (auto *VD = dyn_cast<VarDecl>(ND))
-    return EmitGlobalVarDeclLValue(*this, E, VD);
-
   if (const auto *FD = dyn_cast<FunctionDecl>(ND))
     return EmitFunctionDeclLValue(*this, E, FD);
 
@@ -4363,10 +4408,7 @@
       SanitizerScope SanScope(this);
       llvm::Constant *FTRTTIConst =
           CGM.GetAddrOfRTTIDescriptor(QualType(FnType, 0), /*ForEH=*/true);
-      llvm::Type *PrefixStructTyElems[] = {
-        PrefixSig->getType(),
-        FTRTTIConst->getType()
-      };
+      llvm::Type *PrefixStructTyElems[] = {PrefixSig->getType(), Int32Ty};
       llvm::StructType *PrefixStructTy = llvm::StructType::get(
           CGM.getLLVMContext(), PrefixStructTyElems, /*isPacked=*/true);
 
@@ -4387,8 +4429,10 @@
       EmitBlock(TypeCheck);
       llvm::Value *CalleeRTTIPtr =
           Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, 0, 1);
-      llvm::Value *CalleeRTTI =
+      llvm::Value *CalleeRTTIEncoded =
           Builder.CreateAlignedLoad(CalleeRTTIPtr, getPointerAlign());
+      llvm::Value *CalleeRTTI =
+          DecodeAddrUsedInPrologue(CalleePtr, CalleeRTTIEncoded);
       llvm::Value *CalleeRTTIMatch =
           Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst);
       llvm::Constant *StaticData[] = {
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index a05a088..1ab8433 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -124,24 +124,7 @@
   }
 
   // l-values.
-  void VisitDeclRefExpr(DeclRefExpr *E) {
-    // For aggregates, we should always be able to emit the variable
-    // as an l-value unless it's a reference.  This is due to the fact
-    // that we can't actually ever see a normal l2r conversion on an
-    // aggregate in C++, and in C there's no language standard
-    // actively preventing us from listing variables in the captures
-    // list of a block.
-    if (E->getDecl()->getType()->isReferenceType()) {
-      if (CodeGenFunction::ConstantEmission result
-            = CGF.tryEmitAsConstant(E)) {
-        EmitFinalDestCopy(E->getType(), result.getReferenceLValue(CGF, E));
-        return;
-      }
-    }
-
-    EmitAggLoadOfLValue(E);
-  }
-
+  void VisitDeclRefExpr(DeclRefExpr *E) { EmitAggLoadOfLValue(E); }
   void VisitMemberExpr(MemberExpr *ME) { EmitAggLoadOfLValue(ME); }
   void VisitUnaryDeref(UnaryOperator *E) { EmitAggLoadOfLValue(E); }
   void VisitStringLiteral(StringLiteral *E) { EmitAggLoadOfLValue(E); }
diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp
index ab17024..8ee236d 100644
--- a/lib/CodeGen/CGExprCXX.cpp
+++ b/lib/CodeGen/CGExprCXX.cpp
@@ -16,6 +16,7 @@
 #include "CGCXXABI.h"
 #include "CGDebugInfo.h"
 #include "CGObjCRuntime.h"
+#include "ConstantEmitter.h"
 #include "clang/CodeGen/CGFunctionInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/IR/CallSite.h"
@@ -681,8 +682,8 @@
   // Emit the array size expression.
   // We multiply the size of all dimensions for NumElements.
   // e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.
-  numElements = CGF.CGM.EmitConstantExpr(e->getArraySize(),
-                                         CGF.getContext().getSizeType(), &CGF);
+  numElements =
+    ConstantEmitter(CGF).tryEmitAbstract(e->getArraySize(), e->getType());
   if (!numElements)
     numElements = CGF.EmitScalarExpr(e->getArraySize());
   assert(isa<llvm::IntegerType>(numElements->getType()));
diff --git a/lib/CodeGen/CGExprComplex.cpp b/lib/CodeGen/CGExprComplex.cpp
index 9809723..f019e35 100644
--- a/lib/CodeGen/CGExprComplex.cpp
+++ b/lib/CodeGen/CGExprComplex.cpp
@@ -120,18 +120,22 @@
     return Visit(E->getSubExpr());
   }
 
+  ComplexPairTy emitConstant(const CodeGenFunction::ConstantEmission &Constant,
+                             Expr *E) {
+    assert(Constant && "not a constant");
+    if (Constant.isReference())
+      return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E),
+                              E->getExprLoc());
+
+    llvm::Constant *pair = Constant.getValue();
+    return ComplexPairTy(pair->getAggregateElement(0U),
+                         pair->getAggregateElement(1U));
+  }
 
   // l-values.
   ComplexPairTy VisitDeclRefExpr(DeclRefExpr *E) {
-    if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
-      if (result.isReference())
-        return EmitLoadOfLValue(result.getReferenceLValue(CGF, E),
-                                E->getExprLoc());
-
-      llvm::Constant *pair = result.getValue();
-      return ComplexPairTy(pair->getAggregateElement(0U),
-                           pair->getAggregateElement(1U));
-    }
+    if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E))
+      return emitConstant(Constant, E);
     return EmitLoadOfLValue(E);
   }
   ComplexPairTy VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
@@ -141,7 +145,14 @@
     return CGF.EmitObjCMessageExpr(E).getComplexVal();
   }
   ComplexPairTy VisitArraySubscriptExpr(Expr *E) { return EmitLoadOfLValue(E); }
-  ComplexPairTy VisitMemberExpr(const Expr *E) { return EmitLoadOfLValue(E); }
+  ComplexPairTy VisitMemberExpr(MemberExpr *ME) {
+    if (CodeGenFunction::ConstantEmission Constant =
+            CGF.tryEmitAsConstant(ME)) {
+      CGF.EmitIgnoredExpr(ME->getBase());
+      return emitConstant(Constant, ME);
+    }
+    return EmitLoadOfLValue(ME);
+  }
   ComplexPairTy VisitOpaqueValueExpr(OpaqueValueExpr *E) {
     if (E->isGLValue())
       return EmitLoadOfLValue(CGF.getOpaqueLValueMapping(E), E->getExprLoc());
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 6b72774..7262ba6 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -16,6 +16,7 @@
 #include "CGObjCRuntime.h"
 #include "CGRecordLayout.h"
 #include "CodeGenModule.h"
+#include "ConstantEmitter.h"
 #include "TargetInfo.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
@@ -37,25 +38,26 @@
 class ConstExprEmitter;
 class ConstStructBuilder {
   CodeGenModule &CGM;
-  CodeGenFunction *CGF;
+  ConstantEmitter &Emitter;
 
   bool Packed;
   CharUnits NextFieldOffsetInChars;
   CharUnits LLVMStructAlignment;
   SmallVector<llvm::Constant *, 32> Elements;
 public:
-  static llvm::Constant *BuildStruct(CodeGenModule &CGM, CodeGenFunction *CFG,
-                                     ConstExprEmitter *Emitter,
+  static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
+                                     ConstExprEmitter *ExprEmitter,
                                      llvm::ConstantStruct *Base,
-                                     InitListExpr *Updater);
-  static llvm::Constant *BuildStruct(CodeGenModule &CGM, CodeGenFunction *CGF,
-                                     InitListExpr *ILE);
-  static llvm::Constant *BuildStruct(CodeGenModule &CGM, CodeGenFunction *CGF,
+                                     InitListExpr *Updater,
+                                     QualType ValTy);
+  static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
+                                     InitListExpr *ILE, QualType StructTy);
+  static llvm::Constant *BuildStruct(ConstantEmitter &Emitter,
                                      const APValue &Value, QualType ValTy);
 
 private:
-  ConstStructBuilder(CodeGenModule &CGM, CodeGenFunction *CGF)
-    : CGM(CGM), CGF(CGF), Packed(false), 
+  ConstStructBuilder(ConstantEmitter &emitter)
+    : CGM(emitter.CGM), Emitter(emitter), Packed(false), 
     NextFieldOffsetInChars(CharUnits::Zero()),
     LLVMStructAlignment(CharUnits::One()) { }
 
@@ -76,7 +78,7 @@
   bool Build(InitListExpr *ILE);
   bool Build(ConstExprEmitter *Emitter, llvm::ConstantStruct *Base,
              InitListExpr *Updater);
-  void Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
+  bool Build(const APValue &Val, const RecordDecl *RD, bool IsPrimaryBase,
              const CXXRecordDecl *VTableClass, CharUnits BaseOffset);
   llvm::Constant *Finalize(QualType Ty);
 
@@ -391,10 +393,10 @@
     // we just use explicit null values for them.
     llvm::Constant *EltInit;
     if (ElementNo < ILE->getNumInits())
-      EltInit = CGM.EmitConstantExpr(ILE->getInit(ElementNo++),
-                                     Field->getType(), CGF);
+      EltInit = Emitter.tryEmitPrivateForMemory(ILE->getInit(ElementNo++),
+                                                Field->getType());
     else
-      EltInit = CGM.EmitNullConstant(Field->getType());
+      EltInit = Emitter.emitNullForMemory(Field->getType());
 
     if (!EltInit)
       return false;
@@ -431,7 +433,7 @@
 };
 }
 
-void ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
+bool ConstStructBuilder::Build(const APValue &Val, const RecordDecl *RD,
                                bool IsPrimaryBase,
                                const CXXRecordDecl *VTableClass,
                                CharUnits Offset) {
@@ -486,8 +488,9 @@
     const APValue &FieldValue =
       RD->isUnion() ? Val.getUnionValue() : Val.getStructField(FieldNo);
     llvm::Constant *EltInit =
-      CGM.EmitConstantValueForMemory(FieldValue, Field->getType(), CGF);
-    assert(EltInit && "EmitConstantValue can't fail");
+      Emitter.tryEmitPrivateForMemory(FieldValue, Field->getType());
+    if (!EltInit)
+      return false;
 
     if (!Field->isBitField()) {
       // Handle non-bitfield members.
@@ -498,6 +501,8 @@
                      cast<llvm::ConstantInt>(EltInit));
     }
   }
+
+  return true;
 }
 
 llvm::Constant *ConstStructBuilder::Finalize(QualType Ty) {
@@ -559,37 +564,37 @@
   return Result;
 }
 
-llvm::Constant *ConstStructBuilder::BuildStruct(CodeGenModule &CGM,
-                                                CodeGenFunction *CGF,
-                                                ConstExprEmitter *Emitter,
+llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
+                                                ConstExprEmitter *ExprEmitter,
                                                 llvm::ConstantStruct *Base,
-                                                InitListExpr *Updater) {
-  ConstStructBuilder Builder(CGM, CGF);
-  if (!Builder.Build(Emitter, Base, Updater))
+                                                InitListExpr *Updater,
+                                                QualType ValTy) {
+  ConstStructBuilder Builder(Emitter);
+  if (!Builder.Build(ExprEmitter, Base, Updater))
     return nullptr;
-  return Builder.Finalize(Updater->getType());
+  return Builder.Finalize(ValTy);
 }
 
-llvm::Constant *ConstStructBuilder::BuildStruct(CodeGenModule &CGM,
-                                                CodeGenFunction *CGF,
-                                                InitListExpr *ILE) {
-  ConstStructBuilder Builder(CGM, CGF);
+llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
+                                                InitListExpr *ILE,
+                                                QualType ValTy) {
+  ConstStructBuilder Builder(Emitter);
 
   if (!Builder.Build(ILE))
     return nullptr;
 
-  return Builder.Finalize(ILE->getType());
+  return Builder.Finalize(ValTy);
 }
 
-llvm::Constant *ConstStructBuilder::BuildStruct(CodeGenModule &CGM,
-                                                CodeGenFunction *CGF,
+llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
                                                 const APValue &Val,
                                                 QualType ValTy) {
-  ConstStructBuilder Builder(CGM, CGF);
+  ConstStructBuilder Builder(Emitter);
 
   const RecordDecl *RD = ValTy->castAs<RecordType>()->getDecl();
   const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
-  Builder.Build(Val, RD, false, CD, CharUnits::Zero());
+  if (!Builder.Build(Val, RD, false, CD, CharUnits::Zero()))
+    return nullptr;
 
   return Builder.Finalize(ValTy);
 }
@@ -599,57 +604,86 @@
 //                             ConstExprEmitter
 //===----------------------------------------------------------------------===//
 
+static ConstantAddress tryEmitGlobalCompoundLiteral(CodeGenModule &CGM,
+                                                    CodeGenFunction *CGF,
+                                              const CompoundLiteralExpr *E) {
+  CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
+  if (llvm::GlobalVariable *Addr =
+          CGM.getAddrOfConstantCompoundLiteralIfEmitted(E))
+    return ConstantAddress(Addr, Align);
+
+  unsigned addressSpace = E->getType().getAddressSpace();
+
+  ConstantEmitter emitter(CGM, CGF);
+  llvm::Constant *C = emitter.tryEmitForInitializer(E->getInitializer(),
+                                                    addressSpace, E->getType());
+  if (!C) {
+    assert(!E->isFileScope() &&
+           "file-scope compound literal did not have constant initializer!");
+    return ConstantAddress::invalid();
+  }
+
+  auto GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
+                                     CGM.isTypeConstant(E->getType(), true),
+                                     llvm::GlobalValue::InternalLinkage,
+                                     C, ".compoundliteral", nullptr,
+                                     llvm::GlobalVariable::NotThreadLocal,
+                    CGM.getContext().getTargetAddressSpace(addressSpace));
+  emitter.finalize(GV);
+  GV->setAlignment(Align.getQuantity());
+  CGM.setAddrOfConstantCompoundLiteral(E, GV);
+  return ConstantAddress(GV, Align);
+}
+
 /// This class only needs to handle two cases:
 /// 1) Literals (this is used by APValue emission to emit literals).
 /// 2) Arrays, structs and unions (outside C++11 mode, we don't currently
 ///    constant fold these types).
 class ConstExprEmitter :
-  public StmtVisitor<ConstExprEmitter, llvm::Constant*> {
+  public StmtVisitor<ConstExprEmitter, llvm::Constant*, QualType> {
   CodeGenModule &CGM;
-  CodeGenFunction *CGF;
+  ConstantEmitter &Emitter;
   llvm::LLVMContext &VMContext;
 public:
-  ConstExprEmitter(CodeGenModule &cgm, CodeGenFunction *cgf)
-    : CGM(cgm), CGF(cgf), VMContext(cgm.getLLVMContext()) {
+  ConstExprEmitter(ConstantEmitter &emitter)
+    : CGM(emitter.CGM), Emitter(emitter), VMContext(CGM.getLLVMContext()) {
   }
 
   //===--------------------------------------------------------------------===//
   //                            Visitor Methods
   //===--------------------------------------------------------------------===//
 
-  llvm::Constant *VisitStmt(Stmt *S) {
+  llvm::Constant *VisitStmt(Stmt *S, QualType T) {
     return nullptr;
   }
 
-  llvm::Constant *VisitParenExpr(ParenExpr *PE) {
-    return Visit(PE->getSubExpr());
+  llvm::Constant *VisitParenExpr(ParenExpr *PE, QualType T) {
+    return Visit(PE->getSubExpr(), T);
   }
 
   llvm::Constant *
-  VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE) {
-    return Visit(PE->getReplacement());
+  VisitSubstNonTypeTemplateParmExpr(SubstNonTypeTemplateParmExpr *PE,
+                                    QualType T) {
+    return Visit(PE->getReplacement(), T);
   }
 
-  llvm::Constant *VisitGenericSelectionExpr(GenericSelectionExpr *GE) {
-    return Visit(GE->getResultExpr());
+  llvm::Constant *VisitGenericSelectionExpr(GenericSelectionExpr *GE,
+                                            QualType T) {
+    return Visit(GE->getResultExpr(), T);
   }
 
-  llvm::Constant *VisitChooseExpr(ChooseExpr *CE) {
-    return Visit(CE->getChosenSubExpr());
+  llvm::Constant *VisitChooseExpr(ChooseExpr *CE, QualType T) {
+    return Visit(CE->getChosenSubExpr(), T);
   }
 
-  llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) {
-    return Visit(E->getInitializer());
+  llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E, QualType T) {
+    return Visit(E->getInitializer(), T);
   }
 
-  llvm::Constant *VisitCastExpr(CastExpr* E) {
+  llvm::Constant *VisitCastExpr(CastExpr *E, QualType destType) {
     if (const auto *ECE = dyn_cast<ExplicitCastExpr>(E))
-      CGM.EmitExplicitCastExprType(ECE, CGF);
+      CGM.EmitExplicitCastExprType(ECE, Emitter.CGF);
     Expr *subExpr = E->getSubExpr();
-    llvm::Constant *C = CGM.EmitConstantExpr(subExpr, subExpr->getType(), CGF);
-    if (!C) return nullptr;
-
-    llvm::Type *destType = ConvertType(E->getType());
 
     switch (E->getCastKind()) {
     case CK_ToUnion: {
@@ -657,14 +691,22 @@
       assert(E->getType()->isUnionType() &&
              "Destination type is not union type!");
 
+      auto field = E->getTargetUnionField();
+
+      auto C = Emitter.tryEmitPrivateForMemory(subExpr, field->getType());
+      if (!C) return nullptr;
+
+      auto destTy = ConvertType(destType);
+      if (C->getType() == destTy) return C;
+
       // Build a struct with the union sub-element as the first member,
-      // and padded to the appropriate size
+      // and padded to the appropriate size.
       SmallVector<llvm::Constant*, 2> Elts;
       SmallVector<llvm::Type*, 2> Types;
       Elts.push_back(C);
       Types.push_back(C->getType());
       unsigned CurSize = CGM.getDataLayout().getTypeAllocSize(C->getType());
-      unsigned TotalSize = CGM.getDataLayout().getTypeAllocSize(destType);
+      unsigned TotalSize = CGM.getDataLayout().getTypeAllocSize(destTy);
 
       assert(CurSize <= TotalSize && "Union size mismatch!");
       if (unsigned NumPadBytes = TotalSize - CurSize) {
@@ -676,20 +718,26 @@
         Types.push_back(Ty);
       }
 
-      llvm::StructType* STy =
-        llvm::StructType::get(C->getType()->getContext(), Types, false);
+      llvm::StructType *STy = llvm::StructType::get(VMContext, Types, false);
       return llvm::ConstantStruct::get(STy, Elts);
     }
 
-    case CK_AddressSpaceConversion:
-      return llvm::ConstantExpr::getAddrSpaceCast(C, destType);
+    case CK_AddressSpaceConversion: {
+      auto C = Emitter.tryEmitPrivate(subExpr, subExpr->getType());
+      if (!C) return nullptr;
+      unsigned destAS = E->getType()->getPointeeType().getAddressSpace();
+      unsigned srcAS = subExpr->getType()->getPointeeType().getAddressSpace();
+      llvm::Type *destTy = ConvertType(E->getType());
+      return CGM.getTargetCodeGenInfo().performAddrSpaceCast(CGM, C, srcAS,
+                                                             destAS, destTy);
+    }
 
     case CK_LValueToRValue:
     case CK_AtomicToNonAtomic:
     case CK_NonAtomicToAtomic:
     case CK_NoOp:
     case CK_ConstructorConversion:
-      return C;
+      return Visit(subExpr, destType);
 
     case CK_IntToOCLSampler:
       llvm_unreachable("global sampler variables are not generated");
@@ -701,8 +749,11 @@
 
     case CK_ReinterpretMemberPointer:
     case CK_DerivedToBaseMemberPointer:
-    case CK_BaseToDerivedMemberPointer:
+    case CK_BaseToDerivedMemberPointer: {
+      auto C = Emitter.tryEmitPrivate(subExpr, subExpr->getType());
+      if (!C) return nullptr;
       return CGM.getCXXABI().EmitMemberPointerConversion(E, C);
+    }
 
     // These will never be supported.
     case CK_ObjCObjectLValueCast:
@@ -759,27 +810,28 @@
     llvm_unreachable("Invalid CastKind");
   }
 
-  llvm::Constant *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE) {
-    return Visit(DAE->getExpr());
+  llvm::Constant *VisitCXXDefaultArgExpr(CXXDefaultArgExpr *DAE, QualType T) {
+    return Visit(DAE->getExpr(), T);
   }
 
-  llvm::Constant *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE) {
+  llvm::Constant *VisitCXXDefaultInitExpr(CXXDefaultInitExpr *DIE, QualType T) {
     // No need for a DefaultInitExprScope: we don't handle 'this' in a
     // constant expression.
-    return Visit(DIE->getExpr());
+    return Visit(DIE->getExpr(), T);
   }
 
-  llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E) {
+  llvm::Constant *VisitExprWithCleanups(ExprWithCleanups *E, QualType T) {
     if (!E->cleanupsHaveSideEffects())
-      return Visit(E->getSubExpr());
+      return Visit(E->getSubExpr(), T);
     return nullptr;
   }
 
-  llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
-    return Visit(E->GetTemporaryExpr());
+  llvm::Constant *VisitMaterializeTemporaryExpr(MaterializeTemporaryExpr *E,
+                                                QualType T) {
+    return Visit(E->GetTemporaryExpr(), T);
   }
 
-  llvm::Constant *EmitArrayInitialization(InitListExpr *ILE) {
+  llvm::Constant *EmitArrayInitialization(InitListExpr *ILE, QualType T) {
     llvm::ArrayType *AType =
         cast<llvm::ArrayType>(ConvertType(ILE->getType()));
     llvm::Type *ElemTy = AType->getElementType();
@@ -790,13 +842,14 @@
     // initialise any elements that have not been initialised explicitly
     unsigned NumInitableElts = std::min(NumInitElements, NumElements);
 
+    QualType EltType = CGM.getContext().getAsArrayType(T)->getElementType();
+
     // Initialize remaining array elements.
-    // FIXME: This doesn't handle member pointers correctly!
     llvm::Constant *fillC;
     if (Expr *filler = ILE->getArrayFiller())
-      fillC = CGM.EmitConstantExpr(filler, filler->getType(), CGF);
+      fillC = Emitter.tryEmitAbstractForMemory(filler, EltType);
     else
-      fillC = llvm::Constant::getNullValue(ElemTy);
+      fillC = Emitter.emitNullForMemory(EltType);
     if (!fillC)
       return nullptr;
 
@@ -805,13 +858,13 @@
       return llvm::ConstantAggregateZero::get(AType);
 
     // Copy initializer elements.
-    std::vector<llvm::Constant*> Elts;
+    SmallVector<llvm::Constant*, 16> Elts;
     Elts.reserve(NumInitableElts + NumElements);
 
     bool RewriteType = false;
     for (unsigned i = 0; i < NumInitableElts; ++i) {
       Expr *Init = ILE->getInit(i);
-      llvm::Constant *C = CGM.EmitConstantExpr(Init, Init->getType(), CGF);
+      llvm::Constant *C = Emitter.tryEmitPrivateForMemory(Init, EltType);
       if (!C)
         return nullptr;
       RewriteType |= (C->getType() != ElemTy);
@@ -835,33 +888,33 @@
     return llvm::ConstantArray::get(AType, Elts);
   }
 
-  llvm::Constant *EmitRecordInitialization(InitListExpr *ILE) {
-    return ConstStructBuilder::BuildStruct(CGM, CGF, ILE);
+  llvm::Constant *EmitRecordInitialization(InitListExpr *ILE, QualType T) {
+    return ConstStructBuilder::BuildStruct(Emitter, ILE, T);
   }
 
-  llvm::Constant *VisitImplicitValueInitExpr(ImplicitValueInitExpr* E) {
-    return CGM.EmitNullConstant(E->getType());
+  llvm::Constant *VisitImplicitValueInitExpr(ImplicitValueInitExpr* E,
+                                             QualType T) {
+    return CGM.EmitNullConstant(T);
   }
 
-  llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {
+  llvm::Constant *VisitInitListExpr(InitListExpr *ILE, QualType T) {
     if (ILE->isTransparent())
-      return Visit(ILE->getInit(0));
+      return Visit(ILE->getInit(0), T);
 
     if (ILE->getType()->isArrayType())
-      return EmitArrayInitialization(ILE);
+      return EmitArrayInitialization(ILE, T);
 
     if (ILE->getType()->isRecordType())
-      return EmitRecordInitialization(ILE);
+      return EmitRecordInitialization(ILE, T);
 
     return nullptr;
   }
 
   llvm::Constant *EmitDesignatedInitUpdater(llvm::Constant *Base,
-                                            InitListExpr *Updater) {
-    QualType ExprType = Updater->getType();
-
-    if (ExprType->isArrayType()) {
-      llvm::ArrayType *AType = cast<llvm::ArrayType>(ConvertType(ExprType));
+                                            InitListExpr *Updater,
+                                            QualType destType) {
+    if (auto destAT = CGM.getContext().getAsArrayType(destType)) {
+      llvm::ArrayType *AType = cast<llvm::ArrayType>(ConvertType(destType));
       llvm::Type *ElemType = AType->getElementType();
 
       unsigned NumInitElements = Updater->getNumInits();
@@ -870,12 +923,12 @@
       std::vector<llvm::Constant *> Elts;
       Elts.reserve(NumElements);
 
-      if (llvm::ConstantDataArray *DataArray =
-            dyn_cast<llvm::ConstantDataArray>(Base))
+      QualType destElemType = destAT->getElementType();
+
+      if (auto DataArray = dyn_cast<llvm::ConstantDataArray>(Base))
         for (unsigned i = 0; i != NumElements; ++i)
           Elts.push_back(DataArray->getElementAsConstant(i));
-      else if (llvm::ConstantArray *Array =
-                 dyn_cast<llvm::ConstantArray>(Base))
+      else if (auto Array = dyn_cast<llvm::ConstantArray>(Base))
         for (unsigned i = 0; i != NumElements; ++i)
           Elts.push_back(Array->getOperand(i));
       else
@@ -884,7 +937,7 @@
       llvm::Constant *fillC = nullptr;
       if (Expr *filler = Updater->getArrayFiller())
         if (!isa<NoInitExpr>(filler))
-          fillC = CGM.EmitConstantExpr(filler, filler->getType(), CGF);
+          fillC = Emitter.tryEmitAbstractForMemory(filler, destElemType);
       bool RewriteType = (fillC && fillC->getType() != ElemType);
 
       for (unsigned i = 0; i != NumElements; ++i) {
@@ -897,9 +950,9 @@
         else if (!Init || isa<NoInitExpr>(Init))
           ; // Do nothing.
         else if (InitListExpr *ChildILE = dyn_cast<InitListExpr>(Init))
-          Elts[i] = EmitDesignatedInitUpdater(Elts[i], ChildILE);
+          Elts[i] = EmitDesignatedInitUpdater(Elts[i], ChildILE, destElemType);
         else
-          Elts[i] = CGM.EmitConstantExpr(Init, Init->getType(), CGF);
+          Elts[i] = Emitter.tryEmitPrivateForMemory(Init, destElemType);
  
        if (!Elts[i])
           return nullptr;
@@ -919,25 +972,24 @@
       return llvm::ConstantArray::get(AType, Elts);
     }
 
-    if (ExprType->isRecordType())
-      return ConstStructBuilder::BuildStruct(CGM, CGF, this,
-                 dyn_cast<llvm::ConstantStruct>(Base), Updater);
+    if (destType->isRecordType())
+      return ConstStructBuilder::BuildStruct(Emitter, this,
+                 dyn_cast<llvm::ConstantStruct>(Base), Updater, destType);
 
     return nullptr;
   }
 
-  llvm::Constant *VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E) {
-    return EmitDesignatedInitUpdater(
-               CGM.EmitConstantExpr(E->getBase(), E->getType(), CGF),
-               E->getUpdater());
+  llvm::Constant *VisitDesignatedInitUpdateExpr(DesignatedInitUpdateExpr *E,
+                                                QualType destType) {
+    auto C = Visit(E->getBase(), destType);
+    if (!C) return nullptr;
+    return EmitDesignatedInitUpdater(C, E->getUpdater(), destType);
   }  
 
-  llvm::Constant *VisitCXXConstructExpr(CXXConstructExpr *E) {
+  llvm::Constant *VisitCXXConstructExpr(CXXConstructExpr *E, QualType Ty) {
     if (!E->getConstructor()->isTrivial())
       return nullptr;
 
-    QualType Ty = E->getType();
-
     // FIXME: We should not have to call getBaseElementType here.
     const RecordType *RT = 
       CGM.getContext().getBaseElementType(Ty)->getAs<RecordType>();
@@ -960,26 +1012,23 @@
       assert(CGM.getContext().hasSameUnqualifiedType(Ty, Arg->getType()) &&
              "argument to copy ctor is of wrong type");
 
-      return Visit(Arg);
+      return Visit(Arg, Ty);
     }
 
     return CGM.EmitNullConstant(Ty);
   }
 
-  llvm::Constant *VisitStringLiteral(StringLiteral *E) {
+  llvm::Constant *VisitStringLiteral(StringLiteral *E, QualType T) {
     return CGM.GetConstantArrayFromStringLiteral(E);
   }
 
-  llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+  llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E, QualType T) {
     // This must be an @encode initializing an array in a static initializer.
     // Don't emit it as the address of the string, emit the string data itself
     // as an inline array.
     std::string Str;
     CGM.getContext().getObjCEncodingForType(E->getEncodedType(), Str);
-    QualType T = E->getType();
-    if (T->getTypeClass() == Type::TypeOfExpr)
-      T = cast<TypeOfExprType>(T)->getUnderlyingExpr()->getType();
-    const ConstantArrayType *CAT = cast<ConstantArrayType>(T);
+    const ConstantArrayType *CAT = CGM.getContext().getAsConstantArrayType(T);
 
     // Resize the string to the right size, adding zeros at the end, or
     // truncating as needed.
@@ -987,151 +1036,19 @@
     return llvm::ConstantDataArray::getString(VMContext, Str, false);
   }
 
-  llvm::Constant *VisitUnaryExtension(const UnaryOperator *E) {
-    return Visit(E->getSubExpr());
+  llvm::Constant *VisitUnaryExtension(const UnaryOperator *E, QualType T) {
+    return Visit(E->getSubExpr(), T);
   }
 
   // Utility methods
   llvm::Type *ConvertType(QualType T) {
     return CGM.getTypes().ConvertType(T);
   }
-
-public:
-  ConstantAddress EmitLValue(APValue::LValueBase LVBase) {
-    if (const ValueDecl *Decl = LVBase.dyn_cast<const ValueDecl*>()) {
-      if (Decl->hasAttr<WeakRefAttr>())
-        return CGM.GetWeakRefReference(Decl);
-      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(Decl))
-        return ConstantAddress(CGM.GetAddrOfFunction(FD), CharUnits::One());
-      if (const VarDecl* VD = dyn_cast<VarDecl>(Decl)) {
-        // We can never refer to a variable with local storage.
-        if (!VD->hasLocalStorage()) {
-          CharUnits Align = CGM.getContext().getDeclAlign(VD);
-          if (VD->isFileVarDecl() || VD->hasExternalStorage())
-            return ConstantAddress(CGM.GetAddrOfGlobalVar(VD), Align);
-          else if (VD->isLocalVarDecl()) {
-            auto Ptr = CGM.getOrCreateStaticVarDecl(
-                *VD, CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false));
-            return ConstantAddress(Ptr, Align);
-          }
-        }
-      }
-      return ConstantAddress::invalid();
-    }
-
-    Expr *E = const_cast<Expr*>(LVBase.get<const Expr*>());
-    switch (E->getStmtClass()) {
-    default: break;
-    case Expr::CompoundLiteralExprClass: {
-      CompoundLiteralExpr *CLE = cast<CompoundLiteralExpr>(E);
-      CharUnits Align = CGM.getContext().getTypeAlignInChars(E->getType());
-      if (llvm::GlobalVariable *Addr =
-              CGM.getAddrOfConstantCompoundLiteralIfEmitted(CLE))
-        return ConstantAddress(Addr, Align);
-
-      llvm::Constant* C = CGM.EmitConstantExpr(CLE->getInitializer(),
-                                               CLE->getType(), CGF);
-      // FIXME: "Leaked" on failure.
-      if (!C) return ConstantAddress::invalid();
-
-      auto GV = new llvm::GlobalVariable(CGM.getModule(), C->getType(),
-                                     E->getType().isConstant(CGM.getContext()),
-                                     llvm::GlobalValue::InternalLinkage,
-                                     C, ".compoundliteral", nullptr,
-                                     llvm::GlobalVariable::NotThreadLocal,
-                          CGM.getContext().getTargetAddressSpace(E->getType()));
-      GV->setAlignment(Align.getQuantity());
-      CGM.setAddrOfConstantCompoundLiteral(CLE, GV);
-      return ConstantAddress(GV, Align);
-    }
-    case Expr::StringLiteralClass:
-      return CGM.GetAddrOfConstantStringFromLiteral(cast<StringLiteral>(E));
-    case Expr::ObjCEncodeExprClass:
-      return CGM.GetAddrOfConstantStringFromObjCEncode(cast<ObjCEncodeExpr>(E));
-    case Expr::ObjCStringLiteralClass: {
-      ObjCStringLiteral* SL = cast<ObjCStringLiteral>(E);
-      ConstantAddress C =
-          CGM.getObjCRuntime().GenerateConstantString(SL->getString());
-      return C.getElementBitCast(ConvertType(E->getType()));
-    }
-    case Expr::PredefinedExprClass: {
-      unsigned Type = cast<PredefinedExpr>(E)->getIdentType();
-      if (CGF) {
-        LValue Res = CGF->EmitPredefinedLValue(cast<PredefinedExpr>(E));
-        return cast<ConstantAddress>(Res.getAddress());
-      } else if (Type == PredefinedExpr::PrettyFunction) {
-        return CGM.GetAddrOfConstantCString("top level", ".tmp");
-      }
-
-      return CGM.GetAddrOfConstantCString("", ".tmp");
-    }
-    case Expr::AddrLabelExprClass: {
-      assert(CGF && "Invalid address of label expression outside function.");
-      llvm::Constant *Ptr =
-        CGF->GetAddrOfLabel(cast<AddrLabelExpr>(E)->getLabel());
-      Ptr = llvm::ConstantExpr::getBitCast(Ptr, ConvertType(E->getType()));
-      return ConstantAddress(Ptr, CharUnits::One());
-    }
-    case Expr::CallExprClass: {
-      CallExpr* CE = cast<CallExpr>(E);
-      unsigned builtin = CE->getBuiltinCallee();
-      if (builtin !=
-            Builtin::BI__builtin___CFStringMakeConstantString &&
-          builtin !=
-            Builtin::BI__builtin___NSStringMakeConstantString)
-        break;
-      const Expr *Arg = CE->getArg(0)->IgnoreParenCasts();
-      const StringLiteral *Literal = cast<StringLiteral>(Arg);
-      if (builtin ==
-            Builtin::BI__builtin___NSStringMakeConstantString) {
-        return CGM.getObjCRuntime().GenerateConstantString(Literal);
-      }
-      // FIXME: need to deal with UCN conversion issues.
-      return CGM.GetAddrOfConstantCFString(Literal);
-    }
-    case Expr::BlockExprClass: {
-      StringRef FunctionName;
-      if (CGF)
-        FunctionName = CGF->CurFn->getName();
-      else
-        FunctionName = "global";
-
-      // This is not really an l-value.
-      llvm::Constant *Ptr =
-        CGM.GetAddrOfGlobalBlock(cast<BlockExpr>(E), FunctionName);
-      return ConstantAddress(Ptr, CGM.getPointerAlign());
-    }
-    case Expr::CXXTypeidExprClass: {
-      CXXTypeidExpr *Typeid = cast<CXXTypeidExpr>(E);
-      QualType T;
-      if (Typeid->isTypeOperand())
-        T = Typeid->getTypeOperand(CGM.getContext());
-      else
-        T = Typeid->getExprOperand()->getType();
-      return ConstantAddress(CGM.GetAddrOfRTTIDescriptor(T),
-                             CGM.getPointerAlign());
-    }
-    case Expr::CXXUuidofExprClass: {
-      return CGM.GetAddrOfUuidDescriptor(cast<CXXUuidofExpr>(E));
-    }
-    case Expr::MaterializeTemporaryExprClass: {
-      MaterializeTemporaryExpr *MTE = cast<MaterializeTemporaryExpr>(E);
-      assert(MTE->getStorageDuration() == SD_Static);
-      SmallVector<const Expr *, 2> CommaLHSs;
-      SmallVector<SubobjectAdjustment, 2> Adjustments;
-      const Expr *Inner = MTE->GetTemporaryExpr()
-          ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
-      return CGM.GetAddrOfGlobalTemporary(MTE, Inner);
-    }
-    }
-
-    return ConstantAddress::invalid();
-  }
 };
 
 }  // end anonymous namespace.
 
-bool ConstStructBuilder::Build(ConstExprEmitter *Emitter,
+bool ConstStructBuilder::Build(ConstExprEmitter *ExprEmitter,
                                llvm::ConstantStruct *Base,
                                InitListExpr *Updater) {
   assert(Base && "base expression should not be empty");
@@ -1179,9 +1096,10 @@
     if (!Init || isa<NoInitExpr>(Init))
       ; // Do nothing.
     else if (InitListExpr *ChildILE = dyn_cast<InitListExpr>(Init))
-      EltInit = Emitter->EmitDesignatedInitUpdater(EltInit, ChildILE);
+      EltInit = ExprEmitter->EmitDesignatedInitUpdater(EltInit, ChildILE,
+                                                       Field->getType());
     else
-      EltInit = CGM.EmitConstantExpr(Init, Field->getType(), CGF);
+      EltInit = Emitter.tryEmitPrivateForMemory(Init, Field->getType());
 
     ++ElementNo;
 
@@ -1200,26 +1118,294 @@
   return true;
 }
 
-llvm::Constant *CodeGenModule::EmitConstantInit(const VarDecl &D,
-                                                CodeGenFunction *CGF) {
+llvm::Constant *ConstantEmitter::validateAndPopAbstract(llvm::Constant *C,
+                                                        AbstractState saved) {
+  Abstract = saved.OldValue;
+
+  assert(saved.OldPlaceholdersSize == PlaceholderAddresses.size() &&
+         "created a placeholder while doing an abstract emission?");
+
+  // No validation necessary for now.
+  // No cleanup to do for now.
+  return C;
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstractForInitializer(const VarDecl &D) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivateForVarInit(D);
+  return validateAndPopAbstract(C, state);
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstract(const Expr *E, QualType destType) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivate(E, destType);
+  return validateAndPopAbstract(C, state);
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstract(const APValue &value, QualType destType) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivate(value, destType);
+  return validateAndPopAbstract(C, state);
+}
+
+llvm::Constant *
+ConstantEmitter::emitAbstract(const Expr *E, QualType destType) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivate(E, destType);
+  C = validateAndPopAbstract(C, state);
+  if (!C) {
+    CGM.Error(E->getExprLoc(),
+              "internal error: could not emit constant value \"abstractly\"");
+    C = CGM.EmitNullConstant(destType);
+  }
+  return C;
+}
+
+llvm::Constant *
+ConstantEmitter::emitAbstract(SourceLocation loc, const APValue &value,
+                              QualType destType) {
+  auto state = pushAbstract();
+  auto C = tryEmitPrivate(value, destType);
+  C = validateAndPopAbstract(C, state);
+  if (!C) {
+    CGM.Error(loc,
+              "internal error: could not emit constant value \"abstractly\"");
+    C = CGM.EmitNullConstant(destType);
+  }
+  return C;
+}
+
+llvm::Constant *ConstantEmitter::tryEmitForInitializer(const VarDecl &D) {
+  initializeNonAbstract(D.getType().getAddressSpace());
+  return markIfFailed(tryEmitPrivateForVarInit(D));
+}
+
+llvm::Constant *ConstantEmitter::tryEmitForInitializer(const Expr *E,
+                                                       unsigned destAddrSpace,
+                                                       QualType destType) {
+  initializeNonAbstract(destAddrSpace);
+  return markIfFailed(tryEmitPrivateForMemory(E, destType));
+}
+
+llvm::Constant *ConstantEmitter::emitForInitializer(const APValue &value,
+                                                    unsigned destAddrSpace,
+                                                    QualType destType) {
+  initializeNonAbstract(destAddrSpace);
+  auto C = tryEmitPrivateForMemory(value, destType);
+  assert(C && "couldn't emit constant value non-abstractly?");
+  return C;
+}
+
+llvm::GlobalValue *ConstantEmitter::getCurrentAddrPrivate() {
+  assert(!Abstract && "cannot get current address for abstract constant");
+
+
+
+  // Make an obviously ill-formed global that should blow up compilation
+  // if it survives.
+  auto global = new llvm::GlobalVariable(CGM.getModule(), CGM.Int8Ty, true,
+                                         llvm::GlobalValue::PrivateLinkage,
+                                         /*init*/ nullptr,
+                                         /*name*/ "",
+                                         /*before*/ nullptr,
+                                         llvm::GlobalVariable::NotThreadLocal,
+                                         CGM.getContext().getTargetAddressSpace(DestAddressSpace));
+
+  PlaceholderAddresses.push_back(std::make_pair(nullptr, global));
+
+  return global;
+}
+
+void ConstantEmitter::registerCurrentAddrPrivate(llvm::Constant *signal,
+                                           llvm::GlobalValue *placeholder) {
+  assert(!PlaceholderAddresses.empty());
+  assert(PlaceholderAddresses.back().first == nullptr);
+  assert(PlaceholderAddresses.back().second == placeholder);
+  PlaceholderAddresses.back().first = signal;
+}
+
+namespace {
+  struct ReplacePlaceholders {
+    CodeGenModule &CGM;
+
+    /// The base address of the global.
+    llvm::Constant *Base;
+    llvm::Type *BaseValueTy = nullptr;
+
+    /// The placeholder addresses that were registered during emission.
+    llvm::DenseMap<llvm::Constant*, llvm::GlobalVariable*> PlaceholderAddresses;
+
+    /// The locations of the placeholder signals.
+    llvm::DenseMap<llvm::GlobalVariable*, llvm::Constant*> Locations;
+
+    /// The current index stack.  We use a simple unsigned stack because
+    /// we assume that placeholders will be relatively sparse in the
+    /// initializer, but we cache the index values we find just in case.
+    llvm::SmallVector<unsigned, 8> Indices;
+    llvm::SmallVector<llvm::Constant*, 8> IndexValues;
+
+    ReplacePlaceholders(CodeGenModule &CGM, llvm::Constant *base,
+                        ArrayRef<std::pair<llvm::Constant*,
+                                           llvm::GlobalVariable*>> addresses)
+        : CGM(CGM), Base(base),
+          PlaceholderAddresses(addresses.begin(), addresses.end()) {
+    }
+
+    void replaceInInitializer(llvm::Constant *init) {
+      // Remember the type of the top-most initializer.
+      BaseValueTy = init->getType();
+
+      // Initialize the stack.
+      Indices.push_back(0);
+      IndexValues.push_back(nullptr);
+
+      // Recurse into the initializer.
+      findLocations(init);
+
+      // Check invariants.
+      assert(IndexValues.size() == Indices.size() && "mismatch");
+      assert(Indices.size() == 1 && "didn't pop all indices");
+
+      // Do the replacement; this basically invalidates 'init'.
+      assert(Locations.size() == PlaceholderAddresses.size() &&
+             "missed a placeholder?");
+
+      // We're iterating over a hashtable, so this would be a source of
+      // non-determinism in compiler output *except* that we're just
+      // messing around with llvm::Constant structures, which never itself
+      // does anything that should be visible in compiler output.
+      for (auto &entry : Locations) {
+        assert(entry.first->getParent() == nullptr && "not a placeholder!");
+        entry.first->replaceAllUsesWith(entry.second);
+        entry.first->eraseFromParent();
+      }
+    }
+
+  private:
+    void findLocations(llvm::Constant *init) {
+      // Recurse into aggregates.
+      if (auto agg = dyn_cast<llvm::ConstantAggregate>(init)) {
+        for (unsigned i = 0, e = agg->getNumOperands(); i != e; ++i) {
+          Indices.push_back(i);
+          IndexValues.push_back(nullptr);
+
+          findLocations(agg->getOperand(i));
+
+          IndexValues.pop_back();
+          Indices.pop_back();
+        }
+        return;
+      }
+
+      // Otherwise, check for registered constants.
+      while (true) {
+        auto it = PlaceholderAddresses.find(init);
+        if (it != PlaceholderAddresses.end()) {
+          setLocation(it->second);
+          break;
+        }
+
+        // Look through bitcasts or other expressions.
+        if (auto expr = dyn_cast<llvm::ConstantExpr>(init)) {
+          init = expr->getOperand(0);
+        } else {
+          break;
+        }
+      }
+    }
+
+    void setLocation(llvm::GlobalVariable *placeholder) {
+      assert(Locations.find(placeholder) == Locations.end() &&
+             "already found location for placeholder!");
+
+      // Lazily fill in IndexValues with the values from Indices.
+      // We do this in reverse because we should always have a strict
+      // prefix of indices from the start.
+      assert(Indices.size() == IndexValues.size());
+      for (size_t i = Indices.size() - 1; i != size_t(-1); --i) {
+        if (IndexValues[i]) {
+#ifndef NDEBUG
+          for (size_t j = 0; j != i + 1; ++j) {
+            assert(IndexValues[j] &&
+                   isa<llvm::ConstantInt>(IndexValues[j]) &&
+                   cast<llvm::ConstantInt>(IndexValues[j])->getZExtValue()
+                     == Indices[j]);
+          }
+#endif
+          break;
+        }
+
+        IndexValues[i] = llvm::ConstantInt::get(CGM.Int32Ty, Indices[i]);
+      }
+
+      // Form a GEP and then bitcast to the placeholder type so that the
+      // replacement will succeed.
+      llvm::Constant *location =
+        llvm::ConstantExpr::getInBoundsGetElementPtr(BaseValueTy,
+                                                     Base, IndexValues);
+      location = llvm::ConstantExpr::getBitCast(location,
+                                                placeholder->getType());
+
+      Locations.insert({placeholder, location});
+    }
+  };
+}
+
+void ConstantEmitter::finalize(llvm::GlobalVariable *global) {
+  assert(InitializedNonAbstract &&
+         "finalizing emitter that was used for abstract emission?");
+  assert(!Finalized && "finalizing emitter multiple times");
+  assert(global->getInitializer());
+
+  // Note that we might also be Failed.
+  Finalized = true;
+
+  if (!PlaceholderAddresses.empty()) {
+    ReplacePlaceholders(CGM, global, PlaceholderAddresses)
+      .replaceInInitializer(global->getInitializer());
+    PlaceholderAddresses.clear(); // satisfy
+  }
+}
+
+ConstantEmitter::~ConstantEmitter() {
+  assert((!InitializedNonAbstract || Finalized || Failed) &&
+         "not finalized after being initialized for non-abstract emission");
+  assert(PlaceholderAddresses.empty() && "unhandled placeholders");
+}
+
+static QualType getNonMemoryType(CodeGenModule &CGM, QualType type) {
+  if (auto AT = type->getAs<AtomicType>()) {
+    return CGM.getContext().getQualifiedType(AT->getValueType(),
+                                             type.getQualifiers());
+  }
+  return type;
+}
+
+llvm::Constant *ConstantEmitter::tryEmitPrivateForVarInit(const VarDecl &D) {
   // Make a quick check if variable can be default NULL initialized
   // and avoid going through rest of code which may do, for c++11,
   // initialization of memory to all NULLs.
   if (!D.hasLocalStorage()) {
-    QualType Ty = D.getType();
-    if (Ty->isArrayType())
-      Ty = Context.getBaseElementType(Ty);
+    QualType Ty = CGM.getContext().getBaseElementType(D.getType());
     if (Ty->isRecordType())
       if (const CXXConstructExpr *E =
           dyn_cast_or_null<CXXConstructExpr>(D.getInit())) {
         const CXXConstructorDecl *CD = E->getConstructor();
         if (CD->isTrivial() && CD->isDefaultConstructor())
-          return EmitNullConstant(D.getType());
+          return CGM.EmitNullConstant(D.getType());
       }
   }
-  
-  if (const APValue *Value = D.evaluateValue())
-    return EmitConstantValueForMemory(*Value, D.getType(), CGF);
+
+  QualType destType = D.getType();
+
+  // Try to emit the initializer.  Note that this can allow some things that
+  // are not allowed by tryEmitPrivateForMemory alone.
+  if (auto value = D.evaluateValue()) {
+    return tryEmitPrivateForMemory(*value, destType);
+  }
 
   // FIXME: Implement C++11 [basic.start.init]p2: if the initializer of a
   // reference is a constant expression, and the reference binds to a temporary,
@@ -1227,42 +1413,95 @@
   // incorrectly emit a prvalue constant in this case, and the calling code
   // interprets that as the (pointer) value of the reference, rather than the
   // desired value of the referee.
-  if (D.getType()->isReferenceType())
+  if (destType->isReferenceType())
     return nullptr;
 
   const Expr *E = D.getInit();
   assert(E && "No initializer to emit");
 
-  llvm::Constant* C = ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
-  if (C && C->getType()->isIntegerTy(1)) {
-    llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
-    C = llvm::ConstantExpr::getZExt(C, BoolTy);
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  auto C =
+    ConstExprEmitter(*this).Visit(const_cast<Expr*>(E), nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstractForMemory(const Expr *E, QualType destType) {
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  auto C = tryEmitAbstract(E, nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);  
+}
+
+llvm::Constant *
+ConstantEmitter::tryEmitAbstractForMemory(const APValue &value,
+                                          QualType destType) {
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  auto C = tryEmitAbstract(value, nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);  
+}
+
+llvm::Constant *ConstantEmitter::tryEmitPrivateForMemory(const Expr *E,
+                                                         QualType destType) {
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  llvm::Constant *C = tryEmitPrivate(E, nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);
+}
+
+llvm::Constant *ConstantEmitter::tryEmitPrivateForMemory(const APValue &value,
+                                                         QualType destType) {
+  auto nonMemoryDestType = getNonMemoryType(CGM, destType);
+  auto C = tryEmitPrivate(value, nonMemoryDestType);
+  return (C ? emitForMemory(C, destType) : nullptr);
+}
+
+llvm::Constant *ConstantEmitter::emitForMemory(CodeGenModule &CGM,
+                                               llvm::Constant *C,
+                                               QualType destType) {
+  // For an _Atomic-qualified constant, we may need to add tail padding.
+  if (auto AT = destType->getAs<AtomicType>()) {
+    QualType destValueType = AT->getValueType();
+    C = emitForMemory(CGM, C, destValueType);
+
+    uint64_t innerSize = CGM.getContext().getTypeSize(destValueType);
+    uint64_t outerSize = CGM.getContext().getTypeSize(destType);
+    if (innerSize == outerSize)
+      return C;
+
+    assert(innerSize < outerSize && "emitted over-large constant for atomic");
+    llvm::Constant *elts[] = {
+      C,
+      llvm::ConstantAggregateZero::get(
+          llvm::ArrayType::get(CGM.Int8Ty, (outerSize - innerSize) / 8))
+    };
+    return llvm::ConstantStruct::getAnon(elts);
   }
+
+  // Zero-extend bool.
+  if (C->getType()->isIntegerTy(1)) {
+    llvm::Type *boolTy = CGM.getTypes().ConvertTypeForMem(destType);
+    return llvm::ConstantExpr::getZExt(C, boolTy);
+  }
+
   return C;
 }
 
-llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
-                                                QualType DestType,
-                                                CodeGenFunction *CGF) {
+llvm::Constant *ConstantEmitter::tryEmitPrivate(const Expr *E,
+                                                QualType destType) {
   Expr::EvalResult Result;
 
   bool Success = false;
 
-  if (DestType->isReferenceType())
-    Success = E->EvaluateAsLValue(Result, Context);
+  if (destType->isReferenceType())
+    Success = E->EvaluateAsLValue(Result, CGM.getContext());
   else
-    Success = E->EvaluateAsRValue(Result, Context);
+    Success = E->EvaluateAsRValue(Result, CGM.getContext());
 
-  llvm::Constant *C = nullptr;
+  llvm::Constant *C;
   if (Success && !Result.HasSideEffects)
-    C = EmitConstantValue(Result.Val, DestType, CGF);
+    C = tryEmitPrivate(Result.Val, destType);
   else
-    C = ConstExprEmitter(*this, CGF).Visit(const_cast<Expr*>(E));
+    C = ConstExprEmitter(*this).Visit(const_cast<Expr*>(E), destType);
 
-  if (C && C->getType()->isIntegerTy(1)) {
-    llvm::Type *BoolTy = getTypes().ConvertTypeForMem(E->getType());
-    C = llvm::ConstantExpr::getZExt(C, BoolTy);
-  }
   return C;
 }
 
@@ -1270,94 +1509,311 @@
   return getTargetCodeGenInfo().getNullPointer(*this, T, QT);
 }
 
-llvm::Constant *CodeGenModule::EmitConstantValue(const APValue &Value,
-                                                 QualType DestType,
-                                                 CodeGenFunction *CGF) {
-  // For an _Atomic-qualified constant, we may need to add tail padding.
-  if (auto *AT = DestType->getAs<AtomicType>()) {
-    QualType InnerType = AT->getValueType();
-    auto *Inner = EmitConstantValue(Value, InnerType, CGF);
+namespace {
+/// A struct which can be used to peephole certain kinds of finalization
+/// that normally happen during l-value emission.
+struct ConstantLValue {
+  llvm::Constant *Value;
+  bool HasOffsetApplied;
 
-    uint64_t InnerSize = Context.getTypeSize(InnerType);
-    uint64_t OuterSize = Context.getTypeSize(DestType);
-    if (InnerSize == OuterSize)
-      return Inner;
+  /*implicit*/ ConstantLValue(llvm::Constant *value,
+                              bool hasOffsetApplied = false)
+    : Value(value), HasOffsetApplied(false) {}
 
-    assert(InnerSize < OuterSize && "emitted over-large constant for atomic");
-    llvm::Constant *Elts[] = {
-      Inner,
-      llvm::ConstantAggregateZero::get(
-          llvm::ArrayType::get(Int8Ty, (OuterSize - InnerSize) / 8))
-    };
-    return llvm::ConstantStruct::getAnon(Elts);
+  /*implicit*/ ConstantLValue(ConstantAddress address)
+    : ConstantLValue(address.getPointer()) {}
+};
+
+/// A helper class for emitting constant l-values.
+class ConstantLValueEmitter : public ConstStmtVisitor<ConstantLValueEmitter,
+                                                      ConstantLValue> {
+  CodeGenModule &CGM;
+  ConstantEmitter &Emitter;
+  const APValue &Value;
+  QualType DestType;
+
+  // Befriend StmtVisitorBase so that we don't have to expose Visit*.
+  friend StmtVisitorBase;
+
+public:
+  ConstantLValueEmitter(ConstantEmitter &emitter, const APValue &value,
+                        QualType destType)
+    : CGM(emitter.CGM), Emitter(emitter), Value(value), DestType(destType) {}
+
+  llvm::Constant *tryEmit();
+
+private:
+  llvm::Constant *tryEmitAbsolute(llvm::Type *destTy);
+  ConstantLValue tryEmitBase(const APValue::LValueBase &base);
+
+  ConstantLValue VisitStmt(const Stmt *S) { return nullptr; }
+  ConstantLValue VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
+  ConstantLValue VisitStringLiteral(const StringLiteral *E);
+  ConstantLValue VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
+  ConstantLValue VisitObjCStringLiteral(const ObjCStringLiteral *E);
+  ConstantLValue VisitPredefinedExpr(const PredefinedExpr *E);
+  ConstantLValue VisitAddrLabelExpr(const AddrLabelExpr *E);
+  ConstantLValue VisitCallExpr(const CallExpr *E);
+  ConstantLValue VisitBlockExpr(const BlockExpr *E);
+  ConstantLValue VisitCXXTypeidExpr(const CXXTypeidExpr *E);
+  ConstantLValue VisitCXXUuidofExpr(const CXXUuidofExpr *E);
+  ConstantLValue VisitMaterializeTemporaryExpr(
+                                         const MaterializeTemporaryExpr *E);
+
+  bool hasNonZeroOffset() const {
+    return !Value.getLValueOffset().isZero();
   }
 
+  /// Return the value offset.
+  llvm::Constant *getOffset() {
+    return llvm::ConstantInt::get(CGM.Int64Ty,
+                                  Value.getLValueOffset().getQuantity());
+  }
+
+  /// Apply the value offset to the given constant.
+  llvm::Constant *applyOffset(llvm::Constant *C) {
+    if (!hasNonZeroOffset())
+      return C;
+
+    llvm::Type *origPtrTy = C->getType();
+    unsigned AS = origPtrTy->getPointerAddressSpace();
+    llvm::Type *charPtrTy = CGM.Int8Ty->getPointerTo(AS);
+    C = llvm::ConstantExpr::getBitCast(C, charPtrTy);
+    C = llvm::ConstantExpr::getGetElementPtr(CGM.Int8Ty, C, getOffset());
+    C = llvm::ConstantExpr::getPointerCast(C, origPtrTy);
+    return C;
+  }
+};
+
+}
+
+llvm::Constant *ConstantLValueEmitter::tryEmit() {
+  const APValue::LValueBase &base = Value.getLValueBase();
+
+  // Certain special array initializers are represented in APValue
+  // as l-values referring to the base expression which generates the
+  // array.  This happens with e.g. string literals.  These should
+  // probably just get their own representation kind in APValue.
+  if (DestType->isArrayType()) {
+    assert(!hasNonZeroOffset() && "offset on array initializer");
+    auto expr = const_cast<Expr*>(base.get<const Expr*>());
+    return ConstExprEmitter(Emitter).Visit(expr, DestType);
+  }
+
+  // Otherwise, the destination type should be a pointer or reference
+  // type, but it might also be a cast thereof.
+  //
+  // FIXME: the chain of casts required should be reflected in the APValue.
+  // We need this in order to correctly handle things like a ptrtoint of a
+  // non-zero null pointer and addrspace casts that aren't trivially
+  // represented in LLVM IR.
+  auto destTy = CGM.getTypes().ConvertTypeForMem(DestType);
+  assert(isa<llvm::IntegerType>(destTy) || isa<llvm::PointerType>(destTy));
+
+  // If there's no base at all, this is a null or absolute pointer,
+  // possibly cast back to an integer type.
+  if (!base) {
+    return tryEmitAbsolute(destTy);
+  }
+
+  // Otherwise, try to emit the base.
+  ConstantLValue result = tryEmitBase(base);
+
+  // If that failed, we're done.
+  llvm::Constant *value = result.Value;
+  if (!value) return nullptr;
+
+  // Apply the offset if necessary and not already done.
+  if (!result.HasOffsetApplied) {
+    value = applyOffset(value);
+  }
+
+  // Convert to the appropriate type; this could be an lvalue for
+  // an integer.  FIXME: performAddrSpaceCast
+  if (isa<llvm::PointerType>(destTy))
+    return llvm::ConstantExpr::getPointerCast(value, destTy);
+
+  return llvm::ConstantExpr::getPtrToInt(value, destTy);
+}
+
+/// Try to emit an absolute l-value, such as a null pointer or an integer
+/// bitcast to pointer type.
+llvm::Constant *
+ConstantLValueEmitter::tryEmitAbsolute(llvm::Type *destTy) {
+  auto offset = getOffset();
+
+  // If we're producing a pointer, this is easy.
+  if (auto destPtrTy = cast<llvm::PointerType>(destTy)) {
+    if (Value.isNullPointer()) {
+      // FIXME: integer offsets from non-zero null pointers.
+      return CGM.getNullPointer(destPtrTy, DestType);
+    }
+
+    // Convert the integer to a pointer-sized integer before converting it
+    // to a pointer.
+    // FIXME: signedness depends on the original integer type.
+    auto intptrTy = CGM.getDataLayout().getIntPtrType(destPtrTy);
+    llvm::Constant *C = offset;
+    C = llvm::ConstantExpr::getIntegerCast(getOffset(), intptrTy,
+                                           /*isSigned*/ false);
+    C = llvm::ConstantExpr::getIntToPtr(C, destPtrTy);
+    return C;
+  }
+
+  // Otherwise, we're basically returning an integer constant.
+
+  // FIXME: this does the wrong thing with ptrtoint of a null pointer,
+  // but since we don't know the original pointer type, there's not much
+  // we can do about it.
+
+  auto C = getOffset();
+  C = llvm::ConstantExpr::getIntegerCast(C, destTy, /*isSigned*/ false);
+  return C;
+}
+
+ConstantLValue
+ConstantLValueEmitter::tryEmitBase(const APValue::LValueBase &base) {
+  // Handle values.
+  if (const ValueDecl *D = base.dyn_cast<const ValueDecl*>()) {
+    if (D->hasAttr<WeakRefAttr>())
+      return CGM.GetWeakRefReference(D).getPointer();
+
+    if (auto FD = dyn_cast<FunctionDecl>(D))
+      return CGM.GetAddrOfFunction(FD);
+
+    if (auto VD = dyn_cast<VarDecl>(D)) {
+      // We can never refer to a variable with local storage.
+      if (!VD->hasLocalStorage()) {
+        if (VD->isFileVarDecl() || VD->hasExternalStorage())
+          return CGM.GetAddrOfGlobalVar(VD);
+
+        if (VD->isLocalVarDecl()) {
+          return CGM.getOrCreateStaticVarDecl(
+              *VD, CGM.getLLVMLinkageVarDefinition(VD, /*isConstant=*/false));
+        }
+      }
+    }
+
+    return nullptr;
+  }
+
+  // Otherwise, it must be an expression.
+  return Visit(base.get<const Expr*>());
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
+  return tryEmitGlobalCompoundLiteral(CGM, Emitter.CGF, E);
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitStringLiteral(const StringLiteral *E) {
+  return CGM.GetAddrOfConstantStringFromLiteral(E);
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
+  return CGM.GetAddrOfConstantStringFromObjCEncode(E);
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitObjCStringLiteral(const ObjCStringLiteral *E) {
+  auto C = CGM.getObjCRuntime().GenerateConstantString(E->getString());
+  return C.getElementBitCast(CGM.getTypes().ConvertTypeForMem(E->getType()));
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitPredefinedExpr(const PredefinedExpr *E) {
+  if (auto CGF = Emitter.CGF) {
+    LValue Res = CGF->EmitPredefinedLValue(E);
+    return cast<ConstantAddress>(Res.getAddress());
+  }
+
+  auto kind = E->getIdentType();
+  if (kind == PredefinedExpr::PrettyFunction) {
+    return CGM.GetAddrOfConstantCString("top level", ".tmp");
+  }
+
+  return CGM.GetAddrOfConstantCString("", ".tmp");
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitAddrLabelExpr(const AddrLabelExpr *E) {
+  assert(Emitter.CGF && "Invalid address of label expression outside function");
+  llvm::Constant *Ptr = Emitter.CGF->GetAddrOfLabel(E->getLabel());
+  Ptr = llvm::ConstantExpr::getBitCast(Ptr,
+                                   CGM.getTypes().ConvertType(E->getType()));
+  return Ptr;
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitCallExpr(const CallExpr *E) {
+  unsigned builtin = E->getBuiltinCallee();
+  if (builtin != Builtin::BI__builtin___CFStringMakeConstantString &&
+      builtin != Builtin::BI__builtin___NSStringMakeConstantString)
+    return nullptr;
+
+  auto literal = cast<StringLiteral>(E->getArg(0)->IgnoreParenCasts());
+  if (builtin == Builtin::BI__builtin___NSStringMakeConstantString) {
+    return CGM.getObjCRuntime().GenerateConstantString(literal);
+  } else {
+    // FIXME: need to deal with UCN conversion issues.
+    return CGM.GetAddrOfConstantCFString(literal);
+  }
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitBlockExpr(const BlockExpr *E) {
+  StringRef functionName;
+  if (auto CGF = Emitter.CGF)
+    functionName = CGF->CurFn->getName();
+  else
+    functionName = "global";
+
+  return CGM.GetAddrOfGlobalBlock(E, functionName);
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
+  QualType T;
+  if (E->isTypeOperand())
+    T = E->getTypeOperand(CGM.getContext());
+  else
+    T = E->getExprOperand()->getType();
+  return CGM.GetAddrOfRTTIDescriptor(T);
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
+  return CGM.GetAddrOfUuidDescriptor(E);
+}
+
+ConstantLValue
+ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
+                                            const MaterializeTemporaryExpr *E) {
+  assert(E->getStorageDuration() == SD_Static);
+  SmallVector<const Expr *, 2> CommaLHSs;
+  SmallVector<SubobjectAdjustment, 2> Adjustments;
+  const Expr *Inner = E->GetTemporaryExpr()
+      ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
+  return CGM.GetAddrOfGlobalTemporary(E, Inner);
+}
+
+llvm::Constant *ConstantEmitter::tryEmitPrivate(const APValue &Value,
+                                                QualType DestType) {
   switch (Value.getKind()) {
   case APValue::Uninitialized:
     llvm_unreachable("Constant expressions should be initialized.");
-  case APValue::LValue: {
-    llvm::Type *DestTy = getTypes().ConvertTypeForMem(DestType);
-    llvm::Constant *Offset =
-      llvm::ConstantInt::get(Int64Ty, Value.getLValueOffset().getQuantity());
-
-    llvm::Constant *C = nullptr;
-
-    if (APValue::LValueBase LVBase = Value.getLValueBase()) {
-      // An array can be represented as an lvalue referring to the base.
-      if (isa<llvm::ArrayType>(DestTy)) {
-        assert(Offset->isNullValue() && "offset on array initializer");
-        return ConstExprEmitter(*this, CGF).Visit(
-          const_cast<Expr*>(LVBase.get<const Expr*>()));
-      }
-
-      C = ConstExprEmitter(*this, CGF).EmitLValue(LVBase).getPointer();
-
-      // Apply offset if necessary.
-      if (!Offset->isNullValue()) {
-        unsigned AS = C->getType()->getPointerAddressSpace();
-        llvm::Type *CharPtrTy = Int8Ty->getPointerTo(AS);
-        llvm::Constant *Casted = llvm::ConstantExpr::getBitCast(C, CharPtrTy);
-        Casted = llvm::ConstantExpr::getGetElementPtr(Int8Ty, Casted, Offset);
-        C = llvm::ConstantExpr::getPointerCast(Casted, C->getType());
-      }
-
-      // Convert to the appropriate type; this could be an lvalue for
-      // an integer.
-      if (isa<llvm::PointerType>(DestTy))
-        return llvm::ConstantExpr::getPointerCast(C, DestTy);
-
-      return llvm::ConstantExpr::getPtrToInt(C, DestTy);
-    } else {
-      C = Offset;
-
-      // Convert to the appropriate type; this could be an lvalue for
-      // an integer.
-      if (auto PT = dyn_cast<llvm::PointerType>(DestTy)) {
-        if (Value.isNullPointer())
-          return getNullPointer(PT, DestType);
-        // Convert the integer to a pointer-sized integer before converting it
-        // to a pointer.
-        C = llvm::ConstantExpr::getIntegerCast(
-            C, getDataLayout().getIntPtrType(DestTy),
-            /*isSigned=*/false);
-        return llvm::ConstantExpr::getIntToPtr(C, DestTy);
-      }
-
-      // If the types don't match this should only be a truncate.
-      if (C->getType() != DestTy)
-        return llvm::ConstantExpr::getTrunc(C, DestTy);
-
-      return C;
-    }
-  }
+  case APValue::LValue:
+    return ConstantLValueEmitter(*this, Value, DestType).tryEmit();
   case APValue::Int:
-    return llvm::ConstantInt::get(VMContext, Value.getInt());
+    return llvm::ConstantInt::get(CGM.getLLVMContext(), Value.getInt());
   case APValue::ComplexInt: {
     llvm::Constant *Complex[2];
 
-    Complex[0] = llvm::ConstantInt::get(VMContext,
+    Complex[0] = llvm::ConstantInt::get(CGM.getLLVMContext(),
                                         Value.getComplexIntReal());
-    Complex[1] = llvm::ConstantInt::get(VMContext,
+    Complex[1] = llvm::ConstantInt::get(CGM.getLLVMContext(),
                                         Value.getComplexIntImag());
 
     // FIXME: the target may want to specify that this is packed.
@@ -1368,18 +1824,19 @@
   case APValue::Float: {
     const llvm::APFloat &Init = Value.getFloat();
     if (&Init.getSemantics() == &llvm::APFloat::IEEEhalf() &&
-        !Context.getLangOpts().NativeHalfType &&
-        !Context.getLangOpts().HalfArgsAndReturns)
-      return llvm::ConstantInt::get(VMContext, Init.bitcastToAPInt());
+        !CGM.getContext().getLangOpts().NativeHalfType &&
+        !CGM.getContext().getLangOpts().HalfArgsAndReturns)
+      return llvm::ConstantInt::get(CGM.getLLVMContext(),
+                                    Init.bitcastToAPInt());
     else
-      return llvm::ConstantFP::get(VMContext, Init);
+      return llvm::ConstantFP::get(CGM.getLLVMContext(), Init);
   }
   case APValue::ComplexFloat: {
     llvm::Constant *Complex[2];
 
-    Complex[0] = llvm::ConstantFP::get(VMContext,
+    Complex[0] = llvm::ConstantFP::get(CGM.getLLVMContext(),
                                        Value.getComplexFloatReal());
-    Complex[1] = llvm::ConstantFP::get(VMContext,
+    Complex[1] = llvm::ConstantFP::get(CGM.getLLVMContext(),
                                        Value.getComplexFloatImag());
 
     // FIXME: the target may want to specify that this is packed.
@@ -1394,9 +1851,9 @@
     for (unsigned I = 0; I != NumElts; ++I) {
       const APValue &Elt = Value.getVectorElt(I);
       if (Elt.isInt())
-        Inits[I] = llvm::ConstantInt::get(VMContext, Elt.getInt());
+        Inits[I] = llvm::ConstantInt::get(CGM.getLLVMContext(), Elt.getInt());
       else if (Elt.isFloat())
-        Inits[I] = llvm::ConstantFP::get(VMContext, Elt.getFloat());
+        Inits[I] = llvm::ConstantFP::get(CGM.getLLVMContext(), Elt.getFloat());
       else
         llvm_unreachable("unsupported vector element type");
     }
@@ -1405,13 +1862,14 @@
   case APValue::AddrLabelDiff: {
     const AddrLabelExpr *LHSExpr = Value.getAddrLabelDiffLHS();
     const AddrLabelExpr *RHSExpr = Value.getAddrLabelDiffRHS();
-    llvm::Constant *LHS = EmitConstantExpr(LHSExpr, LHSExpr->getType(), CGF);
-    llvm::Constant *RHS = EmitConstantExpr(RHSExpr, RHSExpr->getType(), CGF);
+    llvm::Constant *LHS = tryEmitPrivate(LHSExpr, LHSExpr->getType());
+    llvm::Constant *RHS = tryEmitPrivate(RHSExpr, RHSExpr->getType());
+    if (!LHS || !RHS) return nullptr;
 
     // Compute difference
-    llvm::Type *ResultType = getTypes().ConvertType(DestType);
-    LHS = llvm::ConstantExpr::getPtrToInt(LHS, IntPtrTy);
-    RHS = llvm::ConstantExpr::getPtrToInt(RHS, IntPtrTy);
+    llvm::Type *ResultType = CGM.getTypes().ConvertType(DestType);
+    LHS = llvm::ConstantExpr::getPtrToInt(LHS, CGM.IntPtrTy);
+    RHS = llvm::ConstantExpr::getPtrToInt(RHS, CGM.IntPtrTy);
     llvm::Constant *AddrLabelDiff = llvm::ConstantExpr::getSub(LHS, RHS);
 
     // LLVM is a bit sensitive about the exact format of the
@@ -1421,21 +1879,21 @@
   }
   case APValue::Struct:
   case APValue::Union:
-    return ConstStructBuilder::BuildStruct(*this, CGF, Value, DestType);
+    return ConstStructBuilder::BuildStruct(*this, Value, DestType);
   case APValue::Array: {
-    const ArrayType *CAT = Context.getAsArrayType(DestType);
+    const ArrayType *CAT = CGM.getContext().getAsArrayType(DestType);
     unsigned NumElements = Value.getArraySize();
     unsigned NumInitElts = Value.getArrayInitializedElts();
 
     // Emit array filler, if there is one.
     llvm::Constant *Filler = nullptr;
     if (Value.hasArrayFiller())
-      Filler = EmitConstantValueForMemory(Value.getArrayFiller(),
-                                          CAT->getElementType(), CGF);
+      Filler = tryEmitAbstractForMemory(Value.getArrayFiller(),
+                                        CAT->getElementType());
 
     // Emit initializer elements.
     llvm::Type *CommonElementType =
-        getTypes().ConvertType(CAT->getElementType());
+        CGM.getTypes().ConvertType(CAT->getElementType());
 
     // Try to use a ConstantAggregateZero if we can.
     if (Filler && Filler->isNullValue() && !NumInitElts) {
@@ -1444,15 +1902,21 @@
       return llvm::ConstantAggregateZero::get(AType);
     }
 
-    std::vector<llvm::Constant*> Elts;
+    SmallVector<llvm::Constant*, 16> Elts;
     Elts.reserve(NumElements);
     for (unsigned I = 0; I < NumElements; ++I) {
       llvm::Constant *C = Filler;
-      if (I < NumInitElts)
-        C = EmitConstantValueForMemory(Value.getArrayInitializedElt(I),
-                                       CAT->getElementType(), CGF);
-      else
-        assert(Filler && "Missing filler for implicit elements of initializer");
+      if (I < NumInitElts) {
+        C = tryEmitPrivateForMemory(Value.getArrayInitializedElt(I),
+                                    CAT->getElementType());
+      } else if (!Filler) {
+        assert(Value.hasArrayFiller() &&
+               "Missing filler for implicit elements of initializer");
+        C = tryEmitPrivateForMemory(Value.getArrayFiller(),
+                                    CAT->getElementType());
+      }
+      if (!C) return nullptr;
+
       if (I == 0)
         CommonElementType = C->getType();
       else if (C->getType() != CommonElementType)
@@ -1466,7 +1930,8 @@
       Types.reserve(NumElements);
       for (unsigned i = 0, e = Elts.size(); i < e; ++i)
         Types.push_back(Elts[i]->getType());
-      llvm::StructType *SType = llvm::StructType::get(VMContext, Types, true);
+      llvm::StructType *SType =
+        llvm::StructType::get(CGM.getLLVMContext(), Types, true);
       return llvm::ConstantStruct::get(SType, Elts);
     }
 
@@ -1475,23 +1940,11 @@
     return llvm::ConstantArray::get(AType, Elts);
   }
   case APValue::MemberPointer:
-    return getCXXABI().EmitMemberPointer(Value, DestType);
+    return CGM.getCXXABI().EmitMemberPointer(Value, DestType);
   }
   llvm_unreachable("Unknown APValue kind");
 }
 
-llvm::Constant *
-CodeGenModule::EmitConstantValueForMemory(const APValue &Value,
-                                          QualType DestType,
-                                          CodeGenFunction *CGF) {
-  llvm::Constant *C = EmitConstantValue(Value, DestType, CGF);
-  if (C->getType()->isIntegerTy(1)) {
-    llvm::Type *BoolTy = getTypes().ConvertTypeForMem(DestType);
-    C = llvm::ConstantExpr::getZExt(C, BoolTy);
-  }
-  return C;
-}
-
 llvm::GlobalVariable *CodeGenModule::getAddrOfConstantCompoundLiteralIfEmitted(
     const CompoundLiteralExpr *E) {
   return EmittedCompoundLiterals.lookup(E);
@@ -1507,7 +1960,7 @@
 ConstantAddress
 CodeGenModule::GetAddrOfConstantCompoundLiteral(const CompoundLiteralExpr *E) {
   assert(E->isFileScope() && "not a file-scope compound literal expr");
-  return ConstExprEmitter(*this, nullptr).EmitLValue(E);
+  return tryEmitGlobalCompoundLiteral(*this, nullptr, E);
 }
 
 llvm::Constant *
@@ -1629,6 +2082,11 @@
   return EmitNullConstant(CGM, base, /*asCompleteObject=*/false);
 }
 
+llvm::Constant *ConstantEmitter::emitNullForMemory(CodeGenModule &CGM,
+                                                   QualType T) {
+  return emitForMemory(CGM, CGM.EmitNullConstant(T), T);
+}
+
 llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
   if (T->getAs<PointerType>())
     return getNullPointer(
@@ -1643,7 +2101,8 @@
 
     QualType ElementTy = CAT->getElementType();
 
-    llvm::Constant *Element = EmitNullConstant(ElementTy);
+    llvm::Constant *Element =
+      ConstantEmitter::emitNullForMemory(*this, ElementTy);
     unsigned NumElements = CAT->getSize().getZExtValue();
     SmallVector<llvm::Constant *, 8> Array(NumElements, Element);
     return llvm::ConstantArray::get(ATy, Array);
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 1170b01..65f9007 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -428,14 +428,19 @@
     return CGF.getOpaqueRValueMapping(E).getScalarVal();
   }
 
+  Value *emitConstant(const CodeGenFunction::ConstantEmission &Constant,
+                      Expr *E) {
+    assert(Constant && "not a constant");
+    if (Constant.isReference())
+      return EmitLoadOfLValue(Constant.getReferenceLValue(CGF, E),
+                              E->getExprLoc());
+    return Constant.getValue();
+  }
+
   // l-values.
   Value *VisitDeclRefExpr(DeclRefExpr *E) {
-    if (CodeGenFunction::ConstantEmission result = CGF.tryEmitAsConstant(E)) {
-      if (result.isReference())
-        return EmitLoadOfLValue(result.getReferenceLValue(CGF, E),
-                                E->getExprLoc());
-      return result.getValue();
-    }
+    if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E))
+      return emitConstant(Constant, E);
     return EmitLoadOfLValue(E);
   }
 
@@ -1009,10 +1014,41 @@
     return Builder.CreateVectorSplat(NumElements, Src, "splat");
   }
 
-  // Allow bitcast from vector to integer/fp of the same size.
-  if (isa<llvm::VectorType>(SrcTy) ||
-      isa<llvm::VectorType>(DstTy))
-    return Builder.CreateBitCast(Src, DstTy, "conv");
+  if (isa<llvm::VectorType>(SrcTy) || isa<llvm::VectorType>(DstTy)) {
+    // Allow bitcast from vector to integer/fp of the same size.
+    unsigned SrcSize = SrcTy->getPrimitiveSizeInBits();
+    unsigned DstSize = DstTy->getPrimitiveSizeInBits();
+    if (SrcSize == DstSize)
+      return Builder.CreateBitCast(Src, DstTy, "conv");
+
+    // Conversions between vectors of different sizes are not allowed except
+    // when vectors of half are involved. Operations on storage-only half
+    // vectors require promoting half vector operands to float vectors and
+    // truncating the result, which is either an int or float vector, to a
+    // short or half vector.
+
+    // Source and destination are both expected to be vectors.
+    llvm::Type *SrcElementTy = SrcTy->getVectorElementType();
+    llvm::Type *DstElementTy = DstTy->getVectorElementType();
+
+    assert(((SrcElementTy->isIntegerTy() &&
+             DstElementTy->isIntegerTy()) ||
+            (SrcElementTy->isFloatingPointTy() &&
+             DstElementTy->isFloatingPointTy())) &&
+           "unexpected conversion between a floating-point vector and an "
+           "integer vector");
+
+    // Truncate an i32 vector to an i16 vector.
+    if (SrcElementTy->isIntegerTy())
+      return Builder.CreateIntCast(Src, DstTy, false, "conv");
+
+    // Truncate a float vector to a half vector.
+    if (SrcSize > DstSize)
+      return Builder.CreateFPTrunc(Src, DstTy, "conv");
+
+    // Promote a half vector to a float vector.
+    return Builder.CreateFPExt(Src, DstTy, "conv");
+  }
 
   // Finally, we have the arithmetic types: real int/float.
   Value *Res = nullptr;
@@ -1299,13 +1335,15 @@
 }
 
 Value *ScalarExprEmitter::VisitMemberExpr(MemberExpr *E) {
-  llvm::APSInt Value;
-  if (E->EvaluateAsInt(Value, CGF.getContext(), Expr::SE_AllowSideEffects)) {
-    if (E->isArrow())
-      CGF.EmitScalarExpr(E->getBase());
-    else
-      EmitLValue(E->getBase());
-    return Builder.getInt(Value);
+  if (CodeGenFunction::ConstantEmission Constant = CGF.tryEmitAsConstant(E)) {
+    CGF.EmitIgnoredExpr(E->getBase());
+    return emitConstant(Constant, E);
+  } else {
+    llvm::APSInt Value;
+    if (E->EvaluateAsInt(Value, CGF.getContext(), Expr::SE_AllowSideEffects)) {
+      CGF.EmitIgnoredExpr(E->getBase());
+      return Builder.getInt(Value);
+    }
   }
 
   return EmitLoadOfLValue(E);
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp
index 90fcad2..93577a7 100644
--- a/lib/CodeGen/CGObjC.cpp
+++ b/lib/CodeGen/CGObjC.cpp
@@ -1816,22 +1816,6 @@
 }
 
 
-static bool IsForwarding(StringRef Name) {
-  return llvm::StringSwitch<bool>(Name)
-      .Cases("objc_autoreleaseReturnValue",             // ARCInstKind::AutoreleaseRV
-             "objc_autorelease",                        // ARCInstKind::Autorelease
-             "objc_retainAutoreleaseReturnValue",       // ARCInstKind::FusedRetainAutoreleaseRV
-             "objc_retainAutoreleasedReturnValue",      // ARCInstKind::RetainRV
-             "objc_retainAutorelease",                  // ARCInstKind::FusedRetainAutorelease
-             "objc_retainedObject",                     // ARCInstKind::NoopCast
-             "objc_retain",                             // ARCInstKind::Retain
-             "objc_unretainedObject",                   // ARCInstKind::NoopCast
-             "objc_unretainedPointer",                  // ARCInstKind::NoopCast
-             "objc_unsafeClaimAutoreleasedReturnValue", // ARCInstKind::ClaimRV
-             true)
-      .Default(false);
-}
-
 static llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM,
                                                 llvm::FunctionType *FTy,
                                                 StringRef Name) {
@@ -1849,9 +1833,6 @@
       // performance.
       F->addFnAttr(llvm::Attribute::NonLazyBind);
     }
-
-    if (IsForwarding(Name))
-      F->arg_begin()->addAttr(llvm::Attribute::Returned);
   }
 
   return RTF;
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 98435fe..32a7d6a 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -7142,7 +7142,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 d488bd4..afbeb18 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -2447,7 +2447,7 @@
     OutlinedFnArgs.push_back(ThreadIDAddr.getPointer());
     OutlinedFnArgs.push_back(ZeroAddr.getPointer());
     OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
-    CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs);
+    RT.emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
 
     // __kmpc_end_serialized_parallel(&Loc, GTid);
     llvm::Value *EndArgs[] = {RT.emitUpdateLocation(CGF, Loc), ThreadID};
@@ -3348,14 +3348,14 @@
   auto *UnRegFn = createOffloadingBinaryDescriptorFunction(
       CGM, ".omp_offloading.descriptor_unreg",
       [&](CodeGenFunction &CGF, PrePostActionTy &) {
-        CGF.EmitCallOrInvoke(createRuntimeFunction(OMPRTL__tgt_unregister_lib),
-                             Desc);
+        CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_unregister_lib),
+                            Desc);
       });
   auto *RegFn = createOffloadingBinaryDescriptorFunction(
       CGM, ".omp_offloading.descriptor_reg",
       [&](CodeGenFunction &CGF, PrePostActionTy &) {
-        CGF.EmitCallOrInvoke(createRuntimeFunction(OMPRTL__tgt_register_lib),
-                             Desc);
+        CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__tgt_register_lib),
+                            Desc);
         CGM.getCXXABI().registerGlobalDtor(CGF, RegUnregVar, UnRegFn, Desc);
       });
   if (CGM.supportsCOMDAT()) {
@@ -3859,7 +3859,8 @@
   }
   CallArgs.push_back(SharedsParam);
 
-  CGF.EmitCallOrInvoke(TaskFunction, CallArgs);
+  CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskFunction,
+                                                  CallArgs);
   CGF.EmitStoreThroughLValue(
       RValue::get(CGF.Builder.getInt32(/*C=*/0)),
       CGF.MakeAddrLValue(CGF.ReturnValue, KmpInt32Ty));
@@ -4534,8 +4535,8 @@
     DepWaitTaskArgs[5] = llvm::ConstantPointerNull::get(CGF.VoidPtrTy);
   }
   auto &&ElseCodeGen = [&TaskArgs, ThreadID, NewTaskNewTaskTTy, TaskEntry,
-                        NumDependencies, &DepWaitTaskArgs](CodeGenFunction &CGF,
-                                                           PrePostActionTy &) {
+                        NumDependencies, &DepWaitTaskArgs,
+                        Loc](CodeGenFunction &CGF, PrePostActionTy &) {
     auto &RT = CGF.CGM.getOpenMPRuntime();
     CodeGenFunction::RunCleanupsScope LocalScope(CGF);
     // Build void __kmpc_omp_wait_deps(ident_t *, kmp_int32 gtid,
@@ -4546,11 +4547,12 @@
       CGF.EmitRuntimeCall(RT.createRuntimeFunction(OMPRTL__kmpc_omp_wait_deps),
                           DepWaitTaskArgs);
     // Call proxy_task_entry(gtid, new_task);
-    auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy](
-        CodeGenFunction &CGF, PrePostActionTy &Action) {
+    auto &&CodeGen = [TaskEntry, ThreadID, NewTaskNewTaskTTy,
+                      Loc](CodeGenFunction &CGF, PrePostActionTy &Action) {
       Action.Enter(CGF);
       llvm::Value *OutlinedFnArgs[] = {ThreadID, NewTaskNewTaskTTy};
-      CGF.EmitCallOrInvoke(TaskEntry, OutlinedFnArgs);
+      CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, Loc, TaskEntry,
+                                                          OutlinedFnArgs);
     };
 
     // Build void __kmpc_omp_task_begin_if0(ident_t *, kmp_int32 gtid,
@@ -7034,7 +7036,7 @@
   CGF.Builder.CreateCondBr(Failed, OffloadFailedBlock, OffloadContBlock);
 
   CGF.EmitBlock(OffloadFailedBlock);
-  CGF.Builder.CreateCall(OutlinedFn, KernelArgs);
+  emitOutlinedFunctionCall(CGF, D.getLocStart(), OutlinedFn, KernelArgs);
   CGF.EmitBranch(OffloadContBlock);
 
   CGF.EmitBlock(OffloadContBlock, /*IsFinished=*/true);
@@ -7754,3 +7756,29 @@
   CGF.EmitRuntimeCall(RTLFn, Args);
 }
 
+void CGOpenMPRuntime::emitCall(CodeGenFunction &CGF, llvm::Value *Callee,
+                               ArrayRef<llvm::Value *> Args,
+                               SourceLocation Loc) const {
+  auto DL = ApplyDebugLocation::CreateDefaultArtificial(CGF, Loc);
+
+  if (auto *Fn = dyn_cast<llvm::Function>(Callee)) {
+    if (Fn->doesNotThrow()) {
+      CGF.EmitNounwindRuntimeCall(Fn, Args);
+      return;
+    }
+  }
+  CGF.EmitRuntimeCall(Callee, Args);
+}
+
+void CGOpenMPRuntime::emitOutlinedFunctionCall(
+    CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+    ArrayRef<llvm::Value *> Args) const {
+  assert(Loc.isValid() && "Outlined function call location must be valid.");
+  emitCall(CGF, OutlinedFn, Args, Loc);
+}
+
+Address CGOpenMPRuntime::getParameterAddress(CodeGenFunction &CGF,
+                                             const VarDecl *NativeParam,
+                                             const VarDecl *TargetParam) const {
+  return CGF.GetAddrOfLocalVar(NativeParam);
+}
diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h
index 5dcf999..30e37a8 100644
--- a/lib/CodeGen/CGOpenMPRuntime.h
+++ b/lib/CodeGen/CGOpenMPRuntime.h
@@ -250,6 +250,11 @@
   //
   virtual StringRef getOutlinedHelperName() const { return ".omp_outlined."; }
 
+  /// Emits \p Callee function call with arguments \p Args with location \p Loc.
+  void emitCall(CodeGenFunction &CGF, llvm::Value *Callee,
+                ArrayRef<llvm::Value *> Args = llvm::None,
+                SourceLocation Loc = SourceLocation()) const;
+
 private:
   /// \brief Default const ident_t object used for initialization of all other
   /// ident_t objects.
@@ -1324,6 +1329,30 @@
   /// \param C 'depend' clause with 'sink|source' dependency kind.
   virtual void emitDoacrossOrdered(CodeGenFunction &CGF,
                                    const OMPDependClause *C);
+
+  /// Translates the native parameter of outlined function if this is required
+  /// for target.
+  /// \param FD Field decl from captured record for the paramater.
+  /// \param NativeParam Parameter itself.
+  virtual const VarDecl *translateParameter(const FieldDecl *FD,
+                                            const VarDecl *NativeParam) const {
+    return NativeParam;
+  }
+
+  /// Gets the address of the native argument basing on the address of the
+  /// target-specific parameter.
+  /// \param NativeParam Parameter itself.
+  /// \param TargetParam Corresponding target-specific parameter.
+  virtual Address getParameterAddress(CodeGenFunction &CGF,
+                                      const VarDecl *NativeParam,
+                                      const VarDecl *TargetParam) const;
+
+  /// Emits call of the outlined function with the provided arguments,
+  /// translating these arguments to correct target-specific arguments.
+  virtual void
+  emitOutlinedFunctionCall(CodeGenFunction &CGF, SourceLocation Loc,
+                           llvm::Value *OutlinedFn,
+                           ArrayRef<llvm::Value *> Args = llvm::None) const;
 };
 
 } // namespace CodeGen
diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
index 3ced05d..fca0a50 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
@@ -150,20 +150,18 @@
 
 /// Get the GPU warp size.
 static llvm::Value *getNVPTXWarpSize(CodeGenFunction &CGF) {
-  CGBuilderTy &Bld = CGF.Builder;
-  return Bld.CreateCall(
+  return CGF.EmitRuntimeCall(
       llvm::Intrinsic::getDeclaration(
           &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_warpsize),
-      llvm::None, "nvptx_warp_size");
+      "nvptx_warp_size");
 }
 
 /// Get the id of the current thread on the GPU.
 static llvm::Value *getNVPTXThreadID(CodeGenFunction &CGF) {
-  CGBuilderTy &Bld = CGF.Builder;
-  return Bld.CreateCall(
+  return CGF.EmitRuntimeCall(
       llvm::Intrinsic::getDeclaration(
           &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_tid_x),
-      llvm::None, "nvptx_tid");
+      "nvptx_tid");
 }
 
 /// Get the id of the warp in the block.
@@ -185,17 +183,15 @@
 
 /// Get the maximum number of threads in a block of the GPU.
 static llvm::Value *getNVPTXNumThreads(CodeGenFunction &CGF) {
-  CGBuilderTy &Bld = CGF.Builder;
-  return Bld.CreateCall(
+  return CGF.EmitRuntimeCall(
       llvm::Intrinsic::getDeclaration(
           &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_read_ptx_sreg_ntid_x),
-      llvm::None, "nvptx_num_threads");
+      "nvptx_num_threads");
 }
 
 /// Get barrier to synchronize all threads in a block.
 static void getNVPTXCTABarrier(CodeGenFunction &CGF) {
-  CGBuilderTy &Bld = CGF.Builder;
-  Bld.CreateCall(llvm::Intrinsic::getDeclaration(
+  CGF.EmitRuntimeCall(llvm::Intrinsic::getDeclaration(
       &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_barrier0));
 }
 
@@ -205,9 +201,9 @@
                             llvm::Value *NumThreads) {
   CGBuilderTy &Bld = CGF.Builder;
   llvm::Value *Args[] = {Bld.getInt32(ID), NumThreads};
-  Bld.CreateCall(llvm::Intrinsic::getDeclaration(&CGF.CGM.getModule(),
-                                                 llvm::Intrinsic::nvvm_barrier),
-                 Args);
+  CGF.EmitRuntimeCall(llvm::Intrinsic::getDeclaration(
+                          &CGF.CGM.getModule(), llvm::Intrinsic::nvvm_barrier),
+                      Args);
 }
 
 /// Synchronize all GPU threads in a block.
@@ -345,7 +341,7 @@
   Bld.CreateCondBr(IsWorker, WorkerBB, MasterCheckBB);
 
   CGF.EmitBlock(WorkerBB);
-  CGF.EmitCallOrInvoke(WST.WorkerFn, llvm::None);
+  emitCall(CGF, WST.WorkerFn);
   CGF.EmitBranch(EST.ExitBB);
 
   CGF.EmitBlock(MasterCheckBB);
@@ -555,7 +551,7 @@
         CGF.CreateDefaultAlignTempAlloca(CGF.Int32Ty, /*Name=*/".zero.addr");
     CGF.InitTempAlloca(ZeroAddr, CGF.Builder.getInt32(/*C=*/0));
     llvm::Value *FnArgs[] = {ZeroAddr.getPointer(), ZeroAddr.getPointer()};
-    CGF.EmitCallOrInvoke(Fn, FnArgs);
+    emitCall(CGF, Fn, FnArgs);
 
     // Go to end of parallel region.
     CGF.EmitBranch(TerminateBB);
@@ -883,7 +879,7 @@
   OutlinedFnArgs.push_back(ZeroAddr.getPointer());
   OutlinedFnArgs.push_back(ZeroAddr.getPointer());
   OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
-  CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs);
+  emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
 }
 
 void CGOpenMPRuntimeNVPTX::emitParallelCall(
@@ -932,10 +928,10 @@
   auto *ThreadID = getThreadID(CGF, Loc);
   llvm::Value *Args[] = {RTLoc, ThreadID};
 
-  auto &&SeqGen = [this, Fn, &CapturedVars, &Args](CodeGenFunction &CGF,
-                                                   PrePostActionTy &) {
-    auto &&CodeGen = [this, Fn, &CapturedVars](CodeGenFunction &CGF,
-                                               PrePostActionTy &Action) {
+  auto &&SeqGen = [this, Fn, &CapturedVars, &Args, Loc](CodeGenFunction &CGF,
+                                                        PrePostActionTy &) {
+    auto &&CodeGen = [this, Fn, &CapturedVars, Loc](CodeGenFunction &CGF,
+                                                    PrePostActionTy &Action) {
       Action.Enter(CGF);
 
       llvm::SmallVector<llvm::Value *, 16> OutlinedFnArgs;
@@ -944,7 +940,7 @@
       OutlinedFnArgs.push_back(
           llvm::ConstantPointerNull::get(CGM.Int32Ty->getPointerTo()));
       OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
-      CGF.EmitCallOrInvoke(Fn, OutlinedFnArgs);
+      emitOutlinedFunctionCall(CGF, Loc, Fn, OutlinedFnArgs);
     };
 
     RegionCodeGenTy RCG(CodeGen);
@@ -980,7 +976,7 @@
   OutlinedFnArgs.push_back(
       llvm::ConstantPointerNull::get(CGM.Int32Ty->getPointerTo()));
   OutlinedFnArgs.append(CapturedVars.begin(), CapturedVars.end());
-  CGF.EmitCallOrInvoke(OutlinedFn, OutlinedFnArgs);
+  emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, OutlinedFnArgs);
 }
 
 /// This function creates calls to one of two shuffle functions to copy
@@ -2238,3 +2234,81 @@
   CGF.EmitBranch(DefaultBB);
   CGF.EmitBlock(DefaultBB, /*IsFinished=*/true);
 }
+
+const VarDecl *
+CGOpenMPRuntimeNVPTX::translateParameter(const FieldDecl *FD,
+                                         const VarDecl *NativeParam) const {
+  if (!NativeParam->getType()->isReferenceType())
+    return NativeParam;
+  QualType ArgType = NativeParam->getType();
+  QualifierCollector QC;
+  const Type *NonQualTy = QC.strip(ArgType);
+  QualType PointeeTy = cast<ReferenceType>(NonQualTy)->getPointeeType();
+  if (const auto *Attr = FD->getAttr<OMPCaptureKindAttr>()) {
+    if (Attr->getCaptureKind() == OMPC_map) {
+      PointeeTy = CGM.getContext().getAddrSpaceQualType(PointeeTy,
+                                                        LangAS::opencl_global);
+    }
+  }
+  ArgType = CGM.getContext().getPointerType(PointeeTy);
+  QC.addRestrict();
+  enum { NVPTX_local_addr = 5 };
+  QC.addAddressSpace(NVPTX_local_addr);
+  ArgType = QC.apply(CGM.getContext(), ArgType);
+  return ImplicitParamDecl::Create(
+      CGM.getContext(), /*DC=*/nullptr, NativeParam->getLocation(),
+      NativeParam->getIdentifier(), ArgType, ImplicitParamDecl::Other);
+}
+
+Address
+CGOpenMPRuntimeNVPTX::getParameterAddress(CodeGenFunction &CGF,
+                                          const VarDecl *NativeParam,
+                                          const VarDecl *TargetParam) const {
+  assert(NativeParam != TargetParam &&
+         NativeParam->getType()->isReferenceType() &&
+         "Native arg must not be the same as target arg.");
+  Address LocalAddr = CGF.GetAddrOfLocalVar(TargetParam);
+  QualType NativeParamType = NativeParam->getType();
+  QualifierCollector QC;
+  const Type *NonQualTy = QC.strip(NativeParamType);
+  QualType NativePointeeTy = cast<ReferenceType>(NonQualTy)->getPointeeType();
+  unsigned NativePointeeAddrSpace =
+      NativePointeeTy.getQualifiers().getAddressSpace();
+  QualType TargetPointeeTy = TargetParam->getType()->getPointeeType();
+  llvm::Value *TargetAddr = CGF.EmitLoadOfScalar(
+      LocalAddr, /*Volatile=*/false, TargetPointeeTy, SourceLocation());
+  // First cast to generic.
+  TargetAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+      TargetAddr, TargetAddr->getType()->getPointerElementType()->getPointerTo(
+                      /*AddrSpace=*/0));
+  // Cast from generic to native address space.
+  TargetAddr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+      TargetAddr, TargetAddr->getType()->getPointerElementType()->getPointerTo(
+                      NativePointeeAddrSpace));
+  Address NativeParamAddr = CGF.CreateMemTemp(NativeParamType);
+  CGF.EmitStoreOfScalar(TargetAddr, NativeParamAddr, /*Volatile=*/false,
+                        NativeParam->getType());
+  return NativeParamAddr;
+}
+
+void CGOpenMPRuntimeNVPTX::emitOutlinedFunctionCall(
+    CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+    ArrayRef<llvm::Value *> Args) const {
+  SmallVector<llvm::Value *, 4> TargetArgs;
+  auto *FnType =
+      cast<llvm::FunctionType>(OutlinedFn->getType()->getPointerElementType());
+  for (unsigned I = 0, E = Args.size(); I < E; ++I) {
+    llvm::Type *TargetType = FnType->getParamType(I);
+    llvm::Value *NativeArg = Args[I];
+    if (!TargetType->isPointerTy()) {
+      TargetArgs.emplace_back(NativeArg);
+      continue;
+    }
+    llvm::Value *TargetArg = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+        NativeArg, NativeArg->getType()->getPointerElementType()->getPointerTo(
+                       /*AddrSpace=*/0));
+    TargetArgs.emplace_back(
+        CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(TargetArg, TargetType));
+  }
+  CGOpenMPRuntime::emitOutlinedFunctionCall(CGF, Loc, OutlinedFn, TargetArgs);
+}
diff --git a/lib/CodeGen/CGOpenMPRuntimeNVPTX.h b/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
index ae25e94..a9d6386 100644
--- a/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
+++ b/lib/CodeGen/CGOpenMPRuntimeNVPTX.h
@@ -268,6 +268,26 @@
   /// \return Specified function.
   llvm::Constant *createNVPTXRuntimeFunction(unsigned Function);
 
+  /// Translates the native parameter of outlined function if this is required
+  /// for target.
+  /// \param FD Field decl from captured record for the paramater.
+  /// \param NativeParam Parameter itself.
+  const VarDecl *translateParameter(const FieldDecl *FD,
+                                    const VarDecl *NativeParam) const override;
+
+  /// Gets the address of the native argument basing on the address of the
+  /// target-specific parameter.
+  /// \param NativeParam Parameter itself.
+  /// \param TargetParam Corresponding target-specific parameter.
+  Address getParameterAddress(CodeGenFunction &CGF, const VarDecl *NativeParam,
+                              const VarDecl *TargetParam) const override;
+
+  /// Emits call of the outlined function with the provided arguments,
+  /// translating these arguments to correct target-specific arguments.
+  void emitOutlinedFunctionCall(
+      CodeGenFunction &CGF, SourceLocation Loc, llvm::Value *OutlinedFn,
+      ArrayRef<llvm::Value *> Args = llvm::None) const override;
+
   /// Target codegen is specialized based on two programming models: the
   /// 'generic' fork-join model of OpenMP, and a more GPU efficient 'spmd'
   /// model for constructs like 'target parallel' that support it.
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 6135cf3..36b6c87 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -246,12 +246,12 @@
     const CapturedStmt *S = nullptr;
     /// true if cast to/from  UIntPtr is required for variables captured by
     /// value.
-    bool UIntPtrCastRequired = true;
-    /// true if only casted argumefnts must be registered as local args or VLA
+    const bool UIntPtrCastRequired = true;
+    /// true if only casted arguments must be registered as local args or VLA
     /// sizes.
-    bool RegisterCastedArgsOnly = false;
+    const bool RegisterCastedArgsOnly = false;
     /// Name of the generated function.
-    StringRef FunctionName;
+    const StringRef FunctionName;
     explicit FunctionOptions(const CapturedStmt *S, bool UIntPtrCastRequired,
                              bool RegisterCastedArgsOnly,
                              StringRef FunctionName)
@@ -261,9 +261,9 @@
   };
 }
 
-static std::pair<llvm::Function *, bool> emitOutlinedFunctionPrologue(
+static llvm::Function *emitOutlinedFunctionPrologue(
     CodeGenFunction &CGF, FunctionArgList &Args,
-    llvm::DenseMap<const Decl *, std::pair<const VarDecl *, Address>>
+    llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>>
         &LocalAddrs,
     llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>>
         &VLASizes,
@@ -276,9 +276,12 @@
   // Build the argument list.
   CodeGenModule &CGM = CGF.CGM;
   ASTContext &Ctx = CGM.getContext();
-  bool HasUIntPtrArgs = false;
+  FunctionArgList TargetArgs;
   Args.append(CD->param_begin(),
               std::next(CD->param_begin(), CD->getContextParamPosition()));
+  TargetArgs.append(
+      CD->param_begin(),
+      std::next(CD->param_begin(), CD->getContextParamPosition()));
   auto I = FO.S->captures().begin();
   for (auto *FD : RD->fields()) {
     QualType ArgType = FD->getType();
@@ -292,7 +295,6 @@
     // outlined function.
     if ((I->capturesVariableByCopy() && !ArgType->isAnyPointerType()) ||
         I->capturesVariableArrayType()) {
-      HasUIntPtrArgs = true;
       if (FO.UIntPtrCastRequired)
         ArgType = Ctx.getUIntPtrType();
     }
@@ -308,19 +310,28 @@
     }
     if (ArgType->isVariablyModifiedType())
       ArgType = getCanonicalParamType(Ctx, ArgType.getNonReferenceType());
-    Args.push_back(ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr,
-                                             FD->getLocation(), II, ArgType,
-                                             ImplicitParamDecl::Other));
+    auto *Arg =
+        ImplicitParamDecl::Create(Ctx, /*DC=*/nullptr, FD->getLocation(), II,
+                                  ArgType, ImplicitParamDecl::Other);
+    Args.emplace_back(Arg);
+    // Do not cast arguments if we emit function with non-original types.
+    TargetArgs.emplace_back(
+        FO.UIntPtrCastRequired
+            ? Arg
+            : CGM.getOpenMPRuntime().translateParameter(FD, Arg));
     ++I;
   }
   Args.append(
       std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
       CD->param_end());
+  TargetArgs.append(
+      std::next(CD->param_begin(), CD->getContextParamPosition() + 1),
+      CD->param_end());
 
   // Create the function declaration.
   FunctionType::ExtInfo ExtInfo;
   const CGFunctionInfo &FuncInfo =
-      CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
+      CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, TargetArgs);
   llvm::FunctionType *FuncLLVMTy = CGM.getTypes().GetFunctionType(FuncInfo);
 
   llvm::Function *F =
@@ -328,19 +339,26 @@
                              FO.FunctionName, &CGM.getModule());
   CGM.SetInternalFunctionAttributes(CD, F, FuncInfo);
   if (CD->isNothrow())
-    F->addFnAttr(llvm::Attribute::NoUnwind);
+    F->setDoesNotThrow();
 
   // Generate the function.
-  CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, Args, CD->getLocation(),
+  CGF.StartFunction(CD, Ctx.VoidTy, F, FuncInfo, TargetArgs, CD->getLocation(),
                     CD->getBody()->getLocStart());
   unsigned Cnt = CD->getContextParamPosition();
   I = FO.S->captures().begin();
   for (auto *FD : RD->fields()) {
+    // Do not map arguments if we emit function with non-original types.
+    Address LocalAddr(Address::invalid());
+    if (!FO.UIntPtrCastRequired && Args[Cnt] != TargetArgs[Cnt]) {
+      LocalAddr = CGM.getOpenMPRuntime().getParameterAddress(CGF, Args[Cnt],
+                                                             TargetArgs[Cnt]);
+    } else {
+      LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]);
+    }
     // If we are capturing a pointer by copy we don't need to do anything, just
     // use the value that we get from the arguments.
     if (I->capturesVariableByCopy() && FD->getType()->isAnyPointerType()) {
       const VarDecl *CurVD = I->getCapturedVar();
-      Address LocalAddr = CGF.GetAddrOfLocalVar(Args[Cnt]);
       // If the variable is a reference we need to materialize it here.
       if (CurVD->getType()->isReferenceType()) {
         Address RefAddr = CGF.CreateMemTemp(
@@ -357,8 +375,8 @@
     }
 
     LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
-    LValue ArgLVal = CGF.MakeAddrLValue(CGF.GetAddrOfLocalVar(Args[Cnt]),
-                                        Args[Cnt]->getType(), BaseInfo);
+    LValue ArgLVal =
+        CGF.MakeAddrLValue(LocalAddr, Args[Cnt]->getType(), BaseInfo);
     if (FD->hasCapturedVLAType()) {
       if (FO.UIntPtrCastRequired) {
         ArgLVal = CGF.MakeAddrLValue(castValueFromUintptr(CGF, FD->getType(),
@@ -412,7 +430,7 @@
     ++I;
   }
 
-  return {F, HasUIntPtrArgs};
+  return F;
 }
 
 llvm::Function *
@@ -426,14 +444,17 @@
       getDebugInfo() &&
       CGM.getCodeGenOpts().getDebugInfo() >= codegenoptions::LimitedDebugInfo;
   FunctionArgList Args;
-  llvm::DenseMap<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
+  llvm::MapVector<const Decl *, std::pair<const VarDecl *, Address>> LocalAddrs;
   llvm::DenseMap<const Decl *, std::pair<const Expr *, llvm::Value *>> VLASizes;
+  SmallString<256> Buffer;
+  llvm::raw_svector_ostream Out(Buffer);
+  Out << CapturedStmtInfo->getHelperName();
+  if (NeedWrapperFunction)
+    Out << "_debug__";
   FunctionOptions FO(&S, !NeedWrapperFunction, /*RegisterCastedArgsOnly=*/false,
-                     CapturedStmtInfo->getHelperName());
-  llvm::Function *F;
-  bool HasUIntPtrArgs;
-  std::tie(F, HasUIntPtrArgs) = emitOutlinedFunctionPrologue(
-      *this, Args, LocalAddrs, VLASizes, CXXThisValue, FO);
+                     Out.str());
+  llvm::Function *F = emitOutlinedFunctionPrologue(*this, Args, LocalAddrs,
+                                                   VLASizes, CXXThisValue, FO);
   for (const auto &LocalAddrPair : LocalAddrs) {
     if (LocalAddrPair.second.first) {
       setAddrOfLocalVar(LocalAddrPair.second.first,
@@ -445,20 +466,19 @@
   PGO.assignRegionCounters(GlobalDecl(CD), F);
   CapturedStmtInfo->EmitBody(*this, CD->getBody());
   FinishFunction(CD->getBodyRBrace());
-  if (!NeedWrapperFunction || !HasUIntPtrArgs)
+  if (!NeedWrapperFunction)
     return F;
 
   FunctionOptions WrapperFO(&S, /*UIntPtrCastRequired=*/true,
                             /*RegisterCastedArgsOnly=*/true,
-                            ".nondebug_wrapper.");
+                            CapturedStmtInfo->getHelperName());
   CodeGenFunction WrapperCGF(CGM, /*suppressNewContext=*/true);
-  WrapperCGF.disableDebugInfo();
   Args.clear();
   LocalAddrs.clear();
   VLASizes.clear();
   llvm::Function *WrapperF =
       emitOutlinedFunctionPrologue(WrapperCGF, Args, LocalAddrs, VLASizes,
-                                   WrapperCGF.CXXThisValue, WrapperFO).first;
+                                   WrapperCGF.CXXThisValue, WrapperFO);
   LValueBaseInfo BaseInfo(AlignmentSource::Decl, false);
   llvm::SmallVector<llvm::Value *, 4> CallArgs;
   for (const auto *Arg : Args) {
@@ -480,7 +500,8 @@
     }
     CallArgs.emplace_back(CallArg);
   }
-  WrapperCGF.Builder.CreateCall(F, CallArgs);
+  CGM.getOpenMPRuntime().emitOutlinedFunctionCall(WrapperCGF, S.getLocStart(),
+                                                  F, CallArgs);
   WrapperCGF.FinishFunction();
   return WrapperF;
 }
@@ -2728,6 +2749,7 @@
     OMPPrivateScope Scope(CGF);
     if (!Data.PrivateVars.empty() || !Data.FirstprivateVars.empty() ||
         !Data.LastprivateVars.empty()) {
+      enum { PrivatesParam = 2, CopyFnParam = 3 };
       auto *CopyFn = CGF.Builder.CreateLoad(
           CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(3)));
       auto *PrivatesPtr = CGF.Builder.CreateLoad(
@@ -2759,7 +2781,8 @@
         PrivatePtrs.push_back(std::make_pair(VD, PrivatePtr));
         CallArgs.push_back(PrivatePtr.getPointer());
       }
-      CGF.EmitRuntimeCall(CopyFn, CallArgs);
+      CGF.CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getLocStart(),
+                                                          CopyFn, CallArgs);
       for (auto &&Pair : LastprivateDstsOrigs) {
         auto *OrigVD = cast<VarDecl>(Pair.second->getDecl());
         DeclRefExpr DRE(
@@ -3070,7 +3093,8 @@
       llvm::SmallVector<llvm::Value *, 16> CapturedVars;
       CGF.GenerateOpenMPCapturedVars(*CS, CapturedVars);
       auto *OutlinedFn = emitOutlinedOrderedFunction(CGM, CS);
-      CGF.EmitNounwindRuntimeCall(OutlinedFn, CapturedVars);
+      CGM.getOpenMPRuntime().emitOutlinedFunctionCall(CGF, S.getLocStart(),
+                                                      OutlinedFn, CapturedVars);
     } else {
       Action.Enter(CGF);
       CGF.EmitStmt(
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index c23b25e..2cc0afe 100644
--- a/lib/CodeGen/CodeGenFunction.cpp
+++ b/lib/CodeGen/CodeGenFunction.cpp
@@ -429,6 +429,43 @@
   return CGM.getCodeGenOpts().XRayInstrumentFunctions;
 }
 
+llvm::Constant *
+CodeGenFunction::EncodeAddrForUseInPrologue(llvm::Function *F,
+                                            llvm::Constant *Addr) {
+  // Addresses stored in prologue data can't require run-time fixups and must
+  // be PC-relative. Run-time fixups are undesirable because they necessitate
+  // writable text segments, which are unsafe. And absolute addresses are
+  // undesirable because they break PIE mode.
+
+  // Add a layer of indirection through a private global. Taking its address
+  // won't result in a run-time fixup, even if Addr has linkonce_odr linkage.
+  auto *GV = new llvm::GlobalVariable(CGM.getModule(), Addr->getType(),
+                                      /*isConstant=*/true,
+                                      llvm::GlobalValue::PrivateLinkage, Addr);
+
+  // Create a PC-relative address.
+  auto *GOTAsInt = llvm::ConstantExpr::getPtrToInt(GV, IntPtrTy);
+  auto *FuncAsInt = llvm::ConstantExpr::getPtrToInt(F, IntPtrTy);
+  auto *PCRelAsInt = llvm::ConstantExpr::getSub(GOTAsInt, FuncAsInt);
+  return (IntPtrTy == Int32Ty)
+             ? PCRelAsInt
+             : llvm::ConstantExpr::getTrunc(PCRelAsInt, Int32Ty);
+}
+
+llvm::Value *
+CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F,
+                                          llvm::Value *EncodedAddr) {
+  // Reconstruct the address of the global.
+  auto *PCRelAsInt = Builder.CreateSExt(EncodedAddr, IntPtrTy);
+  auto *FuncAsInt = Builder.CreatePtrToInt(F, IntPtrTy, "func_addr.int");
+  auto *GOTAsInt = Builder.CreateAdd(PCRelAsInt, FuncAsInt, "global_addr.int");
+  auto *GOTAddr = Builder.CreateIntToPtr(GOTAsInt, Int8PtrPtrTy, "global_addr");
+
+  // Load the original pointer through the global.
+  return Builder.CreateLoad(Address(GOTAddr, getPointerAlign()),
+                            "decoded_addr");
+}
+
 /// EmitFunctionInstrumentation - Emit LLVM code to call the specified
 /// instrumentation function with the current function and the call site, if
 /// function instrumentation is enabled.
@@ -821,7 +858,10 @@
               CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
         llvm::Constant *FTRTTIConst =
             CGM.GetAddrOfRTTIDescriptor(FD->getType(), /*ForEH=*/true);
-        llvm::Constant *PrologueStructElems[] = { PrologueSig, FTRTTIConst };
+        llvm::Constant *FTRTTIConstEncoded =
+            EncodeAddrForUseInPrologue(Fn, FTRTTIConst);
+        llvm::Constant *PrologueStructElems[] = {PrologueSig,
+                                                 FTRTTIConstEncoded};
         llvm::Constant *PrologueStructConst =
             llvm::ConstantStruct::getAnon(PrologueStructElems, /*Packed=*/true);
         Fn->setPrologueData(PrologueStructConst);
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 753dd92..6febda6 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -111,6 +111,7 @@
   SANITIZER_CHECK(DynamicTypeCacheMiss, dynamic_type_cache_miss, 0)            \
   SANITIZER_CHECK(FloatCastOverflow, float_cast_overflow, 0)                   \
   SANITIZER_CHECK(FunctionTypeMismatch, function_type_mismatch, 0)             \
+  SANITIZER_CHECK(InvalidBuiltin, invalid_builtin, 0)                          \
   SANITIZER_CHECK(LoadInvalidValue, load_invalid_value, 0)                     \
   SANITIZER_CHECK(MissingReturn, missing_return, 0)                            \
   SANITIZER_CHECK(MulOverflow, mul_overflow, 0)                                \
@@ -1583,7 +1584,8 @@
   llvm::Function *GenerateBlockFunction(GlobalDecl GD,
                                         const CGBlockInfo &Info,
                                         const DeclMapTy &ldm,
-                                        bool IsLambdaConversionToBlock);
+                                        bool IsLambdaConversionToBlock,
+                                        bool BuildGlobalBlock);
 
   llvm::Constant *GenerateCopyHelperFunction(const CGBlockInfo &blockInfo);
   llvm::Constant *GenerateDestroyHelperFunction(const CGBlockInfo &blockInfo);
@@ -1774,6 +1776,15 @@
   /// EmitMCountInstrumentation - Emit call to .mcount.
   void EmitMCountInstrumentation();
 
+  /// Encode an address into a form suitable for use in a function prologue.
+  llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F,
+                                             llvm::Constant *Addr);
+
+  /// Decode an address used in a function prologue, encoded by \c
+  /// EncodeAddrForUseInPrologue.
+  llvm::Value *DecodeAddrUsedInPrologue(llvm::Value *F,
+                                        llvm::Value *EncodedAddr);
+
   /// EmitFunctionProlog - Emit the target specific LLVM code to load the
   /// arguments for the given function. This is also responsible for naming the
   /// LLVM function arguments.
@@ -3157,6 +3168,7 @@
   };
 
   ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr);
+  ConstantEmission tryEmitAsConstant(const MemberExpr *ME);
 
   RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e,
                                 AggValueSlot slot = AggValueSlot::ignored());
@@ -3605,6 +3617,17 @@
                                       SourceLocation Loc,
                                       const Twine &Name = "");
 
+  /// Specifies which type of sanitizer check to apply when handling a
+  /// particular builtin.
+  enum BuiltinCheckKind {
+    BCK_CTZPassedZero,
+    BCK_CLZPassedZero,
+  };
+
+  /// Emits an argument for a call to a builtin. If the builtin sanitizer is
+  /// enabled, a runtime check specified by \p Kind is also emitted.
+  llvm::Value *EmitCheckedArgForBuiltin(const Expr *E, BuiltinCheckKind Kind);
+
   /// \brief Emit a description of a type in a format suitable for passing to
   /// a runtime sanitizer handler.
   llvm::Constant *EmitCheckTypeDescriptor(QualType T);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 5561d45..1780572 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -24,6 +24,7 @@
 #include "CodeGenFunction.h"
 #include "CodeGenPGO.h"
 #include "CodeGenTBAA.h"
+#include "ConstantEmitter.h"
 #include "CoverageMappingGen.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
@@ -2678,6 +2679,8 @@
   const VarDecl *InitDecl;
   const Expr *InitExpr = D->getAnyInitializer(InitDecl);
 
+  Optional<ConstantEmitter> emitter;
+
   // CUDA E.2.4.1 "__shared__ variables cannot have an initialization
   // as part of their declaration."  Sema has already checked for
   // error cases, so we just need to set Init to UndefValue.
@@ -2698,7 +2701,8 @@
     Init = EmitNullConstant(D->getType());
   } else {
     initializedGlobalDecl = GlobalDecl(D);
-    Init = EmitConstantInit(*InitDecl);
+    emitter.emplace(*this);
+    Init = emitter->tryEmitForInitializer(*InitDecl);
 
     if (!Init) {
       QualType T = InitExpr->getType();
@@ -2811,7 +2815,9 @@
         Linkage = llvm::GlobalValue::InternalLinkage;
     }
   }
+
   GV->setInitializer(Init);
+  if (emitter) emitter->finalize(GV);
 
   // If it is safe to mark the global 'constant', do so now.
   GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor &&
@@ -3727,12 +3733,18 @@
       !EvalResult.hasSideEffects())
     Value = &EvalResult.Val;
 
+  unsigned AddrSpace =
+      VD ? GetGlobalVarAddressSpace(VD) : MaterializedType.getAddressSpace();
+
+  Optional<ConstantEmitter> emitter;
   llvm::Constant *InitialValue = nullptr;
   bool Constant = false;
   llvm::Type *Type;
   if (Value) {
     // The temporary has a constant initializer, use it.
-    InitialValue = EmitConstantValue(*Value, MaterializedType, nullptr);
+    emitter.emplace(*this);
+    InitialValue = emitter->emitForInitializer(*Value, AddrSpace,
+                                               MaterializedType);
     Constant = isTypeConstant(MaterializedType, /*ExcludeCtor*/Value);
     Type = InitialValue->getType();
   } else {
@@ -3757,12 +3769,11 @@
       Linkage = llvm::GlobalVariable::InternalLinkage;
     }
   }
-  unsigned AddrSpace =
-      VD ? GetGlobalVarAddressSpace(VD) : MaterializedType.getAddressSpace();
   auto TargetAS = getContext().getTargetAddressSpace(AddrSpace);
   auto *GV = new llvm::GlobalVariable(
       getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
       /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
+  if (emitter) emitter->finalize(GV);
   setGlobalVisibility(GV, VD);
   GV->setAlignment(Align.getQuantity());
   if (supportsCOMDAT() && GV->isWeakForLinker())
@@ -4527,7 +4538,7 @@
 llvm::Value *
 CodeGenModule::createOpenCLIntToSamplerConversion(const Expr *E,
                                                   CodeGenFunction &CGF) {
-  llvm::Constant *C = EmitConstantExpr(E, E->getType(), &CGF);
+  llvm::Constant *C = ConstantEmitter(CGF).emitAbstract(E, E->getType());
   auto SamplerT = getOpenCLRuntime().getSamplerType();
   auto FTy = llvm::FunctionType::get(SamplerT, {C->getType()}, false);
   return CGF.Builder.CreateCall(CreateRuntimeFunction(FTy,
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index b162e72..47a6dfa 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -942,27 +942,6 @@
 
   llvm::Constant *getMemberPointerConstant(const UnaryOperator *e);
 
-  /// Try to emit the initializer for the given declaration as a constant;
-  /// returns 0 if the expression cannot be emitted as a constant.
-  llvm::Constant *EmitConstantInit(const VarDecl &D,
-                                   CodeGenFunction *CGF = nullptr);
-
-  /// Try to emit the given expression as a constant; returns 0 if the
-  /// expression cannot be emitted as a constant.
-  llvm::Constant *EmitConstantExpr(const Expr *E, QualType DestType,
-                                   CodeGenFunction *CGF = nullptr);
-
-  /// Emit the given constant value as a constant, in the type's scalar
-  /// representation.
-  llvm::Constant *EmitConstantValue(const APValue &Value, QualType DestType,
-                                    CodeGenFunction *CGF = nullptr);
-
-  /// Emit the given constant value as a constant, in the type's memory
-  /// representation.
-  llvm::Constant *EmitConstantValueForMemory(const APValue &Value,
-                                             QualType DestType,
-                                             CodeGenFunction *CGF = nullptr);
-
   /// \brief Emit type info if type of an expression is a variably modified
   /// type. Also emit proper debug info for cast types.
   void EmitExplicitCastExprType(const ExplicitCastExpr *E,
@@ -1355,6 +1334,7 @@
                                   bool AttrOnCallSite,
                                   llvm::AttrBuilder &FuncAttrs);
 };
+
 }  // end namespace CodeGen
 }  // end namespace clang
 
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index 9306c4f..5ed9291 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -44,10 +44,6 @@
     delete &*I++;
 }
 
-const CodeGenOptions &CodeGenTypes::getCodeGenOpts() const {
-  return CGM.getCodeGenOpts();
-}
-
 void CodeGenTypes::addRecordTypeName(const RecordDecl *RD,
                                      llvm::StructType *Ty,
                                      StringRef suffix) {
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h
index 9d0e3de..f0b97eb 100644
--- a/lib/CodeGen/CodeGenTypes.h
+++ b/lib/CodeGen/CodeGenTypes.h
@@ -178,7 +178,6 @@
   const TargetInfo &getTarget() const { return Target; }
   CGCXXABI &getCXXABI() const { return TheCXXABI; }
   llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); }
-  const CodeGenOptions &getCodeGenOpts() const;
 
   /// ConvertType - Convert type T into a llvm::Type.
   llvm::Type *ConvertType(QualType T);
diff --git a/lib/CodeGen/ConstantEmitter.h b/lib/CodeGen/ConstantEmitter.h
new file mode 100644
index 0000000..991ef35
--- /dev/null
+++ b/lib/CodeGen/ConstantEmitter.h
@@ -0,0 +1,180 @@
+//===--- ConstantEmitter.h - IR constant emission ---------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A helper class for emitting expressions and values as llvm::Constants
+// and as initializers for global variables.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H
+#define LLVM_CLANG_LIB_CODEGEN_CONSTANTEMITTER_H
+
+#include "CodeGenFunction.h"
+#include "CodeGenModule.h"
+
+namespace clang {
+namespace CodeGen {
+
+class ConstantEmitter {
+public:
+  CodeGenModule &CGM;
+  CodeGenFunction *CGF;
+
+private:
+  bool Abstract = false;
+
+  /// Whether non-abstract components of the emitter have been initialized.
+  bool InitializedNonAbstract = false;
+
+  /// Whether the emitter has been finalized.
+  bool Finalized = false;
+
+  /// Whether the constant-emission failed.
+  bool Failed = false;
+
+  /// The AST address space where this (non-abstract) initializer is going.
+  /// Used for generating appropriate placeholders.
+  unsigned DestAddressSpace;
+
+  llvm::SmallVector<std::pair<llvm::Constant *, llvm::GlobalVariable*>, 4>
+    PlaceholderAddresses;
+
+public:
+  ConstantEmitter(CodeGenModule &CGM, CodeGenFunction *CGF = nullptr)
+    : CGM(CGM), CGF(CGF) {}
+
+  /// Initialize this emission in the context of the given function.
+  /// Use this if the expression might contain contextaul references like
+  /// block addresses or PredefinedExprs.
+  ConstantEmitter(CodeGenFunction &CGF)
+    : CGM(CGF.CGM), CGF(&CGF) {}
+
+  ConstantEmitter(const ConstantEmitter &other) = delete;
+  ConstantEmitter &operator=(const ConstantEmitter &other) = delete;
+
+  ~ConstantEmitter();
+
+  /// Is the current emission context abstract?
+  bool isAbstract() const {
+    return Abstract;
+  }
+
+  /// Try to emit the initiaizer of the given declaration as an abstract
+  /// constant.  If this succeeds, the emission must be finalized.
+  llvm::Constant *tryEmitForInitializer(const VarDecl &D);
+  llvm::Constant *tryEmitForInitializer(const Expr *E,
+                                        unsigned destAddrSpace,
+                                        QualType destType);
+  llvm::Constant *emitForInitializer(const APValue &value,
+                                     unsigned destAddrSpace,
+                                     QualType destType);
+
+  void finalize(llvm::GlobalVariable *global);
+
+  // All of the "abstract" emission methods below permit the emission to
+  // be immediately discarded without finalizing anything.  Therefore, they
+  // must also promise not to do anything that will, in the future, require
+  // finalization:
+  //
+  //   - using the CGF (if present) for anything other than establishing
+  //     semantic context; for example, an expression with ignored
+  //     side-effects must not be emitted as an abstract expression
+  //
+  //   - doing anything that would not be safe to duplicate within an
+  //     initializer or to propagate to another context; for example,
+  //     side effects, or emitting an initialization that requires a
+  //     reference to its current location.
+
+  /// Try to emit the initializer of the given declaration as an abstract
+  /// constant.
+  llvm::Constant *tryEmitAbstractForInitializer(const VarDecl &D);
+
+  /// Emit the result of the given expression as an abstract constant,
+  /// asserting that it succeeded.  This is only safe to do when the
+  /// expression is known to be a constant expression with either a fairly
+  /// simple type or a known simple form.
+  llvm::Constant *emitAbstract(const Expr *E, QualType T);
+  llvm::Constant *emitAbstract(SourceLocation loc, const APValue &value,
+                               QualType T);
+
+  /// Try to emit the result of the given expression as an abstract constant.
+  llvm::Constant *tryEmitAbstract(const Expr *E, QualType T);
+  llvm::Constant *tryEmitAbstractForMemory(const Expr *E, QualType T);
+
+  llvm::Constant *tryEmitAbstract(const APValue &value, QualType T);
+  llvm::Constant *tryEmitAbstractForMemory(const APValue &value, QualType T);
+
+  llvm::Constant *emitNullForMemory(QualType T) {
+    return emitNullForMemory(CGM, T);
+  }
+  llvm::Constant *emitForMemory(llvm::Constant *C, QualType T) {
+    return emitForMemory(CGM, C, T);
+  }
+
+  static llvm::Constant *emitNullForMemory(CodeGenModule &CGM, QualType T);
+  static llvm::Constant *emitForMemory(CodeGenModule &CGM, llvm::Constant *C,
+                                       QualType T);
+
+  // These are private helper routines of the constant emitter that
+  // can't actually be private because things are split out into helper
+  // functions and classes.
+
+  llvm::Constant *tryEmitPrivateForVarInit(const VarDecl &D);
+
+  llvm::Constant *tryEmitPrivate(const Expr *E, QualType T);
+  llvm::Constant *tryEmitPrivateForMemory(const Expr *E, QualType T);
+
+  llvm::Constant *tryEmitPrivate(const APValue &value, QualType T);
+  llvm::Constant *tryEmitPrivateForMemory(const APValue &value, QualType T);
+
+  /// Get the address of the current location.  This is a constant
+  /// that will resolve, after finalization, to the address of the
+  /// 'signal' value that is registered with the emitter later.
+  llvm::GlobalValue *getCurrentAddrPrivate();
+
+  /// Register a 'signal' value with the emitter to inform it where to
+  /// resolve a placeholder.  The signal value must be unique in the
+  /// initializer; it might, for example, be the address of a global that
+  /// refers to the current-address value in its own initializer.
+  ///
+  /// Uses of the placeholder must be properly anchored before finalizing
+  /// the emitter, e.g. by being installed as the initializer of a global
+  /// variable.  That is, it must be possible to replaceAllUsesWith
+  /// the placeholder with the proper address of the signal.
+  void registerCurrentAddrPrivate(llvm::Constant *signal,
+                                  llvm::GlobalValue *placeholder);
+
+private:
+  void initializeNonAbstract(unsigned destAS) {
+    assert(!InitializedNonAbstract);
+    InitializedNonAbstract = true;
+    DestAddressSpace = destAS;
+  }
+  llvm::Constant *markIfFailed(llvm::Constant *init) {
+    if (!init)
+      Failed = true;
+    return init;
+  }
+
+  struct AbstractState {
+    bool OldValue;
+    size_t OldPlaceholdersSize;
+  };
+  AbstractState pushAbstract() {
+    AbstractState saved = { Abstract, PlaceholderAddresses.size() };
+    Abstract = true;
+    return saved;
+  }
+  llvm::Constant *validateAndPopAbstract(llvm::Constant *C, AbstractState save);
+};
+
+}
+}
+
+#endif
diff --git a/lib/CodeGen/CoverageMappingGen.cpp b/lib/CodeGen/CoverageMappingGen.cpp
index a102347..8f6f3ed 100644
--- a/lib/CodeGen/CoverageMappingGen.cpp
+++ b/lib/CodeGen/CoverageMappingGen.cpp
@@ -29,7 +29,7 @@
 using namespace CodeGen;
 using namespace llvm::coverage;
 
-void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range) {
+void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range, SourceLocation) {
   SkippedRanges.push_back(Range);
 }
 
@@ -45,10 +45,19 @@
   /// \brief The region's ending location.
   Optional<SourceLocation> LocEnd;
 
+  /// Whether this region should be emitted after its parent is emitted.
+  bool DeferRegion;
+
+  /// Whether this region is a gap region. The count from a gap region is set
+  /// as the line execution count if there are no other regions on the line.
+  bool GapRegion;
+
 public:
   SourceMappingRegion(Counter Count, Optional<SourceLocation> LocStart,
-                      Optional<SourceLocation> LocEnd)
-      : Count(Count), LocStart(LocStart), LocEnd(LocEnd) {}
+                      Optional<SourceLocation> LocEnd, bool DeferRegion = false,
+                      bool GapRegion = false)
+      : Count(Count), LocStart(LocStart), LocEnd(LocEnd),
+        DeferRegion(DeferRegion), GapRegion(GapRegion) {}
 
   const Counter &getCounter() const { return Count; }
 
@@ -71,6 +80,44 @@
     assert(LocEnd && "Region has no end location");
     return *LocEnd;
   }
+
+  bool isDeferred() const { return DeferRegion; }
+
+  void setDeferred(bool Deferred) { DeferRegion = Deferred; }
+
+  bool isGap() const { return GapRegion; }
+
+  void setGap(bool Gap) { GapRegion = Gap; }
+};
+
+/// Spelling locations for the start and end of a source region.
+struct SpellingRegion {
+  /// The line where the region starts.
+  unsigned LineStart;
+
+  /// The column where the region starts.
+  unsigned ColumnStart;
+
+  /// The line where the region ends.
+  unsigned LineEnd;
+
+  /// The column where the region ends.
+  unsigned ColumnEnd;
+
+  SpellingRegion(SourceManager &SM, SourceLocation LocStart,
+                 SourceLocation LocEnd) {
+    LineStart = SM.getSpellingLineNumber(LocStart);
+    ColumnStart = SM.getSpellingColumnNumber(LocStart);
+    LineEnd = SM.getSpellingLineNumber(LocEnd);
+    ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
+  }
+
+  /// Check if the start and end locations appear in source order, i.e
+  /// top->bottom, left->right.
+  bool isInSourceOrder() const {
+    return (LineStart < LineEnd) ||
+           (LineStart == LineEnd && ColumnStart <= ColumnEnd);
+  }
 };
 
 /// \brief Provides the common functionality for the different
@@ -241,12 +288,9 @@
       auto CovFileID = getCoverageFileID(LocStart);
       if (!CovFileID)
         continue;
-      unsigned LineStart = SM.getSpellingLineNumber(LocStart);
-      unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
-      unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
-      unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
+      SpellingRegion SR{SM, LocStart, LocEnd};
       auto Region = CounterMappingRegion::makeSkipped(
-          *CovFileID, LineStart, ColumnStart, LineEnd, ColumnEnd);
+          *CovFileID, SR.LineStart, SR.ColumnStart, SR.LineEnd, SR.ColumnEnd);
       // Make sure that we only collect the regions that are inside
       // the souce code of this function.
       if (Region.LineStart >= FileLineRanges[*CovFileID].first &&
@@ -284,16 +328,19 @@
       if (Filter.count(std::make_pair(LocStart, LocEnd)))
         continue;
 
-      // Find the spilling locations for the mapping region.
-      unsigned LineStart = SM.getSpellingLineNumber(LocStart);
-      unsigned ColumnStart = SM.getSpellingColumnNumber(LocStart);
-      unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
-      unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
+      // Find the spelling locations for the mapping region.
+      SpellingRegion SR{SM, LocStart, LocEnd};
+      assert(SR.isInSourceOrder() && "region start and end out of order");
 
-      assert(LineStart <= LineEnd && "region start and end out of order");
-      MappingRegions.push_back(CounterMappingRegion::makeRegion(
-          Region.getCounter(), *CovFileID, LineStart, ColumnStart, LineEnd,
-          ColumnEnd));
+      if (Region.isGap()) {
+        MappingRegions.push_back(CounterMappingRegion::makeGapRegion(
+            Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart,
+            SR.LineEnd, SR.ColumnEnd));
+      } else {
+        MappingRegions.push_back(CounterMappingRegion::makeRegion(
+            Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart,
+            SR.LineEnd, SR.ColumnEnd));
+      }
     }
   }
 
@@ -317,14 +364,11 @@
              "region spans multiple files");
       Filter.insert(std::make_pair(ParentLoc, LocEnd));
 
-      unsigned LineStart = SM.getSpellingLineNumber(ParentLoc);
-      unsigned ColumnStart = SM.getSpellingColumnNumber(ParentLoc);
-      unsigned LineEnd = SM.getSpellingLineNumber(LocEnd);
-      unsigned ColumnEnd = SM.getSpellingColumnNumber(LocEnd);
-
+      SpellingRegion SR{SM, ParentLoc, LocEnd};
+      assert(SR.isInSourceOrder() && "region start and end out of order");
       MappingRegions.push_back(CounterMappingRegion::makeExpansion(
-          *ParentFileID, *ExpandedFileID, LineStart, ColumnStart, LineEnd,
-          ColumnEnd));
+          *ParentFileID, *ExpandedFileID, SR.LineStart, SR.ColumnStart,
+          SR.LineEnd, SR.ColumnEnd));
     }
     return Filter;
   }
@@ -389,6 +433,10 @@
   /// \brief A stack of currently live regions.
   std::vector<SourceMappingRegion> RegionStack;
 
+  /// The currently deferred region: its end location and count can be set once
+  /// its parent has been popped from the region stack.
+  Optional<SourceMappingRegion> DeferredRegion;
+
   CounterExpressionBuilder Builder;
 
   /// \brief A location in the most recently visited file or macro.
@@ -424,19 +472,61 @@
   /// used with popRegions to exit a "scope", ending the region that was pushed.
   size_t pushRegion(Counter Count, Optional<SourceLocation> StartLoc = None,
                     Optional<SourceLocation> EndLoc = None) {
-    if (StartLoc)
+    if (StartLoc) {
       MostRecentLocation = *StartLoc;
+      completeDeferred(Count, MostRecentLocation);
+    }
     RegionStack.emplace_back(Count, StartLoc, EndLoc);
 
     return RegionStack.size() - 1;
   }
 
+  /// Complete any pending deferred region by setting its end location and
+  /// count, and then pushing it onto the region stack.
+  size_t completeDeferred(Counter Count, SourceLocation DeferredEndLoc) {
+    size_t Index = RegionStack.size();
+    if (!DeferredRegion)
+      return Index;
+
+    // Consume the pending region.
+    SourceMappingRegion DR = DeferredRegion.getValue();
+    DeferredRegion = None;
+
+    // If the region ends in an expansion, find the expansion site.
+    if (SM.getFileID(DeferredEndLoc) != SM.getMainFileID()) {
+      FileID StartFile = SM.getFileID(DR.getStartLoc());
+      if (isNestedIn(DeferredEndLoc, StartFile)) {
+        do {
+          DeferredEndLoc = getIncludeOrExpansionLoc(DeferredEndLoc);
+        } while (StartFile != SM.getFileID(DeferredEndLoc));
+      }
+    }
+
+    // The parent of this deferred region ends where the containing decl ends,
+    // so the region isn't useful.
+    if (DR.getStartLoc() == DeferredEndLoc)
+      return Index;
+
+    // If we're visiting statements in non-source order (e.g switch cases or
+    // a loop condition) we can't construct a sensible deferred region.
+    if (!SpellingRegion(SM, DR.getStartLoc(), DeferredEndLoc).isInSourceOrder())
+      return Index;
+
+    DR.setGap(true);
+    DR.setCounter(Count);
+    DR.setEndLoc(DeferredEndLoc);
+    handleFileExit(DeferredEndLoc);
+    RegionStack.push_back(DR);
+    return Index;
+  }
+
   /// \brief Pop regions from the stack into the function's list of regions.
   ///
   /// Adds all regions from \c ParentIndex to the top of the stack to the
   /// function's \c SourceRegions.
   void popRegions(size_t ParentIndex) {
     assert(RegionStack.size() >= ParentIndex && "parent not in stack");
+    bool ParentOfDeferredRegion = false;
     while (RegionStack.size() > ParentIndex) {
       SourceMappingRegion &Region = RegionStack.back();
       if (Region.hasStartLoc()) {
@@ -468,9 +558,26 @@
 
         assert(SM.isWrittenInSameFile(Region.getStartLoc(), EndLoc));
         SourceRegions.push_back(Region);
+
+        if (ParentOfDeferredRegion) {
+          ParentOfDeferredRegion = false;
+
+          // If there's an existing deferred region, keep the old one, because
+          // it means there are two consecutive returns (or a similar pattern).
+          if (!DeferredRegion.hasValue() &&
+              // File IDs aren't gathered within macro expansions, so it isn't
+              // useful to try and create a deferred region inside of one.
+              (SM.getFileID(EndLoc) == SM.getMainFileID()))
+            DeferredRegion =
+                SourceMappingRegion(Counter::getZero(), EndLoc, None);
+        }
+      } else if (Region.isDeferred()) {
+        assert(!ParentOfDeferredRegion && "Consecutive deferred regions");
+        ParentOfDeferredRegion = true;
       }
       RegionStack.pop_back();
     }
+    assert(!ParentOfDeferredRegion && "Deferred region with no parent");
   }
 
   /// \brief Return the currently active region.
@@ -481,15 +588,17 @@
 
   /// \brief Propagate counts through the children of \c S.
   Counter propagateCounts(Counter TopCount, const Stmt *S) {
-    size_t Index = pushRegion(TopCount, getStart(S), getEnd(S));
+    SourceLocation StartLoc = getStart(S);
+    SourceLocation EndLoc = getEnd(S);
+    size_t Index = pushRegion(TopCount, StartLoc, EndLoc);
     Visit(S);
     Counter ExitCount = getRegion().getCounter();
     popRegions(Index);
 
     // The statement may be spanned by an expansion. Make sure we handle a file
     // exit out of this expansion before moving to the next statement.
-    if (SM.isBeforeInTranslationUnit(getStart(S), S->getLocStart()))
-      MostRecentLocation = getEnd(S);
+    if (SM.isBeforeInTranslationUnit(StartLoc, S->getLocStart()))
+      MostRecentLocation = EndLoc;
 
     return ExitCount;
   }
@@ -595,6 +704,8 @@
     handleFileExit(StartLoc);
     if (!Region.hasStartLoc())
       Region.setStartLoc(StartLoc);
+
+    completeDeferred(Region.getCounter(), StartLoc);
   }
 
   /// \brief Mark \c S as a terminator, starting a zero region.
@@ -604,6 +715,7 @@
     if (!Region.hasEndLoc())
       Region.setEndLoc(getEnd(S));
     pushRegion(Counter::getZero());
+    getRegion().setDeferred(true);
   }
 
   /// \brief Keep counts of breaks and continues inside loops.
@@ -617,13 +729,15 @@
       CoverageMappingModuleGen &CVM,
       llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM,
       const LangOptions &LangOpts)
-      : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {}
+      : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap),
+        DeferredRegion(None) {}
 
   /// \brief Write the mapping data to the output stream
   void write(llvm::raw_ostream &OS) {
     llvm::SmallVector<unsigned, 8> VirtualFileMapping;
     gatherFileIDs(VirtualFileMapping);
     SourceRegionFilter Filter = emitExpansionRegions();
+    assert(!DeferredRegion && "Deferred region never completed");
     emitSourceRegions(Filter);
     gatherSkippedRegions();
 
@@ -645,13 +759,25 @@
   }
 
   void VisitDecl(const Decl *D) {
+    assert(!DeferredRegion && "Deferred region never completed");
+
     Stmt *Body = D->getBody();
 
     // Do not propagate region counts into system headers.
     if (Body && SM.isInSystemHeader(SM.getSpellingLoc(getStart(Body))))
       return;
 
-    propagateCounts(getRegionCounter(Body), Body);
+    Counter ExitCount = propagateCounts(getRegionCounter(Body), Body);
+    assert(RegionStack.empty() && "Regions entered but never exited");
+
+    // Special case: if the last statement is a return, throw away the
+    // deferred region. This allows the closing brace to have a count.
+    if (auto *CS = dyn_cast_or_null<CompoundStmt>(Body))
+      if (dyn_cast_or_null<ReturnStmt>(CS->body_back()))
+        DeferredRegion = None;
+
+    // Complete any deferred regions introduced by the last statement.
+    popRegions(completeDeferred(ExitCount, getEnd(Body)));
   }
 
   void VisitReturnStmt(const ReturnStmt *S) {
@@ -682,6 +808,8 @@
     assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
     BreakContinueStack.back().BreakCount = addCounters(
         BreakContinueStack.back().BreakCount, getRegion().getCounter());
+    // FIXME: a break in a switch should terminate regions for all preceding
+    // case statements, not just the most recent one.
     terminateRegion(S);
   }
 
@@ -692,6 +820,16 @@
     terminateRegion(S);
   }
 
+  void VisitCallExpr(const CallExpr *E) {
+    VisitStmt(E);
+
+    // Terminate the region when we hit a noreturn function.
+    // (This is helpful dealing with switch statements.)
+    QualType CalleeType = E->getCallee()->getType();
+    if (getFunctionExtInfo(*CalleeType).getNoReturn())
+      terminateRegion(E);
+  }
+
   void VisitWhileStmt(const WhileStmt *S) {
     extendRegion(S);
 
@@ -823,15 +961,20 @@
     extendRegion(Body);
     if (const auto *CS = dyn_cast<CompoundStmt>(Body)) {
       if (!CS->body_empty()) {
-        // The body of the switch needs a zero region so that fallthrough counts
-        // behave correctly, but it would be misleading to include the braces of
-        // the compound statement in the zeroed area, so we need to handle this
-        // specially.
+        // Make a region for the body of the switch.  If the body starts with
+        // a case, that case will reuse this region; otherwise, this covers
+        // the unreachable code at the beginning of the switch body.
         size_t Index =
-            pushRegion(Counter::getZero(), getStart(CS->body_front()),
-                       getEnd(CS->body_back()));
+            pushRegion(Counter::getZero(), getStart(CS->body_front()));
         for (const auto *Child : CS->children())
           Visit(Child);
+
+        // Set the end for the body of the switch, if it isn't already set.
+        for (size_t i = RegionStack.size(); i != Index; --i) {
+          if (!RegionStack[i - 1].hasEndLoc())
+            RegionStack[i - 1].setEndLoc(getEnd(CS->body_back()));
+        }
+
         popRegions(Index);
       }
     } else
@@ -992,6 +1135,9 @@
     case CounterMappingRegion::SkippedRegion:
       OS << "Skipped,";
       break;
+    case CounterMappingRegion::GapRegion:
+      OS << "Gap,";
+      break;
     }
 
     OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart
diff --git a/lib/CodeGen/CoverageMappingGen.h b/lib/CodeGen/CoverageMappingGen.h
index b6789c2..d07ed5e 100644
--- a/lib/CodeGen/CoverageMappingGen.h
+++ b/lib/CodeGen/CoverageMappingGen.h
@@ -39,7 +39,7 @@
 public:
   ArrayRef<SourceRange> getSkippedRanges() const { return SkippedRanges; }
 
-  void SourceRangeSkipped(SourceRange Range) override;
+  void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override;
 };
 
 namespace CodeGen {
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index bd4cb9a..c82b967 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -62,20 +62,12 @@
 
   bool classifyReturnType(CGFunctionInfo &FI) const override;
 
-  bool passClassIndirect(const CXXRecordDecl *RD) const {
-    // Clang <= 4 used the pre-C++11 rule, which ignores move operations.
-    // The PS4 platform ABI follows the behavior of Clang 3.2.
-    if (CGM.getCodeGenOpts().getClangABICompat() <=
-            CodeGenOptions::ClangABI::Ver4 ||
-        CGM.getTriple().getOS() == llvm::Triple::PS4)
-      return RD->hasNonTrivialDestructor() ||
-             RD->hasNonTrivialCopyConstructor();
-    return !canCopyArgument(RD);
-  }
-
   RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override {
-    // If C++ prohibits us from making a copy, pass by address.
-    if (passClassIndirect(RD))
+    // Structures with either a non-trivial destructor or a non-trivial
+    // copy constructor are always indirect.
+    // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
+    // special members.
+    if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor())
       return RAA_Indirect;
     return RAA_Default;
   }
@@ -1006,8 +998,10 @@
   if (!RD)
     return false;
 
-  // If C++ prohibits us from making a copy, return by address.
-  if (passClassIndirect(RD)) {
+  // Return indirectly if we have a non-trivial copy ctor or non-trivial dtor.
+  // FIXME: Use canCopyArgument() when it is fixed to handle lazily declared
+  // special members.
+  if (RD->hasNonTrivialDestructor() || RD->hasNonTrivialCopyConstructor()) {
     auto Align = CGM.getContext().getTypeAlignInChars(FI.getReturnType());
     FI.getReturnInfo() = ABIArgInfo::getIndirect(Align, /*ByVal=*/false);
     return true;
diff --git a/lib/CodeGen/MicrosoftCXXABI.cpp b/lib/CodeGen/MicrosoftCXXABI.cpp
index 1bd2937..78b510b 100644
--- a/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -819,44 +819,46 @@
     return RAA_Default;
 
   case llvm::Triple::x86_64:
-    // If a class has a destructor, we'd really like to pass it indirectly
+    // Win64 passes objects with non-trivial copy ctors indirectly.
+    if (RD->hasNonTrivialCopyConstructor())
+      return RAA_Indirect;
+
+    // If an object has a destructor, we'd really like to pass it indirectly
     // because it allows us to elide copies.  Unfortunately, MSVC makes that
     // impossible for small types, which it will pass in a single register or
     // stack slot. Most objects with dtors are large-ish, so handle that early.
     // We can't call out all large objects as being indirect because there are
     // multiple x64 calling conventions and the C++ ABI code shouldn't dictate
     // how we pass large POD types.
-    //
-    // Note: This permits small classes with nontrivial destructors to be
-    // passed in registers, which is non-conforming.
     if (RD->hasNonTrivialDestructor() &&
         getContext().getTypeSize(RD->getTypeForDecl()) > 64)
       return RAA_Indirect;
 
-    // If a class has at least one non-deleted, trivial copy constructor, it
-    // is passed according to the C ABI. Otherwise, it is passed indirectly.
-    //
-    // Note: This permits classes with non-trivial copy or move ctors to be
-    // passed in registers, so long as they *also* have a trivial copy ctor,
-    // which is non-conforming.
-    if (RD->needsImplicitCopyConstructor()) {
-      // If the copy ctor has not yet been declared, we can read its triviality
-      // off the AST.
-      if (!RD->defaultedCopyConstructorIsDeleted() &&
-          RD->hasTrivialCopyConstructor())
-        return RAA_Default;
-    } else {
-      // Otherwise, we need to find the copy constructor(s) and ask.
-      for (const CXXConstructorDecl *CD : RD->ctors()) {
-        if (CD->isCopyConstructor()) {
-          // We had at least one nondeleted trivial copy ctor.  Return directly.
-          if (!CD->isDeleted() && CD->isTrivial())
-            return RAA_Default;
-        }
+    // If this is true, the implicit copy constructor that Sema would have
+    // created would not be deleted. FIXME: We should provide a more direct way
+    // for CodeGen to ask whether the constructor was deleted.
+    if (!RD->hasUserDeclaredCopyConstructor() &&
+        !RD->hasUserDeclaredMoveConstructor() &&
+        !RD->needsOverloadResolutionForMoveConstructor() &&
+        !RD->hasUserDeclaredMoveAssignment() &&
+        !RD->needsOverloadResolutionForMoveAssignment())
+      return RAA_Default;
+
+    // Otherwise, Sema should have created an implicit copy constructor if
+    // needed.
+    assert(!RD->needsImplicitCopyConstructor());
+
+    // We have to make sure the trivial copy constructor isn't deleted.
+    for (const CXXConstructorDecl *CD : RD->ctors()) {
+      if (CD->isCopyConstructor()) {
+        assert(CD->isTrivial());
+        // We had at least one undeleted trivial copy ctor.  Return directly.
+        if (!CD->isDeleted())
+          return RAA_Default;
       }
     }
 
-    // We have no trivial, non-deleted copy constructor.
+    // The trivial copy constructor was deleted.  Return indirectly.
     return RAA_Indirect;
   }
 
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index ece3a40..546439c 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -183,11 +183,7 @@
   return CGT.getTarget();
 }
 
-const CodeGenOptions &ABIInfo::getCodeGenOpts() const {
-  return CGT.getCodeGenOpts();
-}
-
-bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); }
+bool ABIInfo:: isAndroid() const { return getTarget().getTriple().isAndroid(); }
 
 bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
   return false;
@@ -1070,8 +1066,8 @@
   getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override {
     unsigned Sig = (0xeb << 0) |  // jmp rel8
                    (0x06 << 8) |  //           .+0x08
-                   ('F' << 16) |
-                   ('T' << 24);
+                   ('v' << 16) |
+                   ('2' << 24);
     return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
   }
 
@@ -2099,14 +2095,9 @@
     return !getTarget().getTriple().isOSDarwin();
   }
 
-  /// GCC classifies <1 x long long> as SSE but some platform ABIs choose to
-  /// classify it as INTEGER (for compatibility with older clang compilers).
+  /// GCC classifies <1 x long long> as SSE but compatibility with older clang
+  // compilers require us to classify it as INTEGER.
   bool classifyIntegerMMXAsSSE() const {
-    // Clang <= 3.8 did not do this.
-    if (getCodeGenOpts().getClangABICompat() <=
-        CodeGenOptions::ClangABI::Ver3_8)
-      return false;
-
     const llvm::Triple &Triple = getTarget().getTriple();
     if (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::PS4)
       return false;
@@ -2260,17 +2251,10 @@
 
   llvm::Constant *
   getUBSanFunctionSignature(CodeGen::CodeGenModule &CGM) const override {
-    unsigned Sig;
-    if (getABIInfo().has64BitPointers())
-      Sig = (0xeb << 0) |  // jmp rel8
-            (0x0a << 8) |  //           .+0x0c
-            ('F' << 16) |
-            ('T' << 24);
-    else
-      Sig = (0xeb << 0) |  // jmp rel8
-            (0x06 << 8) |  //           .+0x08
-            ('F' << 16) |
-            ('T' << 24);
+    unsigned Sig = (0xeb << 0) | // jmp rel8
+                   (0x06 << 8) | //           .+0x08
+                   ('v' << 16) |
+                   ('2' << 24);
     return llvm::ConstantInt::get(CGM.Int32Ty, Sig);
   }
 
diff --git a/lib/DirectoryWatcher/CMakeLists.txt b/lib/DirectoryWatcher/CMakeLists.txt
new file mode 100644
index 0000000..425a40f
--- /dev/null
+++ b/lib/DirectoryWatcher/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangDirectoryWatcher
+  DirectoryWatcher.cpp
+
+  LINK_LIBS
+  clangBasic
+  )
diff --git a/lib/DirectoryWatcher/DirectoryWatcher.cpp b/lib/DirectoryWatcher/DirectoryWatcher.cpp
new file mode 100644
index 0000000..3a90526
--- /dev/null
+++ b/lib/DirectoryWatcher/DirectoryWatcher.cpp
@@ -0,0 +1,275 @@
+//===- DirectoryWatcher.cpp - Listens for directory file changes ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief Utility class for listening for file system changes in a directory.
+//===----------------------------------------------------------------------===//
+
+#include "clang/DirectoryWatcher/DirectoryWatcher.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/raw_ostream.h"
+
+#define HAVE_CORESERVICES 0
+
+#if defined(__has_include)
+#if __has_include(<CoreServices/CoreServices.h>)
+
+#include <CoreServices/CoreServices.h>
+#undef HAVE_CORESERVICES
+#define HAVE_CORESERVICES 1
+
+#endif
+#endif
+
+using namespace clang;
+using namespace llvm;
+
+static timespec toTimeSpec(sys::TimePoint<> tp) {
+  std::chrono::seconds sec = std::chrono::time_point_cast<std::chrono::seconds>(
+                 tp).time_since_epoch();
+  std::chrono::nanoseconds nsec =
+    std::chrono::time_point_cast<std::chrono::nanoseconds>(tp - sec)
+      .time_since_epoch();
+  timespec ts;
+  ts.tv_sec = sec.count();
+  ts.tv_nsec = nsec.count();
+  return ts;
+}
+
+static Optional<timespec> getModTime(StringRef path) {
+  sys::fs::file_status Status;
+  std::error_code EC = status(path, Status);
+  if (EC)
+    return None;
+  return toTimeSpec(Status.getLastModificationTime());
+}
+
+struct DirectoryWatcher::Implementation {
+#if HAVE_CORESERVICES
+  FSEventStreamRef EventStream = nullptr;
+
+  bool setupFSEventStream(StringRef path, EventReceiver receiver,
+                          dispatch_queue_t queue);
+  void stopFSEventStream();
+
+  ~Implementation() {
+    stopFSEventStream();
+  };
+#endif
+};
+
+#if HAVE_CORESERVICES
+namespace {
+struct EventStreamContextData {
+  std::string WatchedPath;
+  DirectoryWatcher::EventReceiver Receiver;
+
+  EventStreamContextData(std::string watchedPath, DirectoryWatcher::EventReceiver receiver)
+  : WatchedPath(std::move(watchedPath)), Receiver(std::move(receiver)) {
+  }
+
+  static void dispose(const void *ctx) {
+    delete static_cast<const EventStreamContextData*>(ctx);
+  }
+};
+}
+
+static void eventStreamCallback(
+                       ConstFSEventStreamRef stream,
+                       void *clientCallBackInfo,
+                       size_t numEvents,
+                       void *eventPaths,
+                       const FSEventStreamEventFlags eventFlags[],
+                       const FSEventStreamEventId eventIds[]) {
+  auto *ctx = static_cast<EventStreamContextData*>(clientCallBackInfo);
+
+  std::vector<DirectoryWatcher::Event> Events;
+  for (size_t i = 0; i < numEvents; ++i) {
+    StringRef path = ((const char **)eventPaths)[i];
+    const FSEventStreamEventFlags flags = eventFlags[i];
+    if (!(flags & kFSEventStreamEventFlagItemIsFile)) {
+      if ((flags & kFSEventStreamEventFlagItemRemoved) && path == ctx->WatchedPath) {
+        DirectoryWatcher::Event Evt{DirectoryWatcher::EventKind::DirectoryDeleted, path, timespec{}};
+        Events.push_back(Evt);
+        break;
+      }
+      continue;
+    }
+    DirectoryWatcher::EventKind K = DirectoryWatcher::EventKind::Modified;
+    if ((flags & kFSEventStreamEventFlagItemCreated) ||
+        (flags & kFSEventStreamEventFlagItemRenamed))
+      K = DirectoryWatcher::EventKind::Added;
+    if (flags & kFSEventStreamEventFlagItemRemoved)
+      K = DirectoryWatcher::EventKind::Removed;
+    timespec modTime{};
+    if (K != DirectoryWatcher::EventKind::Removed) {
+      auto modTimeOpt = getModTime(path);
+      if (!modTimeOpt.hasValue())
+        continue;
+      modTime = modTimeOpt.getValue();
+    }
+    DirectoryWatcher::Event Evt{K, path, modTime};
+    Events.push_back(Evt);
+  }
+
+  ctx->Receiver(Events, /*isInitial=*/false);
+}
+
+bool DirectoryWatcher::Implementation::setupFSEventStream(StringRef path,
+                                                          EventReceiver receiver,
+                                                          dispatch_queue_t queue) {
+  if (path.empty())
+    return true;
+
+  CFMutableArrayRef pathsToWatch = CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks);
+  CFStringRef cfPathStr = CFStringCreateWithBytes(nullptr, (const UInt8 *)path.data(), path.size(), kCFStringEncodingUTF8, false);
+  CFArrayAppendValue(pathsToWatch, cfPathStr);
+  CFRelease(cfPathStr);
+  CFAbsoluteTime latency = 0.2; // Latency in seconds.
+
+  std::string realPath;
+  {
+    SmallString<128> Storage;
+    StringRef P = llvm::Twine(path).toNullTerminatedStringRef(Storage);
+    char Buffer[PATH_MAX];
+    // Use ::realpath to get the real path name
+    if (::realpath(P.begin(), Buffer) != nullptr)
+      realPath = Buffer;
+    else
+      realPath = path;
+  }
+
+  EventStreamContextData *ctxData = new EventStreamContextData(std::move(realPath), std::move(receiver));
+  FSEventStreamContext context;
+  context.version = 0;
+  context.info = ctxData;
+  context.retain = nullptr;
+  context.release = EventStreamContextData::dispose;
+  context.copyDescription = nullptr;
+
+  EventStream = FSEventStreamCreate(nullptr,
+                                    eventStreamCallback,
+                                    &context,
+                                    pathsToWatch,
+                                    kFSEventStreamEventIdSinceNow,
+                                    latency,
+                                    kFSEventStreamCreateFlagFileEvents |
+                                    kFSEventStreamCreateFlagNoDefer);
+  CFRelease(pathsToWatch);
+  if (!EventStream) {
+    return true;
+  }
+  FSEventStreamSetDispatchQueue(EventStream, queue);
+  FSEventStreamStart(EventStream);
+  return false;
+}
+
+void DirectoryWatcher::Implementation::stopFSEventStream() {
+  if (!EventStream)
+    return;
+  FSEventStreamStop(EventStream);
+  FSEventStreamInvalidate(EventStream);
+  FSEventStreamRelease(EventStream);
+  EventStream = nullptr;
+}
+#endif
+
+DirectoryWatcher::DirectoryWatcher()
+  : Impl(*new Implementation()) {}
+
+DirectoryWatcher::~DirectoryWatcher() {
+  delete &Impl;
+}
+
+#if HAVE_CORESERVICES
+static std::vector<DirectoryWatcher::Event> scanDirectory(StringRef Path) {
+  using namespace llvm::sys;
+
+  std::vector<DirectoryWatcher::Event> Events;
+  std::error_code EC;
+  for (auto It = fs::directory_iterator(Path, EC), End = fs::directory_iterator();
+         !EC && It != End; It.increment(EC)) {
+    auto modTime = getModTime(It->path());
+    if (!modTime.hasValue())
+      continue;
+    DirectoryWatcher::Event Event{DirectoryWatcher::EventKind::Added, It->path(), modTime.getValue()};
+    Events.push_back(std::move(Event));
+  }
+  return Events;
+}
+#endif
+
+std::unique_ptr<DirectoryWatcher> DirectoryWatcher::create(StringRef Path,
+        EventReceiver Receiver, bool waitInitialSync, std::string &Error) {
+#if HAVE_CORESERVICES
+
+  using namespace llvm::sys;
+
+  if (!fs::exists(Path)) {
+    std::error_code EC = fs::create_directories(Path);
+    if (EC) {
+      Error = EC.message();
+      return nullptr;
+    }
+  }
+
+  bool IsDir;
+  std::error_code EC = fs::is_directory(Path, IsDir);
+  if (EC) {
+    Error = EC.message();
+    return nullptr;
+  }
+  if (!IsDir) {
+    Error = "path is not a directory: ";
+    Error += Path;
+    return nullptr;
+  }
+
+  std::unique_ptr<DirectoryWatcher> DirWatch;
+  DirWatch.reset(new DirectoryWatcher());
+  auto &Impl = DirWatch->Impl;
+
+  dispatch_queue_t queue = dispatch_queue_create("DirectoryWatcher", DISPATCH_QUEUE_SERIAL);
+  dispatch_semaphore_t initScanSema = dispatch_semaphore_create(0);
+  dispatch_semaphore_t setupFSEventsSema = dispatch_semaphore_create(0);
+
+  std::string copiedPath = Path;
+  dispatch_retain(initScanSema);
+  dispatch_retain(setupFSEventsSema);
+  dispatch_async(queue, ^{
+    // Wait for the event stream to be setup before doing the initial scan,
+    // to make sure we won't miss any events.
+    dispatch_semaphore_wait(setupFSEventsSema, DISPATCH_TIME_FOREVER);
+    auto events = scanDirectory(copiedPath);
+    Receiver(events, /*isInitial=*/true);
+    dispatch_semaphore_signal(initScanSema);
+    dispatch_release(setupFSEventsSema);
+    dispatch_release(initScanSema);
+  });
+  bool fsErr = Impl.setupFSEventStream(Path, Receiver, queue);
+  dispatch_semaphore_signal(setupFSEventsSema);
+
+  if (waitInitialSync) {
+    dispatch_semaphore_wait(initScanSema, DISPATCH_TIME_FOREVER);
+  }
+  dispatch_release(setupFSEventsSema);
+  dispatch_release(initScanSema);
+  dispatch_release(queue);
+
+  if (fsErr) {
+    raw_string_ostream(Error) << "failed to setup FSEvents stream for path: " << Path;
+    return nullptr;
+  }
+
+  return DirWatch;
+#else
+  return nullptr;
+#endif
+}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index ba4d0e8..dd95e7e 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -995,7 +995,9 @@
   }
 
   // Assume associated files are based off of the first temporary file.
-  CrashReportInfo CrashInfo(TempFiles[0], VFS);
+  CrashReportInfo CrashInfo(
+      TempFiles[0], VFS,
+      C.getArgs().getLastArgValue(options::OPT_index_store_path));
 
   std::string Script = CrashInfo.Filename.rsplit('.').first.str() + ".sh";
   std::error_code EC;
diff --git a/lib/Driver/Job.cpp b/lib/Driver/Job.cpp
index 8b85680..355b9e0 100644
--- a/lib/Driver/Job.cpp
+++ b/lib/Driver/Job.cpp
@@ -67,6 +67,8 @@
     .Default(false);
   if (IsInclude)
     return HaveCrashVFS ? false : true;
+  if (StringRef(Flag).startswith("-index-store-path"))
+    return true;
 
   // The remaining flags are treated as a single argument.
 
@@ -88,6 +90,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;
@@ -219,6 +223,7 @@
   }
 
   bool HaveCrashVFS = CrashInfo && !CrashInfo->VFSPath.empty();
+  bool HaveIndexStorePath = CrashInfo && !CrashInfo->IndexStorePath.empty();
   for (size_t i = 0, e = Args.size(); i < e; ++i) {
     const char *const Arg = Args[i];
 
@@ -282,6 +287,24 @@
     printArg(OS, ModCachePath, Quote);
   }
 
+  if (CrashInfo && HaveIndexStorePath) {
+    SmallString<128> IndexStoreDir;
+
+    if (HaveCrashVFS) {
+      IndexStoreDir = llvm::sys::path::parent_path(
+          llvm::sys::path::parent_path(CrashInfo->VFSPath));
+      llvm::sys::path::append(IndexStoreDir, "index-store");
+    } else {
+      IndexStoreDir = "index-store";
+    }
+
+    OS << ' ';
+    printArg(OS, "-index-store-path", Quote);
+    OS << ' ';
+    printArg(OS, IndexStoreDir.c_str(), Quote);
+  }
+
+
   if (ResponseFile != nullptr) {
     OS << "\n Arguments passed via response file:\n";
     writeResponseFile(OS);
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index 7a442c8..65ebe7d 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -29,10 +29,11 @@
   NeedsUbsanRt = Undefined | Integer | Nullability | CFI,
   NeedsUbsanCxxRt = Vptr | CFI,
   NotAllowedWithTrap = Vptr,
+  NotAllowedWithMinimalRuntime = Vptr,
   RequiresPIE = DataFlow,
   NeedsUnwindTables = Address | Thread | Memory | DataFlow,
   SupportsCoverage = Address | KernelAddress | Memory | Leak | Undefined |
-                     Integer | Nullability | DataFlow | Fuzzer,
+                     Integer | Nullability | DataFlow | Fuzzer | FuzzerNoLink,
   RecoverableByDefault = Undefined | Integer | Nullability,
   Unrecoverable = Unreachable | Return,
   LegacyFsanitizeRecoverMask = Undefined | Integer,
@@ -41,6 +42,7 @@
                       Nullability | LocalBounds | CFI,
   TrappingDefault = CFI,
   CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
+  CompatibleWithMinimalRuntime = TrappingSupported,
 };
 
 enum CoverageFeature {
@@ -100,6 +102,8 @@
     BlacklistFile = "dfsan_abilist.txt";
   else if (Kinds & CFI)
     BlacklistFile = "cfi_blacklist.txt";
+  else if (Kinds & (Undefined | Integer | Nullability))
+    BlacklistFile = "ubsan_blacklist.txt";
 
   if (BlacklistFile) {
     clang::SmallString<64> Path(D.ResourceDir);
@@ -208,6 +212,10 @@
   SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args);
   SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
 
+  MinimalRuntime =
+      Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
+                   options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
+
   // The object size sanitizer should not be enabled at -O0.
   Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
   bool RemoveObjectSizeAtO0 =
@@ -245,6 +253,18 @@
         DiagnosedKinds |= KindsToDiagnose;
       }
       Add &= ~InvalidTrappingKinds;
+
+      if (MinimalRuntime) {
+        if (SanitizerMask KindsToDiagnose =
+                Add & NotAllowedWithMinimalRuntime & ~DiagnosedKinds) {
+          std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
+          D.Diag(diag::err_drv_argument_not_allowed_with)
+              << Desc << "-fsanitize-minimal-runtime";
+          DiagnosedKinds |= KindsToDiagnose;
+        }
+        Add &= ~NotAllowedWithMinimalRuntime;
+      }
+
       if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
         std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
         D.Diag(diag::err_drv_unsupported_opt_for_target)
@@ -281,11 +301,18 @@
       // Silently discard any unsupported sanitizers implicitly enabled through
       // group expansion.
       Add &= ~InvalidTrappingKinds;
+      if (MinimalRuntime) {
+        Add &= ~NotAllowedWithMinimalRuntime;
+      }
       Add &= Supported;
 
-      // Enable coverage if the fuzzing flag is set.
       if (Add & Fuzzer)
-        CoverageFeatures |= CoverageTracePCGuard | CoverageIndirCall | CoverageTraceCmp;
+        Add |= FuzzerNoLink;
+
+      // Enable coverage if the fuzzing flag is set.
+      if (Add & FuzzerNoLink)
+        CoverageFeatures |= CoverageTracePCGuard | CoverageIndirCall |
+                            CoverageTraceCmp;
 
       Kinds |= Add;
     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
@@ -484,6 +511,21 @@
   Stats = Args.hasFlag(options::OPT_fsanitize_stats,
                        options::OPT_fno_sanitize_stats, false);
 
+  if (MinimalRuntime) {
+    SanitizerMask IncompatibleMask =
+        Kinds & ~setGroupBits(CompatibleWithMinimalRuntime);
+    if (IncompatibleMask)
+      D.Diag(clang::diag::err_drv_argument_not_allowed_with)
+          << "-fsanitize-minimal-runtime"
+          << lastArgumentForMask(D, Args, IncompatibleMask);
+
+    SanitizerMask NonTrappingCfi = Kinds & CFI & ~TrappingKinds;
+    if (NonTrappingCfi)
+      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+          << "fsanitize-minimal-runtime"
+          << "fsanitize-trap=cfi";
+  }
+
   // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
   // enabled sanitizers.
   for (const auto *Arg : Args) {
@@ -736,6 +778,9 @@
   if (Stats)
     CmdArgs.push_back("-fsanitize-stats");
 
+  if (MinimalRuntime)
+    CmdArgs.push_back("-fsanitize-minimal-runtime");
+
   if (AsanFieldPadding)
     CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
                                          llvm::utostr(AsanFieldPadding)));
diff --git a/lib/Driver/ToolChain.cpp b/lib/Driver/ToolChain.cpp
index 9a858df..60d53f5 100644
--- a/lib/Driver/ToolChain.cpp
+++ b/lib/Driver/ToolChain.cpp
@@ -648,8 +648,16 @@
   DriverArgs.AddAllArgs(CC1Args, options::OPT_stdlib_EQ);
 }
 
+bool ToolChain::ShouldLinkCXXStdlib(const llvm::opt::ArgList &Args) const {
+  return getDriver().CCCIsCXX() &&
+         !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs,
+                      options::OPT_nostdlibxx);
+}
+
 void ToolChain::AddCXXStdlibLibArgs(const ArgList &Args,
                                     ArgStringList &CmdArgs) const {
+  assert(!Args.hasArg(options::OPT_nostdlibxx) &&
+         "should not have called this");
   CXXStdlibType Type = GetCXXStdlibType(Args);
 
   switch (Type) {
diff --git a/lib/Driver/ToolChains/Ananas.cpp b/lib/Driver/ToolChains/Ananas.cpp
index a67e1d2..ee072cc 100644
--- a/lib/Driver/ToolChains/Ananas.cpp
+++ b/lib/Driver/ToolChains/Ananas.cpp
@@ -91,11 +91,10 @@
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
-  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX())
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+  if (ToolChain.ShouldLinkCXXStdlib(Args))
+    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
     CmdArgs.push_back("-lc");
-  }
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
     CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
diff --git a/lib/Driver/ToolChains/BareMetal.cpp b/lib/Driver/ToolChains/BareMetal.cpp
index 28e4f5b..57a6686 100644
--- a/lib/Driver/ToolChains/BareMetal.cpp
+++ b/lib/Driver/ToolChains/BareMetal.cpp
@@ -184,10 +184,9 @@
                             options::OPT_e, options::OPT_s, options::OPT_t,
                             options::OPT_Z_Flag, options::OPT_r});
 
+  if (TC.ShouldLinkCXXStdlib(Args))
+    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (C.getDriver().CCCIsCXX())
-      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
-
     CmdArgs.push_back("-lc");
     CmdArgs.push_back("-lm");
 
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 6a6b90f..def01ae 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -2532,6 +2532,15 @@
     CmdArgs.push_back("-mpie-copy-relocations");
   }
 
+  // -fhosted is default.
+  // TODO: Audit uses of KernelOrKext and see where it'd be more appropriate to
+  // use Freestanding.
+  bool Freestanding =
+      Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
+      KernelOrKext;
+  if (Freestanding)
+    CmdArgs.push_back("-ffreestanding");
+
   // This is a coarse approximation of what llvm-gcc actually does, both
   // -fasynchronous-unwind-tables and -fnon-call-exceptions interact in more
   // complicated ways.
@@ -2540,7 +2549,7 @@
                    options::OPT_fno_asynchronous_unwind_tables,
                    (getToolChain().IsUnwindTablesDefault(Args) ||
                     getToolChain().getSanitizerArgs().needsUnwindTables()) &&
-                       !KernelOrKext);
+                       !Freestanding);
   if (Args.hasFlag(options::OPT_funwind_tables, options::OPT_fno_unwind_tables,
                    AsynchronousUnwindTables))
     CmdArgs.push_back("-munwind-tables");
@@ -2855,9 +2864,6 @@
 
   addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
 
-  if (auto *ABICompatArg = Args.getLastArg(options::OPT_fclang_abi_compat_EQ))
-    ABICompatArg->render(Args, CmdArgs);
-
   // Add runtime flag for PS4 when PGO or Coverage are enabled.
   if (getToolChain().getTriple().isPS4CPU())
     PS4cpu::addProfileRTArgs(getToolChain(), Args, CmdArgs);
@@ -2949,6 +2955,26 @@
     Args.AddLastArg(CmdArgs, options::OPT_objcmt_whitelist_dir_path);
   }
 
+  if (Args.hasArg(options::OPT_index_store_path)) {
+    Args.AddLastArg(CmdArgs, options::OPT_index_store_path);
+    Args.AddLastArg(CmdArgs, options::OPT_index_ignore_system_symbols);
+    Args.AddLastArg(CmdArgs, options::OPT_index_record_codegen_name);
+
+    // If '-o' is passed along with '-fsyntax-only' pass it along the cc1
+    // invocation so that the index action knows what the out file is.
+    if (isa<CompileJobAction>(JA) && JA.getType() == types::TY_Nothing) {
+      Args.AddLastArg(CmdArgs, options::OPT_o);
+    }
+  }
+
+  if (const char *IdxStorePath = ::getenv("CLANG_PROJECT_INDEX_PATH")) {
+    CmdArgs.push_back("-index-store-path");
+    CmdArgs.push_back(IdxStorePath);
+    CmdArgs.push_back("-index-ignore-system-symbols");
+    CmdArgs.push_back("-index-record-codegen-name");
+  }
+
+
   // Add preprocessing options like -I, -D, etc. if we are using the
   // preprocessor.
   //
@@ -3192,14 +3218,6 @@
 
   Args.AddLastArg(CmdArgs, options::OPT_ftlsmodel_EQ);
 
-  // -fhosted is default.
-  bool IsHosted = true;
-  if (Args.hasFlag(options::OPT_ffreestanding, options::OPT_fhosted, false) ||
-      KernelOrKext) {
-    CmdArgs.push_back("-ffreestanding");
-    IsHosted = false;
-  }
-
   // Forward -f (flag) options which we can pass directly.
   Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
   Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
@@ -3325,10 +3343,6 @@
     } else {
       StackProtectorLevel =
           getToolChain().GetDefaultStackProtectorLevel(KernelOrKext);
-      // Only use a default stack protector on Darwin in case -ffreestanding
-      // is not specified.
-      if (Triple.isOSDarwin() && !IsHosted)
-        StackProtectorLevel = 0;
     }
   }
   if (StackProtectorLevel) {
@@ -3484,6 +3498,19 @@
                     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");
+
+    Args.AddLastArg(CmdArgs, options::OPT_fapinotes_swift_version);
+  }
+
   // -fblocks=0 is default.
   if (Args.hasFlag(options::OPT_fblocks, options::OPT_fno_blocks,
                    getToolChain().IsBlocksDefault()) ||
diff --git a/lib/Driver/ToolChains/CloudABI.cpp b/lib/Driver/ToolChains/CloudABI.cpp
index 0f6c712..cdf807f 100644
--- a/lib/Driver/ToolChains/CloudABI.cpp
+++ b/lib/Driver/ToolChains/CloudABI.cpp
@@ -80,9 +80,9 @@
 
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
+  if (ToolChain.ShouldLinkCXXStdlib(Args))
+    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX())
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
     CmdArgs.push_back("-lc");
     CmdArgs.push_back("-lcompiler_rt");
   }
diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp
index 00bd60b..08c1bee 100644
--- a/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/lib/Driver/ToolChains/CommonArgs.cpp
@@ -541,6 +541,7 @@
   if (SanArgs.needsAsanRt() && SanArgs.needsSharedAsanRt()) {
     SharedRuntimes.push_back("asan");
   }
+
   // The stats_client library is also statically linked into DSOs.
   if (SanArgs.needsStatsRt())
     StaticRuntimes.push_back("stats_client");
@@ -574,9 +575,13 @@
       StaticRuntimes.push_back("tsan_cxx");
   }
   if (SanArgs.needsUbsanRt()) {
-    StaticRuntimes.push_back("ubsan_standalone");
-    if (SanArgs.linkCXXRuntimes())
-      StaticRuntimes.push_back("ubsan_standalone_cxx");
+    if (SanArgs.requiresMinimalRuntime()) {
+      StaticRuntimes.push_back("ubsan_minimal");
+    } else {
+      StaticRuntimes.push_back("ubsan_standalone");
+      if (SanArgs.linkCXXRuntimes())
+        StaticRuntimes.push_back("ubsan_standalone_cxx");
+    }
   }
   if (SanArgs.needsSafeStackRt()) {
     NonWholeStaticRuntimes.push_back("safestack");
@@ -597,17 +602,6 @@
     StaticRuntimes.push_back("esan");
 }
 
-static void addLibFuzzerRuntime(const ToolChain &TC,
-                                const ArgList &Args,
-                                ArgStringList &CmdArgs) {
-    StringRef ParentDir = llvm::sys::path::parent_path(TC.getDriver().InstalledDir);
-    SmallString<128> P(ParentDir);
-    llvm::sys::path::append(P, "lib", "libLLVMFuzzer.a");
-    CmdArgs.push_back(Args.MakeArgString(P));
-    TC.AddCXXStdlibLibArgs(Args, CmdArgs);
-}
-
-
 // Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
 // C runtime, etc). Returns true if sanitizer system deps need to be linked in.
 bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
@@ -617,10 +611,14 @@
   collectSanitizerRuntimes(TC, Args, SharedRuntimes, StaticRuntimes,
                            NonWholeStaticRuntimes, HelperStaticRuntimes,
                            RequiredSymbols);
+
   // Inject libfuzzer dependencies.
   if (TC.getSanitizerArgs().needsFuzzer()
       && !Args.hasArg(options::OPT_shared)) {
-    addLibFuzzerRuntime(TC, Args, CmdArgs);
+
+    addSanitizerRuntime(TC, Args, CmdArgs, "fuzzer", false, true);
+    if (!Args.hasArg(clang::driver::options::OPT_nostdlibxx))
+      TC.AddCXXStdlibLibArgs(Args, CmdArgs);
   }
 
   for (auto RT : SharedRuntimes)
diff --git a/lib/Driver/ToolChains/CrossWindows.cpp b/lib/Driver/ToolChains/CrossWindows.cpp
index 04b71c4..67ce08f 100644
--- a/lib/Driver/ToolChains/CrossWindows.cpp
+++ b/lib/Driver/ToolChains/CrossWindows.cpp
@@ -160,8 +160,7 @@
   TC.AddFilePathLibArgs(Args, CmdArgs);
   AddLinkerInputs(TC, Inputs, Args, CmdArgs, JA);
 
-  if (D.CCCIsCXX() && !Args.hasArg(options::OPT_nostdlib) &&
-      !Args.hasArg(options::OPT_nodefaultlibs)) {
+  if (TC.ShouldLinkCXXStdlib(Args)) {
     bool StaticCXX = Args.hasArg(options::OPT_static_libstdcxx) &&
                      !Args.hasArg(options::OPT_static);
     if (StaticCXX)
diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp
index 32103a6..5f8e76e 100644
--- a/lib/Driver/ToolChains/Darwin.cpp
+++ b/lib/Driver/ToolChains/Darwin.cpp
@@ -10,6 +10,7 @@
 #include "Darwin.h"
 #include "Arch/ARM.h"
 #include "CommonArgs.h"
+#include "clang/Basic/AlignedAllocation.h"
 #include "clang/Basic/ObjCRuntime.h"
 #include "clang/Basic/VirtualFileSystem.h"
 #include "clang/Driver/Compilation.h"
@@ -435,6 +436,10 @@
   // more information.
   ArgStringList CmdArgs;
 
+  Args.ClaimAllArgs(options::OPT_index_store_path);
+  Args.ClaimAllArgs(options::OPT_index_ignore_system_symbols);
+  Args.ClaimAllArgs(options::OPT_index_record_codegen_name);
+
   /// Hack(tm) to ignore linking errors when we are doing ARC migration.
   if (Args.hasArg(options::OPT_ccc_arcmt_check,
                   options::OPT_ccc_arcmt_migrate)) {
@@ -493,7 +498,7 @@
   if (getToolChain().getSanitizerArgs().needsSafeStackRt()) {
     getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs,
                                           "libclang_rt.safestack_osx.a",
-                                          /*AlwaysLink=*/true);
+                                          toolchains::Darwin::RLO_AlwaysLink);
   }
 
   Args.AddAllArgs(CmdArgs, options::OPT_L);
@@ -548,10 +553,9 @@
         Args.MakeArgString(Twine("-threads=") + llvm::to_string(Parallelism)));
   }
 
+  if (getToolChain().ShouldLinkCXXStdlib(Args))
+    getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (getToolChain().getDriver().CCCIsCXX())
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
-
     // link_ssp spec is empty.
 
     // Let the tool chain choose which runtime library to link.
@@ -897,10 +901,11 @@
 }
 
 void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
-                              StringRef DarwinLibName, bool AlwaysLink,
-                              bool IsEmbedded, bool AddRPath) const {
+                              StringRef DarwinLibName,
+                              RuntimeLinkOptions Opts) const {
   SmallString<128> Dir(getDriver().ResourceDir);
-  llvm::sys::path::append(Dir, "lib", IsEmbedded ? "macho_embedded" : "darwin");
+  llvm::sys::path::append(
+      Dir, "lib", (Opts & RLO_IsEmbedded) ? "macho_embedded" : "darwin");
 
   SmallString<128> P(Dir);
   llvm::sys::path::append(P, DarwinLibName);
@@ -908,14 +913,19 @@
   // For now, allow missing resource libraries to support developers who may
   // not have compiler-rt checked out or integrated into their build (unless
   // we explicitly force linking with this library).
-  if (AlwaysLink || getVFS().exists(P))
-    CmdArgs.push_back(Args.MakeArgString(P));
+  if ((Opts & RLO_AlwaysLink) || getVFS().exists(P)) {
+    const char *LibArg = Args.MakeArgString(P);
+    if (Opts & RLO_FirstLink)
+      CmdArgs.insert(CmdArgs.begin(), LibArg);
+    else
+      CmdArgs.push_back(LibArg);
+  }
 
   // Adding the rpaths might negatively interact when other rpaths are involved,
   // so we should make sure we add the rpaths last, after all user-specified
   // rpaths. This is currently true from this place, but we need to be
   // careful if this function is ever called before user's rpaths are emitted.
-  if (AddRPath) {
+  if (Opts & RLO_AddRPath) {
     assert(DarwinLibName.endswith(".dylib") && "must be a dynamic library");
 
     // Add @executable_path to rpath to support having the dylib copied with
@@ -930,18 +940,6 @@
   }
 }
 
-void MachO::AddFuzzerLinkArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
-
-  // Go up one directory from Clang to find the libfuzzer archive file.
-  StringRef ParentDir = llvm::sys::path::parent_path(getDriver().InstalledDir);
-  SmallString<128> P(ParentDir);
-  llvm::sys::path::append(P, "lib", "libLLVMFuzzer.a");
-  CmdArgs.push_back(Args.MakeArgString(P));
-
-  // Libfuzzer is written in C++ and requires libcxx.
-  AddCXXStdlibLibArgs(Args, CmdArgs);
-}
-
 StringRef Darwin::getPlatformFamily() const {
   switch (TargetPlatform) {
     case DarwinPlatformKind::MacOS:
@@ -996,20 +994,23 @@
                               ArgStringList &CmdArgs) const {
   if (!needsProfileRT(Args)) return;
 
-  AddLinkRuntimeLib(Args, CmdArgs, (Twine("libclang_rt.profile_") +
-       getOSLibraryNameSuffix() + ".a").str(),
-                    /*AlwaysLink*/ true);
+  AddLinkRuntimeLib(
+      Args, CmdArgs,
+      (Twine("libclang_rt.profile_") + getOSLibraryNameSuffix() + ".a").str(),
+      RuntimeLinkOptions(RLO_AlwaysLink | RLO_FirstLink));
 }
 
 void DarwinClang::AddLinkSanitizerLibArgs(const ArgList &Args,
                                           ArgStringList &CmdArgs,
-                                          StringRef Sanitizer) const {
-  AddLinkRuntimeLib(
-      Args, CmdArgs,
-      (Twine("libclang_rt.") + Sanitizer + "_" +
-       getOSLibraryNameSuffix() + "_dynamic.dylib").str(),
-      /*AlwaysLink*/ true, /*IsEmbedded*/ false,
-      /*AddRPath*/ true);
+                                          StringRef Sanitizer,
+                                          bool Shared) const {
+  auto RLO = RuntimeLinkOptions(RLO_AlwaysLink | (Shared ? RLO_AddRPath : 0U));
+  AddLinkRuntimeLib(Args, CmdArgs,
+                    (Twine("libclang_rt.") + Sanitizer + "_" +
+                     getOSLibraryNameSuffix() +
+                     (Shared ? "_dynamic.dylib" : ".a"))
+                        .str(),
+                    RLO);
 }
 
 ToolChain::RuntimeLibType DarwinClang::GetRuntimeLibType(
@@ -1050,16 +1051,22 @@
   if (Sanitize.needsLsanRt())
     AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan");
   if (Sanitize.needsUbsanRt())
-    AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan");
+    AddLinkSanitizerLibArgs(Args, CmdArgs,
+                            Sanitize.requiresMinimalRuntime() ? "ubsan_minimal"
+                                                              : "ubsan");
   if (Sanitize.needsTsanRt())
     AddLinkSanitizerLibArgs(Args, CmdArgs, "tsan");
-  if (Sanitize.needsFuzzer() && !Args.hasArg(options::OPT_dynamiclib))
-    AddFuzzerLinkArgs(Args, CmdArgs);
+  if (Sanitize.needsFuzzer() && !Args.hasArg(options::OPT_dynamiclib)) {
+    AddLinkSanitizerLibArgs(Args, CmdArgs, "fuzzer", /*shared=*/false);
+
+    // Libfuzzer is written in C++ and requires libcxx.
+    AddCXXStdlibLibArgs(Args, CmdArgs);
+  }
   if (Sanitize.needsStatsRt()) {
     StringRef OS = isTargetMacOS() ? "osx" : "iossim";
     AddLinkRuntimeLib(Args, CmdArgs,
                       (Twine("libclang_rt.stats_client_") + OS + ".a").str(),
-                      /*AlwaysLink=*/true);
+                      RLO_AlwaysLink);
     AddLinkSanitizerLibArgs(Args, CmdArgs, "stats");
   }
   if (Sanitize.needsEsanRt())
@@ -1741,23 +1748,31 @@
           : "soft";
   CompilerRT += Args.hasArg(options::OPT_fPIC) ? "_pic.a" : "_static.a";
 
-  AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, false, true);
+  AddLinkRuntimeLib(Args, CmdArgs, CompilerRT, RLO_IsEmbedded);
 }
 
 bool Darwin::isAlignedAllocationUnavailable() const {
+  llvm::Triple::OSType OS;
+
   switch (TargetPlatform) {
   case MacOS: // Earlier than 10.13.
-    return TargetVersion < VersionTuple(10U, 13U, 0U);
+    OS = llvm::Triple::MacOSX;
+    break;
   case IPhoneOS:
   case IPhoneOSSimulator:
+    OS = llvm::Triple::IOS;
+    break;
   case TvOS:
   case TvOSSimulator: // Earlier than 11.0.
-    return TargetVersion < VersionTuple(11U, 0U, 0U);
+    OS = llvm::Triple::TvOS;
+    break;
   case WatchOS:
   case WatchOSSimulator: // Earlier than 4.0.
-    return TargetVersion < VersionTuple(4U, 0U, 0U);
+    OS = llvm::Triple::WatchOS;
+    break;
   }
-  llvm_unreachable("Unsupported platform");
+
+  return TargetVersion < alignedAllocMinVersion(OS);
 }
 
 void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
@@ -2015,6 +2030,8 @@
   Res |= SanitizerKind::Address;
   Res |= SanitizerKind::Leak;
   Res |= SanitizerKind::Fuzzer;
+  Res |= SanitizerKind::FuzzerNoLink;
+  Res |= SanitizerKind::Function;
   if (isTargetMacOS()) {
     if (!isMacosxVersionLT(10, 9))
       Res |= SanitizerKind::Vptr;
diff --git a/lib/Driver/ToolChains/Darwin.h b/lib/Driver/ToolChains/Darwin.h
index 77c569e..3c6c740 100644
--- a/lib/Driver/ToolChains/Darwin.h
+++ b/lib/Driver/ToolChains/Darwin.h
@@ -152,10 +152,11 @@
                               llvm::opt::ArgStringList &CmdArgs) const {}
 
   /// Add the linker arguments to link the compiler runtime library.
+  ///
+  /// FIXME: This API is intended for use with embedded libraries only, and is
+  /// misleadingly named.
   virtual void AddLinkRuntimeLibArgs(const llvm::opt::ArgList &Args,
                                      llvm::opt::ArgStringList &CmdArgs) const;
-  virtual void AddFuzzerLinkArgs(const llvm::opt::ArgList &Args,
-                               llvm::opt::ArgStringList &CmdArgs) const;
 
   virtual void addStartObjectFileArgs(const llvm::opt::ArgList &Args,
                                       llvm::opt::ArgStringList &CmdArgs) const {
@@ -171,10 +172,26 @@
   /// Is the target either iOS or an iOS simulator?
   bool isTargetIOSBased() const { return false; }
 
+  /// Options to control how a runtime library is linked.
+  enum RuntimeLinkOptions : unsigned {
+    // Link the library in even if it can't be found in the VFS.
+    RLO_AlwaysLink = 1 << 0,
+
+    // Use the embedded runtime from the macho_embedded directory.
+    RLO_IsEmbedded = 1 << 1,
+
+    // Emit rpaths for @executable_path as well as the resource directory.
+    RLO_AddRPath = 1 << 2,
+
+    //< Link the library in before any others.
+    RLO_FirstLink = 1 << 3,
+  };
+
+  /// Add a runtime library to the list of items to link.
   void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
                          llvm::opt::ArgStringList &CmdArgs,
-                         StringRef DarwinLibName, bool AlwaysLink = false,
-                         bool IsEmbedded = false, bool AddRPath = false) const;
+                         StringRef DarwinLibName,
+                         RuntimeLinkOptions Opts = RuntimeLinkOptions()) const;
 
   /// Add any profiling runtime libraries that are needed. This is essentially a
   /// MachO specific version of addProfileRT in Tools.cpp.
@@ -489,7 +506,8 @@
 private:
   void AddLinkSanitizerLibArgs(const llvm::opt::ArgList &Args,
                                llvm::opt::ArgStringList &CmdArgs,
-                               StringRef Sanitizer) const;
+                               StringRef Sanitizer,
+                               bool shared = true) const;
 };
 
 } // end namespace toolchains
diff --git a/lib/Driver/ToolChains/DragonFly.cpp b/lib/Driver/ToolChains/DragonFly.cpp
index bd2c7fc..648469e 100644
--- a/lib/Driver/ToolChains/DragonFly.cpp
+++ b/lib/Driver/ToolChains/DragonFly.cpp
@@ -127,7 +127,8 @@
     }
 
     if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (getToolChain().ShouldLinkCXXStdlib(Args))
+        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
       CmdArgs.push_back("-lm");
     }
 
diff --git a/lib/Driver/ToolChains/FreeBSD.cpp b/lib/Driver/ToolChains/FreeBSD.cpp
index c6626e9..2f066cf 100644
--- a/lib/Driver/ToolChains/FreeBSD.cpp
+++ b/lib/Driver/ToolChains/FreeBSD.cpp
@@ -240,7 +240,8 @@
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     addOpenMPRuntime(CmdArgs, ToolChain, Args);
     if (D.CCCIsCXX()) {
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (ToolChain.ShouldLinkCXXStdlib(Args))
+        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
       if (Args.hasArg(options::OPT_pg))
         CmdArgs.push_back("-lm_p");
       else
diff --git a/lib/Driver/ToolChains/Fuchsia.cpp b/lib/Driver/ToolChains/Fuchsia.cpp
index 78053aa..b87d9f0 100644
--- a/lib/Driver/ToolChains/Fuchsia.cpp
+++ b/lib/Driver/ToolChains/Fuchsia.cpp
@@ -107,13 +107,15 @@
       CmdArgs.push_back("-Bdynamic");
 
     if (D.CCCIsCXX()) {
-      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
-                                 !Args.hasArg(options::OPT_static);
-      if (OnlyLibstdcxxStatic)
-        CmdArgs.push_back("-Bstatic");
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-      if (OnlyLibstdcxxStatic)
-        CmdArgs.push_back("-Bdynamic");
+      if (ToolChain.ShouldLinkCXXStdlib(Args)) {
+        bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+                                   !Args.hasArg(options::OPT_static);
+        if (OnlyLibstdcxxStatic)
+          CmdArgs.push_back("-Bstatic");
+        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+        if (OnlyLibstdcxxStatic)
+          CmdArgs.push_back("-Bdynamic");
+      }
       CmdArgs.push_back("-lm");
     }
 
diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp
index 72a9f85..5155ce3 100644
--- a/lib/Driver/ToolChains/Gnu.cpp
+++ b/lib/Driver/ToolChains/Gnu.cpp
@@ -560,13 +560,15 @@
 
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
-                               !Args.hasArg(options::OPT_static);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
-    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
+    if (ToolChain.ShouldLinkCXXStdlib(Args)) {
+      bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
+                                 !Args.hasArg(options::OPT_static);
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bstatic");
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bdynamic");
+    }
     CmdArgs.push_back("-lm");
   }
   // Silence warnings when linking C code with a C++ '-stdlib' argument.
diff --git a/lib/Driver/ToolChains/Hexagon.cpp b/lib/Driver/ToolChains/Hexagon.cpp
index 9bf1590..4f62b1f 100644
--- a/lib/Driver/ToolChains/Hexagon.cpp
+++ b/lib/Driver/ToolChains/Hexagon.cpp
@@ -248,7 +248,8 @@
   //----------------------------------------------------------------------------
   if (IncStdLib && IncDefLibs) {
     if (D.CCCIsCXX()) {
-      HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (HTC.ShouldLinkCXXStdlib(Args))
+        HTC.AddCXXStdlibLibArgs(Args, CmdArgs);
       CmdArgs.push_back("-lm");
     }
 
diff --git a/lib/Driver/ToolChains/Linux.cpp b/lib/Driver/ToolChains/Linux.cpp
index 08a27fa..1adf9f7 100644
--- a/lib/Driver/ToolChains/Linux.cpp
+++ b/lib/Driver/ToolChains/Linux.cpp
@@ -828,6 +828,7 @@
   SanitizerMask Res = ToolChain::getSupportedSanitizers();
   Res |= SanitizerKind::Address;
   Res |= SanitizerKind::Fuzzer;
+  Res |= SanitizerKind::FuzzerNoLink;
   Res |= SanitizerKind::KernelAddress;
   Res |= SanitizerKind::Vptr;
   Res |= SanitizerKind::SafeStack;
diff --git a/lib/Driver/ToolChains/MinGW.cpp b/lib/Driver/ToolChains/MinGW.cpp
index 632b76d..b84c6ee 100644
--- a/lib/Driver/ToolChains/MinGW.cpp
+++ b/lib/Driver/ToolChains/MinGW.cpp
@@ -185,8 +185,7 @@
 
   // TODO: Add profile stuff here
 
-  if (D.CCCIsCXX() &&
-      !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
+  if (TC.ShouldLinkCXXStdlib(Args)) {
     bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) &&
                                !Args.hasArg(options::OPT_static);
     if (OnlyLibstdcxxStatic)
diff --git a/lib/Driver/ToolChains/Minix.cpp b/lib/Driver/ToolChains/Minix.cpp
index 2e8939c..39e6f90 100644
--- a/lib/Driver/ToolChains/Minix.cpp
+++ b/lib/Driver/ToolChains/Minix.cpp
@@ -72,7 +72,8 @@
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (getToolChain().ShouldLinkCXXStdlib(Args))
+        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
       CmdArgs.push_back("-lm");
     }
   }
diff --git a/lib/Driver/ToolChains/NaCl.cpp b/lib/Driver/ToolChains/NaCl.cpp
index 5eb5c74..128478d 100644
--- a/lib/Driver/ToolChains/NaCl.cpp
+++ b/lib/Driver/ToolChains/NaCl.cpp
@@ -133,13 +133,15 @@
 
   if (D.CCCIsCXX() &&
       !Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    bool OnlyLibstdcxxStatic =
-        Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bstatic");
-    ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
-    if (OnlyLibstdcxxStatic)
-      CmdArgs.push_back("-Bdynamic");
+    if (ToolChain.ShouldLinkCXXStdlib(Args)) {
+      bool OnlyLibstdcxxStatic =
+          Args.hasArg(options::OPT_static_libstdcxx) && !IsStatic;
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bstatic");
+      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (OnlyLibstdcxxStatic)
+        CmdArgs.push_back("-Bdynamic");
+    }
     CmdArgs.push_back("-lm");
   }
 
diff --git a/lib/Driver/ToolChains/NetBSD.cpp b/lib/Driver/ToolChains/NetBSD.cpp
index a1a3108..9cb0468 100644
--- a/lib/Driver/ToolChains/NetBSD.cpp
+++ b/lib/Driver/ToolChains/NetBSD.cpp
@@ -278,7 +278,8 @@
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     addOpenMPRuntime(CmdArgs, getToolChain(), Args);
     if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (getToolChain().ShouldLinkCXXStdlib(Args))
+        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
       CmdArgs.push_back("-lm");
     }
     if (NeedsSanitizerDeps)
diff --git a/lib/Driver/ToolChains/OpenBSD.cpp b/lib/Driver/ToolChains/OpenBSD.cpp
index 1d54a1e..fbb84a6 100644
--- a/lib/Driver/ToolChains/OpenBSD.cpp
+++ b/lib/Driver/ToolChains/OpenBSD.cpp
@@ -179,7 +179,8 @@
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
     if (D.CCCIsCXX()) {
-      getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (getToolChain().ShouldLinkCXXStdlib(Args))
+        getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
       if (Args.hasArg(options::OPT_pg))
         CmdArgs.push_back("-lm_p");
       else
diff --git a/lib/Driver/ToolChains/PS4CPU.cpp b/lib/Driver/ToolChains/PS4CPU.cpp
index c1b8c3d..b37fe7d 100644
--- a/lib/Driver/ToolChains/PS4CPU.cpp
+++ b/lib/Driver/ToolChains/PS4CPU.cpp
@@ -227,7 +227,8 @@
     // libraries for both C and C++ compilations.
     CmdArgs.push_back("-lkernel");
     if (D.CCCIsCXX()) {
-      ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
+      if (ToolChain.ShouldLinkCXXStdlib(Args))
+        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
       if (Args.hasArg(options::OPT_pg))
         CmdArgs.push_back("-lm_p");
       else
diff --git a/lib/Driver/ToolChains/Solaris.cpp b/lib/Driver/ToolChains/Solaris.cpp
index de98d11..9fe6e9d 100644
--- a/lib/Driver/ToolChains/Solaris.cpp
+++ b/lib/Driver/ToolChains/Solaris.cpp
@@ -100,7 +100,7 @@
   AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (getToolChain().getDriver().CCCIsCXX())
+    if (getToolChain().ShouldLinkCXXStdlib(Args))
       getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
     CmdArgs.push_back("-lgcc_s");
     CmdArgs.push_back("-lc");
diff --git a/lib/Driver/ToolChains/WebAssembly.cpp b/lib/Driver/ToolChains/WebAssembly.cpp
index 058bc42..88a3f1b 100644
--- a/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/lib/Driver/ToolChains/WebAssembly.cpp
@@ -38,7 +38,6 @@
                                 const char *LinkingOutput) const {
 
   const ToolChain &ToolChain = getToolChain();
-  const Driver &D = ToolChain.getDriver();
   const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
   ArgStringList CmdArgs;
   CmdArgs.push_back("-flavor");
@@ -77,7 +76,7 @@
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
-    if (D.CCCIsCXX())
+    if (ToolChain.ShouldLinkCXXStdlib(Args))
       ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
 
     if (Args.hasArg(options::OPT_pthread))
diff --git a/lib/Edit/CMakeLists.txt b/lib/Edit/CMakeLists.txt
index a7fa9c2..99aff3c 100644
--- a/lib/Edit/CMakeLists.txt
+++ b/lib/Edit/CMakeLists.txt
@@ -5,6 +5,8 @@
 add_clang_library(clangEdit
   Commit.cpp
   EditedSource.cpp
+  FillInMissingProtocolStubs.cpp
+  FillInMissingSwitchEnumCases.cpp
   RewriteObjCFoundationAPI.cpp
 
   LINK_LIBS
diff --git a/lib/Edit/FillInMissingProtocolStubs.cpp b/lib/Edit/FillInMissingProtocolStubs.cpp
new file mode 100644
index 0000000..64843e5
--- /dev/null
+++ b/lib/Edit/FillInMissingProtocolStubs.cpp
@@ -0,0 +1,466 @@
+//===--- FillInMissingProtocolStubs.cpp -  --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the "Add methods from protocol(s)" refactoring operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/NSAPI.h"
+#include "clang/Edit/RefactoringFixits.h"
+#include "clang/Lex/Lexer.h"
+#include "llvm/ADT/DenseSet.h"
+#include <algorithm>
+
+using namespace clang;
+using namespace edit;
+using namespace fillInMissingProtocolStubs;
+
+// FIXME: This is duplicated with the refactoring lib.
+static bool areOnSameLine(SourceLocation Loc1, SourceLocation Loc2,
+                          const SourceManager &SM) {
+  return !Loc1.isMacroID() && !Loc2.isMacroID() &&
+         SM.getSpellingLineNumber(Loc1) == SM.getSpellingLineNumber(Loc2);
+}
+
+static bool isSemicolonAtLocation(SourceLocation TokenLoc,
+                                  const SourceManager &SM,
+                                  const LangOptions &LangOpts) {
+  return Lexer::getSourceText(
+             CharSourceRange::getTokenRange(TokenLoc, TokenLoc), SM,
+             LangOpts) == ";";
+}
+
+static SourceLocation getLocationOfPrecedingToken(SourceLocation Loc,
+                                                  const SourceManager &SM,
+                                                  const LangOptions &LangOpts) {
+  SourceLocation Result = Loc;
+  if (Result.isMacroID())
+    Result = SM.getExpansionLoc(Result);
+  FileID FID = SM.getFileID(Result);
+  SourceLocation StartOfFile = SM.getLocForStartOfFile(FID);
+  if (Loc == StartOfFile)
+    return SourceLocation();
+  return Lexer::GetBeginningOfToken(Result.getLocWithOffset(-1), SM, LangOpts);
+}
+
+static SourceLocation
+getLastLineLocationUnlessItHasOtherTokens(SourceLocation SpellingLoc,
+                                          const SourceManager &SM,
+                                          const LangOptions &LangOpts) {
+  assert(!SpellingLoc.isMacroID() && "Expecting a spelling location");
+  SourceLocation NextTokenLoc =
+      Lexer::findNextTokenLocationAfterTokenAt(SpellingLoc, SM, LangOpts);
+  if (NextTokenLoc.isValid()) {
+    bool IsSameLine = areOnSameLine(SpellingLoc, NextTokenLoc, SM);
+    if (IsSameLine) {
+      // Could be a ';' on the same line, so try looking after the ';'
+      if (isSemicolonAtLocation(NextTokenLoc, SM, LangOpts))
+        return getLastLineLocationUnlessItHasOtherTokens(NextTokenLoc, SM,
+                                                         LangOpts);
+    } else {
+      SourceLocation LastLoc = SM.translateLineCol(
+          SM.getFileID(SpellingLoc), SM.getSpellingLineNumber(SpellingLoc),
+          std::numeric_limits<unsigned>::max());
+      if (LastLoc.isValid())
+        return LastLoc;
+    }
+  }
+  return Lexer::getLocForEndOfToken(SpellingLoc, 0, SM, LangOpts);
+}
+
+namespace {
+
+struct ProtocolInfo {
+  /// The lower the priority, the more important this protocol is considered to
+  /// be. Typically protocols from the class have lower priority than protocols
+  /// from superclasses.
+  int Priority;
+};
+
+using ProtocolMapTy = llvm::DenseMap<const ObjCProtocolDecl *, ProtocolInfo>;
+
+/// Contains the set of methods from all the protocols that the class conforms
+/// to.
+class MethodSet {
+public:
+  struct MethodInfo {
+    const ObjCMethodDecl *M;
+    const ObjCProtocolDecl *P;
+    int ProtocolPriority;
+    enum MethodPresenceKind { IsDeclared = 0x1, IsImplemented = 0x2 };
+    unsigned PresenceKind = 0;
+    const ObjCMethodDecl *DeclaredOrImplementedMethod = nullptr;
+
+    MethodInfo(const ObjCMethodDecl *M, const ObjCProtocolDecl *P,
+               int ProtocolPriority)
+        : M(M), P(P), ProtocolPriority(ProtocolPriority) {}
+
+    bool isRequired() const {
+      return M->getImplementationControl() == ObjCMethodDecl::Required;
+    }
+    void markAs(MethodPresenceKind Kind) { PresenceKind |= Kind; }
+    bool is(MethodPresenceKind Kind) const {
+      return (PresenceKind & Kind) == Kind;
+    }
+  };
+
+private:
+  llvm::DenseMap<Selector, MethodInfo> InstanceMethods;
+  llvm::DenseMap<Selector, MethodInfo> ClassMethods;
+
+  void markMethodsFrom(const ObjCContainerDecl *Container,
+                       MethodInfo::MethodPresenceKind Kind) {
+    for (const ObjCMethodDecl *M : Container->methods()) {
+      auto &Map = M->isInstanceMethod() ? InstanceMethods : ClassMethods;
+      auto It = Map.find(M->getSelector());
+      if (It != Map.end()) {
+        It->second.markAs(Kind);
+        if (!It->second.DeclaredOrImplementedMethod)
+          It->second.DeclaredOrImplementedMethod = M;
+      }
+    }
+  }
+
+public:
+  MethodSet() {}
+  MethodSet(MethodSet &&Other) = default;
+  MethodSet &operator=(MethodSet &&Other) = default;
+
+  void gatherMethodsFrom(const ObjCProtocolDecl *P, int Priority) {
+    for (const ObjCMethodDecl *M : P->methods()) {
+      if (M->isImplicit())
+        continue;
+      AvailabilityResult Availability = M->getAvailability();
+      // Methods that are unavailable or not yet introduced are not considered
+      // to be required.
+      if (Availability == AR_NotYetIntroduced || Availability == AR_Unavailable)
+        continue;
+      auto &Map = M->isInstanceMethod() ? InstanceMethods : ClassMethods;
+      Map.insert(std::make_pair(M->getSelector(), MethodInfo(M, P, Priority)));
+    }
+  }
+
+  void markImplementedMethods(const ObjCContainerDecl *Container) {
+    assert(isa<ObjCImplDecl>(Container) && "Not an implementation container");
+    markMethodsFrom(Container, MethodInfo::IsImplemented);
+    if (const auto *ID = dyn_cast<ObjCImplementationDecl>(Container)) {
+      const auto *I = ID->getClassInterface();
+      // Mark declarations from super-classes as implemented to prevent
+      // redundant implementations.
+      while ((I = I->getSuperClass()))
+        markMethodsFrom(I, MethodInfo::IsImplemented);
+    }
+  }
+
+  void markDeclaredMethods(const ObjCContainerDecl *Container) {
+    assert(!isa<ObjCImplDecl>(Container) && "Not an interface container");
+    markMethodsFrom(Container, MethodInfo::IsDeclared);
+    // Mark declarations from super-classes as declared to prevent redundant
+    // declarations.
+    if (const auto *I = dyn_cast<ObjCInterfaceDecl>(Container)) {
+      while ((I = I->getSuperClass()))
+        markMethodsFrom(I, MethodInfo::IsDeclared);
+    }
+  }
+
+  /// Returns true if the given container has missing @required method stubs.
+  ///
+  /// For @interfaces, this method returns true when the interface is missing
+  /// a declaration for any @required method in all of the protocols.
+  /// For @implementations, this method returns true when the implementation is
+  /// missing an implementation of any @required method in all of the protocols.
+  bool hasMissingRequiredMethodStubs(const ObjCContainerDecl *Container) {
+    MethodInfo::MethodPresenceKind Kind = isa<ObjCImplDecl>(Container)
+                                              ? MethodInfo::IsImplemented
+                                              : MethodInfo::IsDeclared;
+    for (const auto &I : InstanceMethods) {
+      if (!I.second.isRequired())
+        continue;
+      if (!I.second.is(Kind))
+        return true;
+    }
+    for (const auto &I : ClassMethods) {
+      if (!I.second.isRequired())
+        continue;
+      if (!I.second.is(Kind))
+        return true;
+    }
+    return false;
+  }
+
+  std::vector<MethodInfo>
+  getMissingRequiredMethods(const ObjCContainerDecl *Container) {
+    MethodInfo::MethodPresenceKind Kind = isa<ObjCImplDecl>(Container)
+                                              ? MethodInfo::IsImplemented
+                                              : MethodInfo::IsDeclared;
+    std::vector<MethodInfo> Results;
+    for (const auto &I : InstanceMethods) {
+      if (!I.second.isRequired())
+        continue;
+      if (!I.second.is(Kind))
+        Results.push_back(I.second);
+    }
+    for (const auto &I : ClassMethods) {
+      if (!I.second.isRequired())
+        continue;
+      if (!I.second.is(Kind))
+        Results.push_back(I.second);
+    }
+    return Results;
+  }
+
+  SourceLocation findLocationForInsertionForMethodsFromProtocol(
+      const ObjCProtocolDecl *P, const ObjCContainerDecl *Container,
+      const SourceManager &SM, const LangOptions &LangOpts) {
+    MethodInfo::MethodPresenceKind Kind = isa<ObjCImplDecl>(Container)
+                                              ? MethodInfo::IsImplemented
+                                              : MethodInfo::IsDeclared;
+    llvm::SmallVector<const ObjCMethodDecl *, 4> MethodsFromProtocolInContainer;
+    for (const ObjCMethodDecl *M : P->methods()) {
+      if (M->isImplicit())
+        continue;
+      const auto &Map = M->isInstanceMethod() ? InstanceMethods : ClassMethods;
+      auto It = Map.find(M->getSelector());
+      if (It == Map.end())
+        continue;
+      if (!It->second.is(Kind))
+        continue;
+      const ObjCMethodDecl *ContainerMethod =
+          It->second.DeclaredOrImplementedMethod;
+      // Ignore method declarations from superclasses.
+      if (ContainerMethod->getLexicalDeclContext() != Container)
+        continue;
+      // This is a method from the given protocol that either declared or
+      // implemented in the container.
+      MethodsFromProtocolInContainer.push_back(ContainerMethod);
+    }
+    // Find the appropriate source locations by looking
+    if (MethodsFromProtocolInContainer.empty())
+      return SourceLocation();
+    SourceLocation Loc = MethodsFromProtocolInContainer[0]->getLocEnd();
+    if (Loc.isMacroID())
+      Loc = SM.getExpansionRange(Loc).second;
+    for (const ObjCMethodDecl *M :
+         makeArrayRef(MethodsFromProtocolInContainer).drop_front()) {
+      SourceLocation EndLoc = M->getLocEnd();
+      if (EndLoc.isMacroID())
+        EndLoc = SM.getExpansionRange(EndLoc).second;
+      if (SM.isBeforeInTranslationUnit(Loc, EndLoc))
+        Loc = EndLoc;
+    }
+    return getLastLineLocationUnlessItHasOtherTokens(Loc, SM, LangOpts);
+  }
+};
+
+} // end anonymous namespace
+
+namespace clang {
+namespace edit {
+namespace fillInMissingProtocolStubs {
+
+class FillInMissingProtocolStubsImpl {
+public:
+  const ObjCContainerDecl *Container;
+  MethodSet Methods;
+};
+
+} // end namespace fillInMissingProtocolStubsImpl
+} // end namespace edit
+} // end namespace clang
+
+static void gatherProtocols(
+    llvm::iterator_range<ObjCList<ObjCProtocolDecl>::iterator> Protocols,
+    NSAPI &API, ProtocolMapTy &Result, int &Priority) {
+  for (const ObjCProtocolDecl *P : Protocols) {
+    // Ignore the 'NSObject' protocol.
+    if (API.getNSClassId(NSAPI::ClassId_NSObject) == P->getIdentifier())
+      continue;
+    gatherProtocols(P->protocols(), API, Result, Priority);
+    Result.insert(std::make_pair(P, ProtocolInfo{Priority++}));
+  }
+}
+
+static ProtocolMapTy
+gatherSuitableClassProtocols(const ObjCInterfaceDecl *I,
+                             const ObjCContainerDecl *Container, NSAPI &API) {
+  ProtocolMapTy Result;
+  // The class of interest should use the protocols from extensions when the
+  // operation is initiated from the @implementation / extension.
+  auto ClassProtocols =
+      Container == I ? I->protocols() : I->all_referenced_protocols();
+  int Priority = 0;
+  gatherProtocols(ClassProtocols, API, Result, Priority);
+  while ((I = I->getSuperClass()))
+    gatherProtocols(I->protocols(), API, Result, Priority);
+  return Result;
+}
+
+static const ObjCContainerDecl *
+getInterfaceOrCategory(const ObjCContainerDecl *Container) {
+  if (const auto *Impl = dyn_cast<ObjCImplementationDecl>(Container))
+    return Impl->getClassInterface();
+  if (const auto *CategoryImpl = dyn_cast<ObjCCategoryImplDecl>(Container))
+    return CategoryImpl->getCategoryDecl();
+  return Container;
+}
+
+static bool initiate(FillInMissingProtocolStubsImpl &Dest, ASTContext &Context,
+                     const ObjCContainerDecl *Container) {
+  const ObjCContainerDecl *ContainerProtocolSource =
+      getInterfaceOrCategory(Container);
+  if (!ContainerProtocolSource)
+    return false;
+
+  // The protocols that are specified in the @interface and/or in the
+  // superclasses.
+  ProtocolMapTy Protocols;
+  NSAPI API(Context);
+  if (const auto *I = dyn_cast<ObjCInterfaceDecl>(ContainerProtocolSource)) {
+    if (!I->hasDefinition())
+      return false;
+    Protocols = gatherSuitableClassProtocols(I, Container, API);
+    if (Protocols.empty())
+      return false;
+  } else if (const auto *I =
+                 dyn_cast<ObjCCategoryDecl>(ContainerProtocolSource)) {
+    int Priority = 0;
+    gatherProtocols(I->protocols(), API, Protocols, Priority);
+    if (Protocols.empty())
+      return false;
+  }
+
+  // Check if there are missing @required methods.
+  for (const auto &P : Protocols)
+    Dest.Methods.gatherMethodsFrom(P.first, P.second.Priority);
+  if (isa<ObjCImplDecl>(Container))
+    Dest.Methods.markImplementedMethods(Container);
+  else
+    Dest.Methods.markDeclaredMethods(Container);
+
+  Dest.Container = Container;
+  return true;
+}
+
+FillInMissingProtocolStubs::FillInMissingProtocolStubs() {}
+FillInMissingProtocolStubs::~FillInMissingProtocolStubs() {}
+FillInMissingProtocolStubs::FillInMissingProtocolStubs(
+    FillInMissingProtocolStubs &&Other)
+    : Impl(std::move(Other.Impl)) {}
+FillInMissingProtocolStubs &FillInMissingProtocolStubs::
+operator=(FillInMissingProtocolStubs &&Other) {
+  Impl = std::move(Other.Impl);
+  return *this;
+}
+
+bool FillInMissingProtocolStubs::initiate(ASTContext &Context,
+                                          const ObjCContainerDecl *Container) {
+  Impl = llvm::make_unique<FillInMissingProtocolStubsImpl>();
+  if (!::initiate(*Impl, Context, Container))
+    return true;
+  return false;
+}
+
+bool FillInMissingProtocolStubs::hasMissingRequiredMethodStubs() {
+  return Impl->Methods.hasMissingRequiredMethodStubs(Impl->Container);
+}
+
+static void perform(MethodSet &Methods, const ObjCContainerDecl *Container,
+                    ASTContext &Context,
+                    llvm::function_ref<void(const FixItHint &)> Consumer) {
+  auto MissingMethods = Methods.getMissingRequiredMethods(Container);
+  // Sort the methods by grouping them into protocol clusters and then sorting
+  // them alphabetically within the same protocol.
+  std::sort(MissingMethods.begin(), MissingMethods.end(),
+            [](const MethodSet::MethodInfo &A, const MethodSet::MethodInfo &B) {
+              if (A.ProtocolPriority == B.ProtocolPriority)
+                return A.M->getSelector().getAsString() <
+                       B.M->getSelector().getAsString();
+              assert(A.P != B.P && "Same protocols should have same priority");
+              return A.ProtocolPriority < B.ProtocolPriority;
+            });
+
+  SourceLocation InsertionLoc =
+      isa<ObjCImplDecl>(Container)
+          ? Container->getLocEnd()
+          : getLocationOfPrecedingToken(Container->getLocEnd(),
+                                        Context.getSourceManager(),
+                                        Context.getLangOpts());
+  if (InsertionLoc.isInvalid())
+    InsertionLoc = Container->getLocEnd();
+
+  PrintingPolicy PP = Context.getPrintingPolicy();
+  PP.PolishForDeclaration = true;
+  PP.SuppressStrongLifetime = true;
+  PP.SuppressLifetimeQualifiers = true;
+  PP.SuppressUnwrittenScope = true;
+
+  std::string EndInsertionOSStr;
+  llvm::raw_string_ostream EndInsertionOS(EndInsertionOSStr);
+
+  std::string InsertionGroupStr;
+  llvm::raw_string_ostream InsertionGroupOS(InsertionGroupStr);
+
+  const ObjCProtocolDecl *CurrentProtocol = nullptr;
+  SourceLocation CurrentProtocolInsertionLoc;
+  bool IsImplementation = isa<ObjCImplDecl>(Container);
+  for (const auto &Method : MissingMethods) {
+    const ObjCProtocolDecl *P = Method.P;
+    if (CurrentProtocol != P) {
+      if (!InsertionGroupOS.str().empty()) {
+        assert(CurrentProtocolInsertionLoc.isValid());
+        Consumer(FixItHint::CreateInsertion(CurrentProtocolInsertionLoc,
+                                            InsertionGroupOS.str()));
+      }
+      InsertionGroupStr.clear();
+      CurrentProtocol = P;
+      CurrentProtocolInsertionLoc =
+          Methods.findLocationForInsertionForMethodsFromProtocol(
+              P, Container, Context.getSourceManager(), Context.getLangOpts());
+    }
+    bool IsInsertingAfterRelatedMethods = CurrentProtocolInsertionLoc.isValid();
+    raw_ostream &OS =
+        IsInsertingAfterRelatedMethods ? InsertionGroupOS : EndInsertionOS;
+
+    std::string MethodDeclStr;
+    llvm::raw_string_ostream MethodOS(MethodDeclStr);
+    Method.M->print(MethodOS, PP);
+    if (IsInsertingAfterRelatedMethods)
+      OS << "\n\n";
+    OS << StringRef(MethodOS.str()).drop_back(); // Drop the ';'
+    if (IsImplementation)
+      OS << " { \n  <#code#>\n}\n";
+    else
+      OS << ";\n";
+    if (!IsInsertingAfterRelatedMethods)
+      OS << "\n";
+  }
+  if (!InsertionGroupOS.str().empty()) {
+    assert(CurrentProtocolInsertionLoc.isValid());
+    Consumer(FixItHint::CreateInsertion(CurrentProtocolInsertionLoc,
+                                        InsertionGroupOS.str()));
+  }
+  if (!EndInsertionOS.str().empty())
+    Consumer(FixItHint::CreateInsertion(InsertionLoc, EndInsertionOS.str()));
+}
+
+void FillInMissingProtocolStubs::perform(
+    ASTContext &Context, llvm::function_ref<void(const FixItHint &)> Consumer) {
+  ::perform(Impl->Methods, Impl->Container, Context, Consumer);
+}
+
+void fillInMissingProtocolStubs::addMissingProtocolStubs(
+    ASTContext &Context, const ObjCContainerDecl *Container,
+    llvm::function_ref<void(const FixItHint &)> Consumer) {
+  FillInMissingProtocolStubsImpl Impl;
+  if (initiate(Impl, Context, Container))
+    perform(Impl.Methods, Impl.Container, Context, Consumer);
+}
diff --git a/lib/Edit/FillInMissingSwitchEnumCases.cpp b/lib/Edit/FillInMissingSwitchEnumCases.cpp
new file mode 100644
index 0000000..c6d5934
--- /dev/null
+++ b/lib/Edit/FillInMissingSwitchEnumCases.cpp
@@ -0,0 +1,192 @@
+//===--- FillInMissingSwitchEnumCases.cpp -  ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/Edit/RefactoringFixits.h"
+#include <unordered_map>
+
+using namespace clang;
+
+namespace {
+
+struct CaseInfo {
+  const SwitchCase *Case, *NextCase;
+  unsigned Index;
+};
+typedef std::unordered_map<int64_t, CaseInfo> CoveredEnumCasesInfoType;
+
+/// Return true if the ordering of the covered enum cases is similar to the
+/// order of the enum case constants that are defined in the enum.
+bool useCaseBasedOrdering(const ArrayRef<int64_t> &CoveredEnumCaseValues,
+                          const CoveredEnumCasesInfoType &CoveredEnumCases) {
+  if (CoveredEnumCaseValues.empty())
+    return false;
+  for (const auto &I : llvm::enumerate(CoveredEnumCaseValues)) {
+    auto It = CoveredEnumCases.find(I.value());
+    if (It == CoveredEnumCases.end())
+      return false;
+    const CaseInfo &Case = It->second;
+    if (Case.Index != I.index())
+      return false;
+  }
+  return true;
+}
+
+/// Determine if the inserted cases should be wrapped in braces using a simple
+/// heuristic:
+///   Wrap only if at least 90% of existing cases use braces.
+bool useBraces(const SwitchStmt *S) {
+  unsigned CaseCount = 0, CompoundCasesCount = 0;
+  for (const SwitchCase *Case = S->getSwitchCaseList(); Case;
+       Case = Case->getNextSwitchCase(), ++CaseCount) {
+    if (!Case->getSubStmt())
+      continue;
+    if (isa<CompoundStmt>(Case->getSubStmt()))
+      ++CompoundCasesCount;
+  }
+  return CaseCount && float(CompoundCasesCount) / float(CaseCount) >= 0.9;
+}
+
+} // end anonymous namespace
+
+void edit::fillInMissingSwitchEnumCases(
+    ASTContext &Context, const SwitchStmt *Switch, const EnumDecl *Enum,
+    const DeclContext *SwitchContext,
+    llvm::function_ref<void(const FixItHint &)> Consumer) {
+  // Compute the number of cases in the switch.
+  unsigned CaseCount = 0;
+  for (const SwitchCase *Case = Switch->getSwitchCaseList(); Case;
+       Case = Case->getNextSwitchCase())
+    ++CaseCount;
+
+  // Compute the set of enum values that are covered by the switch.
+  CoveredEnumCasesInfoType CoveredEnumCases;
+  const SwitchCase *DefaultCase = nullptr;
+  const SwitchCase *FirstCoveredEnumCase = nullptr;
+  const SwitchCase *NextCase = nullptr;
+  unsigned CaseIndex = CaseCount;
+  for (const SwitchCase *Case = Switch->getSwitchCaseList(); Case;
+       NextCase = Case, Case = Case->getNextSwitchCase()) {
+    // The cases in the switch are ordered back to front, so the index has
+    // to be reversed.
+    --CaseIndex;
+    if (isa<DefaultStmt>(Case)) {
+      DefaultCase = Case;
+      continue;
+    }
+    const auto *CS = cast<CaseStmt>(Case);
+    if (const auto *LHS = CS->getLHS()) {
+      llvm::APSInt Value;
+      if (!LHS->EvaluateAsInt(Value, Context))
+        continue;
+      // Only allow constant that fix into 64 bits.
+      if (Value.getMinSignedBits() > 64)
+        continue;
+      CoveredEnumCases[Value.getSExtValue()] =
+          CaseInfo{Case, NextCase, CaseIndex};
+      // The cases in the switch are ordered back to front, so the last
+      //  case is actually the first enum case in the switch.
+      FirstCoveredEnumCase = Case;
+    }
+  }
+
+  // Wrap the inserted cases in braces using a simple heuristic:
+  //   Wrap only if at least 90% of existing cases use braces.
+  bool WrapInBraces = useBraces(Switch);
+  auto CreateReplacementForMissingCaseGroup =
+      [&](ArrayRef<const EnumConstantDecl *> UncoveredEnumCases,
+          SourceLocation InsertionLoc = SourceLocation()) {
+        if (UncoveredEnumCases.empty())
+          return;
+        std::string Result;
+        llvm::raw_string_ostream OS(Result);
+        for (const auto *EnumCase : UncoveredEnumCases) {
+          OS << "case ";
+          if (SwitchContext) {
+            const auto *NS = NestedNameSpecifier::getRequiredQualification(
+                Context, SwitchContext, Enum->getLexicalDeclContext());
+            if (NS)
+              NS->print(OS, Context.getPrintingPolicy());
+          }
+          if (Enum->isScoped())
+            OS << Enum->getName() << "::";
+          OS << EnumCase->getName() << ":";
+          if (WrapInBraces)
+            OS << " {";
+          OS << "\n<#code#>\nbreak;\n";
+          if (WrapInBraces)
+            OS << "}\n";
+        }
+
+        if (InsertionLoc.isInvalid()) {
+          // Insert the cases before the 'default' if it's the last case in the
+          // switch.
+          // Note: Switch cases are ordered back to front, so the last default
+          // case would be the first case in the switch statement.
+          if (DefaultCase && DefaultCase == Switch->getSwitchCaseList())
+            InsertionLoc = DefaultCase->getLocStart();
+          else
+            InsertionLoc = Switch->getBody()->getLocEnd();
+        }
+        Consumer(FixItHint::CreateInsertion(
+            Context.getSourceManager().getSpellingLoc(InsertionLoc), OS.str()));
+      };
+
+  // Determine which enum cases are uncovered.
+
+  llvm::SmallVector<std::pair<const EnumConstantDecl *, int64_t>, 8> EnumCases;
+  llvm::SmallVector<int64_t, 8> CoveredEnumCaseValues;
+  for (const auto *EnumCase : Enum->enumerators()) {
+    if (EnumCase->getInitVal().getMinSignedBits() > 64)
+      continue;
+    int64_t Value = EnumCase->getInitVal().getSExtValue();
+    EnumCases.push_back(std::make_pair(EnumCase, Value));
+    if (CoveredEnumCases.count(Value))
+      CoveredEnumCaseValues.push_back(Value);
+  }
+
+  llvm::SmallVector<const EnumConstantDecl *, 8> UncoveredEnumCases;
+  // Figure out if the ordering of the covered enum cases is similar to the
+  // order of enum case values defined in the enum.
+  if (useCaseBasedOrdering(CoveredEnumCaseValues, CoveredEnumCases)) {
+    // Start inserting before the first covered case.
+    SourceLocation InsertionLoc = FirstCoveredEnumCase->getLocStart();
+
+    for (const auto &EnumCase : EnumCases) {
+      if (!CoveredEnumCases.count(EnumCase.second)) {
+        UncoveredEnumCases.push_back(EnumCase.first);
+        continue;
+      }
+      // Create the insertion source replacement for this set of uncovered
+      // cases.
+      CreateReplacementForMissingCaseGroup(UncoveredEnumCases, InsertionLoc);
+      UncoveredEnumCases.clear();
+      // Find the insertion location for the next set of uncovered cases.
+      auto It = CoveredEnumCases.find(EnumCase.second);
+      assert(It != CoveredEnumCases.end() && "Missing enum case");
+      const CaseInfo &Case = It->second;
+      InsertionLoc = Case.NextCase ? Case.NextCase->getLocStart()
+                                   : /*Insert before end*/ SourceLocation();
+    }
+    CreateReplacementForMissingCaseGroup(UncoveredEnumCases, InsertionLoc);
+  } else {
+    // Gather all of the uncovered enum cases.
+    for (const auto &EnumCase : EnumCases) {
+      if (!CoveredEnumCases.count(EnumCase.second))
+        UncoveredEnumCases.push_back(EnumCase.first);
+    }
+    assert(!UncoveredEnumCases.empty() &&
+           "Can't fill-in enum cases in a full switch");
+    CreateReplacementForMissingCaseGroup(UncoveredEnumCases);
+  }
+}
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 1094e6d..a6f812a 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -542,6 +542,9 @@
     // Initialize the ASTContext
     Context->InitBuiltinTypes(*Target);
 
+    // Adjust printing policy based on language options.
+    Context->setPrintingPolicy(PrintingPolicy(LangOpt));
+
     // We didn't have access to the comment options when the ASTContext was
     // constructed, so register them now.
     Context->getCommentCommandTraits().registerCommentOptions(
diff --git a/lib/Frontend/CMakeLists.txt b/lib/Frontend/CMakeLists.txt
index ba3bd7d..da6a161 100644
--- a/lib/Frontend/CMakeLists.txt
+++ b/lib/Frontend/CMakeLists.txt
@@ -53,6 +53,7 @@
   ${optional_deps}
 
   LINK_LIBS
+  clangAPINotes
   clangAST
   clangBasic
   clangDriver
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index bb6a665..3cfb9d7 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/APINotes/APINotesReader.h"
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
@@ -28,6 +29,7 @@
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/Frontend/VerifyDiagnosticConsumer.h"
+#include "clang/Index/IndexingAction.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/PTHManager.h"
 #include "clang/Lex/Preprocessor.h"
@@ -472,7 +474,7 @@
   SmallString<256> SpecificModuleCache(getHeaderSearchOpts().ModuleCachePath);
   if (!SpecificModuleCache.empty() && !getHeaderSearchOpts().DisableModuleHash)
     llvm::sys::path::append(SpecificModuleCache,
-                            getInvocation().getModuleHash());
+                            getInvocation().getModuleHash(getDiagnostics()));
   return SpecificModuleCache.str();
 }
 
@@ -632,6 +634,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());
@@ -1100,9 +1123,11 @@
   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.  Since we're sharing a PCMCache,
   // CompilerInstance::CompilerInstance is responsible for finalizing the
@@ -1128,6 +1153,10 @@
   SourceMgr.pushModuleBuildStack(ModuleName,
     FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));
 
+  // Pass along the GenModuleActionWrapper callback
+  auto wrapGenModuleAction = ImportingInstance.getGenModuleActionWrapper();
+  Instance.setGenModuleActionWrapper(wrapGenModuleAction);
+
   // If we're collecting module dependencies, we need to share a collector
   // between all of the module CompilerInstances. Other than that, we don't
   // want to produce any dependency output from the module build.
@@ -1146,8 +1175,14 @@
   llvm::CrashRecoveryContext CRC;
   CRC.RunSafelyOnThread(
       [&]() {
-        GenerateModuleFromModuleMapAction Action;
-        Instance.ExecuteAction(Action);
+        // FIXME: I have no idea what the best way to do this is, but it's
+        // probably not this. Interfaces changed upstream.
+        std::unique_ptr<FrontendAction> Action(
+            new GenerateModuleFromModuleMapAction);
+        if (wrapGenModuleAction) {
+          Action = wrapGenModuleAction(FrontendOpts, std::move(Action));
+        }
+        Instance.ExecuteAction(*Action);
       },
       ThreadStackSize);
 
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 0d0869c..2bb2946 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -573,33 +573,6 @@
   if (!Opts.ProfileInstrumentUsePath.empty())
     setPGOUseInstrumentor(Opts, Opts.ProfileInstrumentUsePath);
 
-  if (Arg *A = Args.getLastArg(OPT_fclang_abi_compat_EQ)) {
-    Opts.setClangABICompat(CodeGenOptions::ClangABI::Latest);
-
-    StringRef Ver = A->getValue();
-    std::pair<StringRef, StringRef> VerParts = Ver.split('.');
-    unsigned Major, Minor = 0;
-
-    // Check the version number is valid: either 3.x (0 <= x <= 9) or
-    // y or y.0 (4 <= y <= current version).
-    if (!VerParts.first.startswith("0") &&
-        !VerParts.first.getAsInteger(10, Major) &&
-        3 <= Major && Major <= CLANG_VERSION_MAJOR &&
-        (Major == 3 ? VerParts.second.size() == 1 &&
-                      !VerParts.second.getAsInteger(10, Minor)
-                    : VerParts.first.size() == Ver.size() ||
-                      VerParts.second == "0")) {
-      // Got a valid version number.
-      if (Major == 3 && Minor <= 8)
-        Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver3_8);
-      else if (Major <= 4)
-        Opts.setClangABICompat(CodeGenOptions::ClangABI::Ver4);
-    } else if (Ver != "latest") {
-      Diags.Report(diag::err_drv_invalid_value)
-          << A->getAsString(Args) << A->getValue();
-    }
-  }
-
   Opts.CoverageMapping =
       Args.hasFlag(OPT_fcoverage_mapping, OPT_fno_coverage_mapping, false);
   Opts.DumpCoverageMapping = Args.hasArg(OPT_dump_coverage_mapping);
@@ -825,6 +798,7 @@
       getLastArgIntValue(Args, OPT_fsanitize_memory_track_origins_EQ, 0, Diags);
   Opts.SanitizeMemoryUseAfterDtor =
       Args.hasArg(OPT_fsanitize_memory_use_after_dtor);
+  Opts.SanitizeMinimalRuntime = Args.hasArg(OPT_fsanitize_minimal_runtime);
   Opts.SanitizeCfiCrossDso = Args.hasArg(OPT_fsanitize_cfi_cross_dso);
   Opts.SanitizeStats = Args.hasArg(OPT_fsanitize_stats);
   if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_after_scope,
@@ -1417,6 +1391,10 @@
       << "ARC migration" << "ObjC migration";
   }
 
+  Opts.IndexStorePath = Args.getLastArgValue(OPT_index_store_path);
+  Opts.IndexIgnoreSystemSymbols = Args.hasArg(OPT_index_ignore_system_symbols);
+  Opts.IndexRecordCodegenName = Args.hasArg(OPT_index_record_codegen_name);
+
   InputKind DashX(InputKind::Unknown);
   if (const Arg *A = Args.getLastArg(OPT_x)) {
     StringRef XValue = A->getValue();
@@ -1648,6 +1626,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());
+}
+
 void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
                                          const llvm::Triple &T,
                                          PreprocessorOptions &PPOpts,
@@ -2123,6 +2113,7 @@
       Args.hasArg(OPT_fmodules_local_submodule_visibility) || Opts.ModulesTS;
   Opts.ModulesCodegen = Args.hasArg(OPT_fmodules_codegen);
   Opts.ModulesDebugInfo = Args.hasArg(OPT_fmodules_debuginfo);
+  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);
@@ -2209,6 +2200,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
@@ -2654,6 +2647,8 @@
                               Res.getTargetOpts());
   ParseHeaderSearchArgs(Res.getHeaderSearchOpts(), Args,
                         Res.getFileSystemOpts().WorkingDir);
+  ParseAPINotesArgs(Res.getAPINotesOpts(), Args, Diags);
+
   if (DashX.getFormat() == InputKind::Precompiled ||
       DashX.getLanguage() == InputKind::LLVM_IR) {
     // ObjCAAutoRefCount and Sanitize LangOpts are used to setup the
@@ -2713,7 +2708,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;
@@ -2782,7 +2786,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);
   }
 
   // Extend the signature with the enabled sanitizers, if at least one is
@@ -2792,6 +2808,24 @@
   if (!SanHash.empty())
     code = hash_combine(code, SanHash.Mask);
 
+  // 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 704d515..9f69394 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -863,6 +863,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/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp
index 1d7c8a0..4bde9d0 100644
--- a/lib/Frontend/InitHeaderSearch.cpp
+++ b/lib/Frontend/InitHeaderSearch.cpp
@@ -485,6 +485,7 @@
     if (triple.isOSDarwin()) {
       AddPath("/System/Library/Frameworks", System, true);
       AddPath("/Library/Frameworks", System, true);
+      AddPath("/System/Library/PrivateFrameworks", System, true);
     }
   }
 }
diff --git a/lib/FrontendTool/CMakeLists.txt b/lib/FrontendTool/CMakeLists.txt
index 7e11be0..4a713e5 100644
--- a/lib/FrontendTool/CMakeLists.txt
+++ b/lib/FrontendTool/CMakeLists.txt
@@ -8,6 +8,7 @@
   clangCodeGen
   clangDriver
   clangFrontend
+  clangIndex
   clangRewriteFrontend
   )
 
diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index 1666315..4f88087 100644
--- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -23,6 +23,7 @@
 #include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/FrontendPluginRegistry.h"
 #include "clang/Frontend/Utils.h"
+#include "clang/Index/IndexingAction.h"
 #include "clang/Rewrite/Frontend/FrontendActions.h"
 #include "clang/StaticAnalyzer/Frontend/FrontendActions.h"
 #include "llvm/Option/OptTable.h"
@@ -164,6 +165,11 @@
   }
 #endif
 
+  if (!FEOpts.IndexStorePath.empty()) {
+    Act = index::createIndexDataRecordingAction(FEOpts, std::move(Act));
+    CI.setGenModuleActionWrapper(&index::createIndexDataRecordingAction);
+  }
+
   // If there are any AST files to merge, create a frontend action
   // adaptor to perform the merge.
   if (!FEOpts.ASTMergeFiles.empty())
diff --git a/lib/Index/BitstreamVisitor.h b/lib/Index/BitstreamVisitor.h
new file mode 100644
index 0000000..d324f1a
--- /dev/null
+++ b/lib/Index/BitstreamVisitor.h
@@ -0,0 +1,163 @@
+//===--- BitstreamVisitor.h - Helper for reading a bitstream --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_INDEX_BITSTREAMVISITOR_H
+#define LLVM_CLANG_LIB_INDEX_BITSTREAMVISITOR_H
+
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Serialization/ASTReader.h"
+#include <string>
+
+namespace clang {
+namespace index {
+namespace store {
+
+/// Helper class that saves the current stream position and
+/// then restores it when destroyed.
+struct SavedStreamPosition {
+  explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor)
+    : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { }
+
+  ~SavedStreamPosition() {
+    Cursor.JumpToBit(Offset);
+  }
+
+private:
+  llvm::BitstreamCursor &Cursor;
+  uint64_t Offset;
+};
+
+enum class StreamVisit {
+  Continue,
+  Skip,
+  Abort
+};
+
+template <typename ImplClass>
+class BitstreamVisitor {
+  SmallVector<unsigned, 4> BlockStack;
+
+protected:
+  llvm::BitstreamCursor &Stream;
+  Optional<llvm::BitstreamBlockInfo> BlockInfo;
+  std::string *Error;
+
+public:
+  BitstreamVisitor(llvm::BitstreamCursor &Stream)
+    : Stream(Stream) {}
+
+  StreamVisit visitBlock(unsigned ID) {
+    return StreamVisit::Continue;
+  }
+
+  bool visit(std::string &Error) {
+    this->Error = &Error;
+
+    ASTReader::RecordData Record;
+    while (1) {
+      llvm::BitstreamEntry Entry = Stream.advance(llvm::BitstreamCursor::AF_DontPopBlockAtEnd);
+
+      switch (Entry.Kind) {
+      case llvm::BitstreamEntry::Error:
+        Error = "malformed serialization";
+        return false;
+
+      case llvm::BitstreamEntry::EndBlock:
+        if (BlockStack.empty())
+          return true;
+        BlockStack.pop_back();
+        if (Stream.ReadBlockEnd()) {
+          Error = "malformed serialization";
+          return false;
+        }
+        if (Stream.AtEndOfStream())
+          return true;
+        break;
+
+      case llvm::BitstreamEntry::SubBlock: {
+        if (Entry.ID == llvm::bitc::BLOCKINFO_BLOCK_ID) {
+          BlockInfo = Stream.ReadBlockInfoBlock();
+          if (!BlockInfo) {
+            Error = "malformed BlockInfoBlock";
+            return false;
+          }
+          Stream.setBlockInfo(&*BlockInfo);
+          break;
+        }
+
+        StreamVisit Ret = static_cast<ImplClass*>(this)->visitBlock(Entry.ID);
+        switch (Ret) {
+        case StreamVisit::Continue:
+          if (Stream.EnterSubBlock(Entry.ID)) {
+            Error = "malformed block record";
+            return false;
+          }
+          readBlockAbbrevs(Stream);
+          BlockStack.push_back(Entry.ID);
+          break;
+
+        case StreamVisit::Skip: 
+          if (Stream.SkipBlock()) {
+            Error = "malformed serialization";
+            return false;
+          }
+          if (Stream.AtEndOfStream())
+            return true;
+          break;
+
+        case StreamVisit::Abort:
+          return false;
+        }
+        break;
+      }
+
+      case llvm::BitstreamEntry::Record: {
+        Record.clear();
+        StringRef Blob;
+        unsigned RecID = Stream.readRecord(Entry.ID, Record, &Blob);
+        unsigned BlockID = BlockStack.empty() ? 0 : BlockStack.back();
+        StreamVisit Ret = static_cast<ImplClass*>(this)->visitRecord(BlockID, RecID, Record, Blob);
+        switch (Ret) {
+        case StreamVisit::Continue:
+          break;
+
+        case StreamVisit::Skip: 
+          Stream.skipRecord(Entry.ID);
+          break;
+
+        case StreamVisit::Abort:
+          return false;
+        }
+        break;
+      }
+      }
+    }
+  }
+
+  static void readBlockAbbrevs(llvm::BitstreamCursor &Cursor) {
+    while (true) {
+      uint64_t Offset = Cursor.GetCurrentBitNo();
+      unsigned Code = Cursor.ReadCode();
+
+      // We expect all abbrevs to be at the start of the block.
+      if (Code != llvm::bitc::DEFINE_ABBREV) {
+        Cursor.JumpToBit(Offset);
+        return;
+      }
+      Cursor.ReadAbbrevRecord();
+    }
+  }
+};
+
+} // end namespace store
+} // end namespace index
+} // end namespace clang
+
+#endif
diff --git a/lib/Index/CMakeLists.txt b/lib/Index/CMakeLists.txt
index c9fbfaf..bb17d15 100644
--- a/lib/Index/CMakeLists.txt
+++ b/lib/Index/CMakeLists.txt
@@ -1,17 +1,27 @@
 set(LLVM_LINK_COMPONENTS
+  BitReader
   Core
   Support
   )
 
 add_clang_library(clangIndex
+  ClangIndexRecordWriter.cpp
   CodegenNameGenerator.cpp
   CommentToXML.cpp
+  FileIndexRecord.cpp
   IndexBody.cpp
+  IndexDataStore.cpp
+  IndexDataStoreUtils.cpp
   IndexDecl.cpp
   IndexingAction.cpp
   IndexingContext.cpp
+  IndexRecordHasher.cpp
+  IndexRecordReader.cpp
+  IndexRecordWriter.cpp
   IndexSymbol.cpp
   IndexTypeSourceInfo.cpp
+  IndexUnitReader.cpp
+  IndexUnitWriter.cpp
   USRGeneration.cpp
 
   ADDITIONAL_HEADERS
@@ -23,6 +33,7 @@
   clangBasic
   clangFormat
   clangFrontend
+  clangLex
   clangRewrite
   clangSerialization
   clangToolingCore
diff --git a/lib/Index/ClangIndexRecordWriter.cpp b/lib/Index/ClangIndexRecordWriter.cpp
new file mode 100644
index 0000000..612ef1b
--- /dev/null
+++ b/lib/Index/ClangIndexRecordWriter.cpp
@@ -0,0 +1,128 @@
+//===--- ClangIndexRecordWriter.cpp - Index record serialization ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangIndexRecordWriter.h"
+#include "FileIndexRecord.h"
+#include "clang/Index/IndexSymbol.h"
+#include "clang/Index/IndexRecordReader.h"
+#include "clang/Index/USRGeneration.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+
+using namespace clang;
+using namespace clang::index;
+
+StringRef ClangIndexRecordWriter::getUSR(const Decl *D) {
+  assert(D->isCanonicalDecl());
+  auto Insert = USRByDecl.insert(std::make_pair(D, StringRef()));
+  if (Insert.second) {
+    Insert.first->second = getUSRNonCached(D);
+  }
+  return Insert.first->second;
+}
+
+StringRef ClangIndexRecordWriter::getUSRNonCached(const Decl *D) {
+  SmallString<256> Buf;
+  bool Ignore = generateUSRForDecl(D, Buf);
+  if (Ignore)
+    return StringRef();
+  StringRef USR = Buf.str();
+  char *Ptr = Allocator.Allocate<char>(USR.size());
+  std::copy(USR.begin(), USR.end(), Ptr);
+  return StringRef(Ptr, USR.size());
+}
+
+ClangIndexRecordWriter::ClangIndexRecordWriter(ASTContext &Ctx,
+                                               RecordingOptions Opts)
+    : Impl(Opts.DataDirPath), Ctx(Ctx), RecordOpts(std::move(Opts)),
+      Hasher(Ctx) {
+  if (Opts.RecordSymbolCodeGenName)
+    CGNameGen.reset(new CodegenNameGenerator(Ctx));
+}
+
+ClangIndexRecordWriter::~ClangIndexRecordWriter() {}
+
+bool ClangIndexRecordWriter::writeRecord(StringRef Filename,
+                                         const FileIndexRecord &IdxRecord,
+                                         std::string &Error,
+                                         std::string *OutRecordFile) {
+
+  auto RecordHash = Hasher.hashRecord(IdxRecord);
+
+  switch (Impl.beginRecord(Filename, RecordHash, Error, OutRecordFile)) {
+  case IndexRecordWriter::Result::Success:
+    break; // Continue writing.
+  case IndexRecordWriter::Result::Failure:
+    return true;
+  case IndexRecordWriter::Result::AlreadyExists:
+    return false;
+  }
+
+  ASTContext &Ctx = getASTContext();
+  SourceManager &SM = Ctx.getSourceManager();
+  FileID FID = IdxRecord.getFileID();
+  auto getLineCol = [&](unsigned Offset) -> std::pair<unsigned, unsigned> {
+    unsigned LineNo = SM.getLineNumber(FID, Offset);
+    unsigned ColNo = SM.getColumnNumber(FID, Offset);
+    return std::make_pair(LineNo, ColNo);
+  };
+
+  for (auto &Occur : IdxRecord.getDeclOccurrences()) {
+    unsigned Line, Col;
+    std::tie(Line, Col) = getLineCol(Occur.Offset);
+    SmallVector<writer::SymbolRelation, 3> Related;
+    Related.reserve(Occur.Relations.size());
+    for (auto &Rel : Occur.Relations)
+      Related.push_back(writer::SymbolRelation{Rel.RelatedSymbol, Rel.Roles});
+
+    Impl.addOccurrence(Occur.Dcl, Occur.Roles, Line, Col, Related);
+  }
+
+  PrintingPolicy Policy(Ctx.getLangOpts());
+  Policy.SuppressTemplateArgsInCXXConstructors = true;
+
+  auto Result = Impl.endRecord(Error,
+      [&](writer::OpaqueDecl OD, SmallVectorImpl<char> &Scratch) {
+    const Decl *D = static_cast<const Decl *>(OD);
+    auto Info = getSymbolInfo(D);
+
+    writer::Symbol Sym;
+    Sym.SymInfo = Info;
+
+    auto *ND = dyn_cast<NamedDecl>(D);
+    if (ND) {
+      llvm::raw_svector_ostream OS(Scratch);
+      DeclarationName DeclName = ND->getDeclName();
+      if (!DeclName.isEmpty())
+        DeclName.print(OS, Policy);
+    }
+    unsigned NameLen = Scratch.size();
+    Sym.Name = StringRef(Scratch.data(), NameLen);
+
+    Sym.USR = getUSR(D);
+    assert(!Sym.USR.empty() && "Recorded decl without USR!");
+
+    if (CGNameGen && ND) {
+      llvm::raw_svector_ostream OS(Scratch);
+      CGNameGen->writeName(ND, OS);
+    }
+    unsigned CGNameLen = Scratch.size() - NameLen;
+    Sym.CodeGenName = StringRef(Scratch.data() + NameLen, CGNameLen);
+    return Sym;
+  });
+
+  switch (Result) {
+  case IndexRecordWriter::Result::Success:
+  case IndexRecordWriter::Result::AlreadyExists:
+    return false;
+  case IndexRecordWriter::Result::Failure:
+    return true;
+  }
+}
diff --git a/lib/Index/ClangIndexRecordWriter.h b/lib/Index/ClangIndexRecordWriter.h
new file mode 100644
index 0000000..b68f987
--- /dev/null
+++ b/lib/Index/ClangIndexRecordWriter.h
@@ -0,0 +1,55 @@
+//===--- ClangIndexRecordWriter.h - Index record serialization ------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_INDEX_CLANGINDEXRECORDWRITER_H
+#define LLVM_CLANG_LIB_INDEX_CLANGINDEXRECORDWRITER_H
+
+#include "IndexRecordHasher.h"
+#include "clang/Index/IndexRecordWriter.h"
+#include "clang/Index/IndexingAction.h"
+#include "clang/Index/CodegenNameGenerator.h"
+#include "llvm/ADT/SmallString.h"
+
+namespace clang {
+  class ASTContext;
+  class Decl;
+
+namespace index {
+  class FileIndexRecord;
+
+class ClangIndexRecordWriter {
+  IndexRecordWriter Impl;
+
+  ASTContext &Ctx;
+  RecordingOptions RecordOpts;
+
+  std::unique_ptr<CodegenNameGenerator> CGNameGen;
+  llvm::BumpPtrAllocator Allocator;
+  llvm::DenseMap<const Decl *, StringRef> USRByDecl;
+  IndexRecordHasher Hasher;
+
+public:
+  ClangIndexRecordWriter(ASTContext &Ctx, RecordingOptions Opts);
+  ~ClangIndexRecordWriter();
+
+  ASTContext &getASTContext() { return Ctx; }
+  CodegenNameGenerator *getCGNameGen() { return CGNameGen.get(); }
+
+  bool writeRecord(StringRef Filename, const FileIndexRecord &Record,
+                   std::string &Error, std::string *RecordFile = nullptr);
+  StringRef getUSR(const Decl *D);
+
+private:
+  StringRef getUSRNonCached(const Decl *D);
+};
+
+} // end namespace index
+} // end namespace clang
+
+#endif
diff --git a/lib/Index/CommentToXML.cpp b/lib/Index/CommentToXML.cpp
index e568c83..918068a 100644
--- a/lib/Index/CommentToXML.cpp
+++ b/lib/Index/CommentToXML.cpp
@@ -579,6 +579,7 @@
   PrintingPolicy PPolicy(LangOpts);
   PPolicy.PolishForDeclaration = true;
   PPolicy.TerseOutput = true;
+  PPolicy.ConstantsAsWritten = true;
   ThisDecl->CurrentDecl->print(OS, PPolicy,
                                /*Indentation*/0, /*PrintInstantiation*/false);
 }
diff --git a/lib/Index/FileIndexRecord.cpp b/lib/Index/FileIndexRecord.cpp
new file mode 100644
index 0000000..98d66b6
--- /dev/null
+++ b/lib/Index/FileIndexRecord.cpp
@@ -0,0 +1,59 @@
+//===--- FileIndexRecord.cpp - Index data per file ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "FileIndexRecord.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclTemplate.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang;
+using namespace clang::index;
+
+void FileIndexRecord::addDeclOccurence(SymbolRoleSet Roles,
+                                       unsigned Offset,
+                                       const Decl *D,
+                                       ArrayRef<SymbolRelation> Relations) {
+  assert(D->isCanonicalDecl());
+
+  auto IsNextOccurence = [&]()->bool {
+    if (Decls.empty())
+      return true;
+    auto &Last = Decls.back();
+    return Last.Offset < Offset;
+  };
+
+  if (IsNextOccurence()) {
+    Decls.emplace_back(Roles, Offset, D, Relations);
+    return;
+  }
+
+  DeclOccurrence NewInfo(Roles, Offset, D, Relations);
+  auto It = std::upper_bound(Decls.begin(), Decls.end(), NewInfo);
+  Decls.insert(It, std::move(NewInfo));
+}
+
+void FileIndexRecord::print(llvm::raw_ostream &OS) {
+  OS << "DECLS BEGIN ---\n";
+  for (auto &DclInfo : Decls) {
+    auto D = DclInfo.Dcl;
+    SourceManager &SM = D->getASTContext().getSourceManager();
+    SourceLocation Loc = SM.getFileLoc(D->getLocation());
+    PresumedLoc PLoc = SM.getPresumedLoc(Loc);
+    OS << llvm::sys::path::filename(PLoc.getFilename()) << ':' << PLoc.getLine()
+       << ':' << PLoc.getColumn();
+
+    if (auto ND = dyn_cast<NamedDecl>(D)) {
+      OS << ' ' << ND->getNameAsString();
+    }
+
+    OS << '\n';
+  }
+  OS << "DECLS END ---\n";
+}
diff --git a/lib/Index/FileIndexRecord.h b/lib/Index/FileIndexRecord.h
new file mode 100644
index 0000000..a663173
--- /dev/null
+++ b/lib/Index/FileIndexRecord.h
@@ -0,0 +1,69 @@
+//===--- FileIndexRecord.h - Index data per file --------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_INDEX_FILEINDEXRECORD_H
+#define LLVM_CLANG_LIB_INDEX_FILEINDEXRECORD_H
+
+#include "clang/Index/IndexSymbol.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
+#include <vector>
+
+namespace clang {
+  class IdentifierInfo;
+
+namespace index {
+
+class FileIndexRecord {
+public:
+  struct DeclOccurrence {
+    SymbolRoleSet Roles;
+    unsigned Offset;
+    const Decl *Dcl;
+    SmallVector<SymbolRelation, 3> Relations;
+
+    DeclOccurrence(SymbolRoleSet R,
+                   unsigned Offset,
+                   const Decl *D,
+                   ArrayRef<SymbolRelation> Relations)
+      : Roles(R),
+        Offset(Offset),
+        Dcl(D),
+        Relations(Relations.begin(), Relations.end()) {}
+
+    friend bool operator <(const DeclOccurrence &LHS, const DeclOccurrence &RHS) {
+      return LHS.Offset < RHS.Offset;
+    }
+  };
+
+private:
+  FileID FID;
+  bool IsSystem;
+  std::vector<DeclOccurrence> Decls;
+
+public:
+  FileIndexRecord(FileID FID, bool isSystem) : FID(FID), IsSystem(isSystem) {}
+
+  ArrayRef<DeclOccurrence> getDeclOccurrences() const { return Decls; }
+
+  FileID getFileID() const { return FID; }
+  bool isSystem() const { return IsSystem; }
+
+  void addDeclOccurence(SymbolRoleSet Roles,
+                        unsigned Offset,
+                        const Decl *D,
+                        ArrayRef<SymbolRelation> Relations);
+  void print(llvm::raw_ostream &OS);
+};
+
+} // end namespace index
+} // end namespace clang
+
+#endif
diff --git a/lib/Index/IndexDataStore.cpp b/lib/Index/IndexDataStore.cpp
new file mode 100644
index 0000000..4140392
--- /dev/null
+++ b/lib/Index/IndexDataStore.cpp
@@ -0,0 +1,259 @@
+//===--- IndexDataStore.cpp - Index data store info -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/IndexDataStore.h"
+#include "IndexDataStoreUtils.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Mutex.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::index;
+using namespace clang::index::store;
+using namespace llvm;
+
+static void appendSubDir(StringRef subdir, SmallVectorImpl<char> &StorePathBuf) {
+  SmallString<10> VersionPath;
+  raw_svector_ostream(VersionPath) << 'v' << STORE_FORMAT_VERSION;
+
+  sys::path::append(StorePathBuf, VersionPath);
+  sys::path::append(StorePathBuf, subdir);
+}
+
+void store::appendInteriorUnitPath(StringRef UnitName,
+                                   SmallVectorImpl<char> &PathBuf) {
+  sys::path::append(PathBuf, UnitName);
+}
+
+void store::appendUnitSubDir(SmallVectorImpl<char> &StorePathBuf) {
+  return appendSubDir("units", StorePathBuf);
+}
+
+void store::appendRecordSubDir(SmallVectorImpl<char> &StorePathBuf) {
+  return appendSubDir("records", StorePathBuf);
+}
+
+void store::appendInteriorRecordPath(StringRef RecordName,
+                                     SmallVectorImpl<char> &PathBuf) {
+  // To avoid putting a huge number of files into the records directory, create
+  // subdirectories based on the last 2 characters from the hash.
+  StringRef hash2chars = RecordName.substr(RecordName.size()-2);
+  sys::path::append(PathBuf, hash2chars);
+  sys::path::append(PathBuf, RecordName);
+}
+
+//===----------------------------------------------------------------------===//
+// IndexDataStore
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class UnitEventHandlerData {
+  mutable sys::Mutex Mtx;
+  IndexDataStore::UnitEventHandler Handler;
+
+public:
+  void setHandler(IndexDataStore::UnitEventHandler handler) {
+    sys::ScopedLock L(Mtx);
+    Handler = std::move(handler);
+  }
+  IndexDataStore::UnitEventHandler getHandler() const {
+    sys::ScopedLock L(Mtx);
+    return Handler;
+  }
+};
+
+class IndexDataStoreImpl {
+  std::string FilePath;
+  std::shared_ptr<UnitEventHandlerData> TheUnitEventHandlerData;
+  std::unique_ptr<AbstractDirectoryWatcher> DirWatcher;
+
+public:
+  explicit IndexDataStoreImpl(StringRef indexStorePath)
+    : FilePath(indexStorePath) {
+    TheUnitEventHandlerData = std::make_shared<UnitEventHandlerData>();
+  }
+
+  StringRef getFilePath() const { return FilePath; }
+  bool foreachUnitName(bool sorted,
+                       llvm::function_ref<bool(StringRef unitName)> receiver);
+  void setUnitEventHandler(IndexDataStore::UnitEventHandler Handler);
+  bool startEventListening(llvm::function_ref<AbstractDirectoryWatcher::CreateFnTy> createFn,
+                           bool waitInitialSync, std::string &Error);
+  void stopEventListening();
+  void discardUnit(StringRef UnitName);
+  void discardRecord(StringRef RecordName);
+  void purgeStaleData();
+};
+
+} // anonymous namespace
+
+bool IndexDataStoreImpl::foreachUnitName(bool sorted,
+                        llvm::function_ref<bool(StringRef unitName)> receiver) {
+  SmallString<128> UnitPath;
+  UnitPath = FilePath;
+  appendUnitSubDir(UnitPath);
+
+  std::vector<std::string> filenames;
+
+  std::error_code EC;
+  for (auto It = sys::fs::directory_iterator(UnitPath, EC),
+           End = sys::fs::directory_iterator();
+       !EC && It != End; It.increment(EC)) {
+    StringRef unitName = sys::path::filename(It->path());
+    if (!sorted) {
+      if (!receiver(unitName))
+        return false;
+    } else {
+      filenames.push_back(unitName);
+    }
+  }
+
+  if (sorted) {
+    llvm::array_pod_sort(filenames.begin(), filenames.end());
+    for (auto &fname : filenames)
+      if (!receiver(fname))
+        return false;
+  }
+  return true;
+}
+
+void IndexDataStoreImpl::setUnitEventHandler(IndexDataStore::UnitEventHandler handler) {
+  TheUnitEventHandlerData->setHandler(std::move(handler));
+}
+
+bool IndexDataStoreImpl::startEventListening(llvm::function_ref<AbstractDirectoryWatcher::CreateFnTy> createFn,
+                                             bool waitInitialSync, std::string &Error) {
+  if (DirWatcher) {
+    Error = "event listener already active";
+    return true;
+  }
+
+  SmallString<128> UnitPath;
+  UnitPath = FilePath;
+  appendUnitSubDir(UnitPath);
+
+  auto localUnitEventHandlerData = TheUnitEventHandlerData;
+  auto OnUnitsChange = [localUnitEventHandlerData](ArrayRef<AbstractDirectoryWatcher::Event> Events, bool isInitial) {
+    SmallVector<IndexDataStore::UnitEvent, 16> UnitEvents;
+    UnitEvents.reserve(Events.size());
+    for (const AbstractDirectoryWatcher::Event &evt : Events) {
+      IndexDataStore::UnitEventKind K;
+      StringRef UnitName = sys::path::filename(evt.Filename);
+      switch (evt.Kind) {
+      case AbstractDirectoryWatcher::EventKind::Added:
+        K = IndexDataStore::UnitEventKind::Added; break;
+      case AbstractDirectoryWatcher::EventKind::Removed:
+        K = IndexDataStore::UnitEventKind::Removed; break;
+      case AbstractDirectoryWatcher::EventKind::Modified:
+        K = IndexDataStore::UnitEventKind::Modified; break;
+      case AbstractDirectoryWatcher::EventKind::DirectoryDeleted:
+        K = IndexDataStore::UnitEventKind::DirectoryDeleted;
+        UnitName = StringRef();
+        break;
+      }
+      UnitEvents.push_back(IndexDataStore::UnitEvent{K, UnitName, evt.ModTime});
+    }
+
+    if (auto handler = localUnitEventHandlerData->getHandler()) {
+      IndexDataStore::UnitEventNotification EventNote{isInitial, UnitEvents};
+      handler(EventNote);
+    }
+  };
+
+  DirWatcher = createFn(UnitPath.str(), OnUnitsChange, waitInitialSync, Error);
+  if (!DirWatcher)
+    return true;
+
+  return false;
+}
+
+void IndexDataStoreImpl::stopEventListening() {
+  DirWatcher.reset();
+}
+
+void IndexDataStoreImpl::discardUnit(StringRef UnitName) {
+  SmallString<128> UnitPath;
+  UnitPath = FilePath;
+  appendUnitSubDir(UnitPath);
+  appendInteriorUnitPath(UnitName, UnitPath);
+  sys::fs::remove(UnitPath);
+}
+
+void IndexDataStoreImpl::discardRecord(StringRef RecordName) {
+  SmallString<128> RecordPath;
+  RecordPath = FilePath;
+  appendRecordSubDir(RecordPath);
+  appendInteriorRecordPath(RecordName, RecordPath);
+  sys::fs::remove(RecordPath);
+}
+
+void IndexDataStoreImpl::purgeStaleData() {
+  // FIXME: Implement.
+}
+
+
+std::unique_ptr<IndexDataStore>
+IndexDataStore::create(StringRef IndexStorePath, std::string &Error) {
+  if (!sys::fs::exists(IndexStorePath)) {
+    raw_string_ostream OS(Error);
+    OS << "index store path does not exist: " << IndexStorePath;
+    return nullptr;
+  }
+
+  return std::unique_ptr<IndexDataStore>(
+    new IndexDataStore(new IndexDataStoreImpl(IndexStorePath)));
+}
+
+#define IMPL static_cast<IndexDataStoreImpl*>(Impl)
+
+IndexDataStore::~IndexDataStore() {
+  delete IMPL;
+}
+
+StringRef IndexDataStore::getFilePath() const {
+  return IMPL->getFilePath();
+}
+
+bool IndexDataStore::foreachUnitName(bool sorted,
+                     llvm::function_ref<bool(StringRef unitName)> receiver) {
+  return IMPL->foreachUnitName(sorted, std::move(receiver));
+}
+
+unsigned IndexDataStore::getFormatVersion() {
+  return STORE_FORMAT_VERSION;
+}
+
+void IndexDataStore::setUnitEventHandler(UnitEventHandler Handler) {
+  return IMPL->setUnitEventHandler(std::move(Handler));
+}
+
+bool IndexDataStore::startEventListening(llvm::function_ref<AbstractDirectoryWatcher::CreateFnTy> createFn,
+                                         bool waitInitialSync, std::string &Error) {
+  return IMPL->startEventListening(std::move(createFn), waitInitialSync, Error);
+}
+
+void IndexDataStore::stopEventListening() {
+  return IMPL->stopEventListening();
+}
+
+void IndexDataStore::discardUnit(StringRef UnitName) {
+  IMPL->discardUnit(UnitName);
+}
+
+void IndexDataStore::discardRecord(StringRef RecordName) {
+  IMPL->discardRecord(RecordName);
+}
+
+void IndexDataStore::purgeStaleData() {
+  IMPL->purgeStaleData();
+}
diff --git a/lib/Index/IndexDataStoreUtils.cpp b/lib/Index/IndexDataStoreUtils.cpp
new file mode 100644
index 0000000..3efaec9
--- /dev/null
+++ b/lib/Index/IndexDataStoreUtils.cpp
@@ -0,0 +1,410 @@
+//===--- IndexDataStoreUtils.cpp - Functions/constants for the data store -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/IndexDataStoreSymbolUtils.h"
+#include "IndexDataStoreUtils.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+
+using namespace clang;
+using namespace clang::index;
+using namespace clang::index::store;
+using namespace llvm;
+
+void store::emitBlockID(unsigned ID, const char *Name,
+                        BitstreamWriter &Stream, RecordDataImpl &Record) {
+  Record.clear();
+  Record.push_back(ID);
+  Stream.EmitRecord(bitc::BLOCKINFO_CODE_SETBID, Record);
+
+  // Emit the block name if present.
+  if (!Name || Name[0] == 0)
+    return;
+  Record.clear();
+  while (*Name)
+    Record.push_back(*Name++);
+  Stream.EmitRecord(bitc::BLOCKINFO_CODE_BLOCKNAME, Record);
+}
+
+void store::emitRecordID(unsigned ID, const char *Name,
+                         BitstreamWriter &Stream,
+                         RecordDataImpl &Record) {
+  Record.clear();
+  Record.push_back(ID);
+  while (*Name)
+    Record.push_back(*Name++);
+  Stream.EmitRecord(bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
+}
+
+/// Map an indexstore_symbol_kind_t to a SymbolKind, handling unknown values.
+SymbolKind index::getSymbolKind(indexstore_symbol_kind_t K) {
+  switch ((uint64_t)K) {
+  default:
+  case INDEXSTORE_SYMBOL_KIND_UNKNOWN:
+    return SymbolKind::Unknown;
+  case INDEXSTORE_SYMBOL_KIND_MODULE:
+    return SymbolKind::Module;
+  case INDEXSTORE_SYMBOL_KIND_NAMESPACE:
+    return SymbolKind::Namespace;
+  case INDEXSTORE_SYMBOL_KIND_NAMESPACEALIAS:
+    return SymbolKind::NamespaceAlias;
+  case INDEXSTORE_SYMBOL_KIND_MACRO:
+    return SymbolKind::Macro;
+  case INDEXSTORE_SYMBOL_KIND_ENUM:
+    return SymbolKind::Enum;
+  case INDEXSTORE_SYMBOL_KIND_STRUCT:
+    return SymbolKind::Struct;
+  case INDEXSTORE_SYMBOL_KIND_CLASS:
+    return SymbolKind::Class;
+  case INDEXSTORE_SYMBOL_KIND_PROTOCOL:
+    return SymbolKind::Protocol;
+  case INDEXSTORE_SYMBOL_KIND_EXTENSION:
+    return SymbolKind::Extension;
+  case INDEXSTORE_SYMBOL_KIND_UNION:
+    return SymbolKind::Union;
+  case INDEXSTORE_SYMBOL_KIND_TYPEALIAS:
+    return SymbolKind::TypeAlias;
+  case INDEXSTORE_SYMBOL_KIND_FUNCTION:
+    return SymbolKind::Function;
+  case INDEXSTORE_SYMBOL_KIND_VARIABLE:
+    return SymbolKind::Variable;
+  case INDEXSTORE_SYMBOL_KIND_FIELD:
+    return SymbolKind::Field;
+  case INDEXSTORE_SYMBOL_KIND_ENUMCONSTANT:
+    return SymbolKind::EnumConstant;
+  case INDEXSTORE_SYMBOL_KIND_INSTANCEMETHOD:
+    return SymbolKind::InstanceMethod;
+  case INDEXSTORE_SYMBOL_KIND_CLASSMETHOD:
+    return SymbolKind::ClassMethod;
+  case INDEXSTORE_SYMBOL_KIND_STATICMETHOD:
+    return SymbolKind::StaticMethod;
+  case INDEXSTORE_SYMBOL_KIND_INSTANCEPROPERTY:
+    return SymbolKind::InstanceProperty;
+  case INDEXSTORE_SYMBOL_KIND_CLASSPROPERTY:
+    return SymbolKind::ClassProperty;
+  case INDEXSTORE_SYMBOL_KIND_STATICPROPERTY:
+    return SymbolKind::StaticProperty;
+  case INDEXSTORE_SYMBOL_KIND_CONSTRUCTOR:
+    return SymbolKind::Constructor;
+  case INDEXSTORE_SYMBOL_KIND_DESTRUCTOR:
+    return SymbolKind::Destructor;
+  case INDEXSTORE_SYMBOL_KIND_CONVERSIONFUNCTION:
+    return SymbolKind::ConversionFunction;
+  case INDEXSTORE_SYMBOL_KIND_PARAMETER:
+    return SymbolKind::Parameter;
+  case INDEXSTORE_SYMBOL_KIND_USING:
+    return SymbolKind::Using;
+  case INDEXSTORE_SYMBOL_KIND_COMMENTTAG:
+    return SymbolKind::CommentTag;
+  }
+}
+
+SymbolSubKind index::getSymbolSubKind(indexstore_symbol_subkind_t K) {
+  switch ((uint64_t)K) {
+  default:
+  case INDEXSTORE_SYMBOL_SUBKIND_NONE:
+    return SymbolSubKind::None;
+  case INDEXSTORE_SYMBOL_SUBKIND_CXXCOPYCONSTRUCTOR:
+    return SymbolSubKind::CXXCopyConstructor;
+  case INDEXSTORE_SYMBOL_SUBKIND_CXXMOVECONSTRUCTOR:
+    return SymbolSubKind::CXXMoveConstructor;
+  case INDEXSTORE_SYMBOL_SUBKIND_ACCESSORGETTER:
+      return SymbolSubKind::AccessorGetter;
+  case INDEXSTORE_SYMBOL_SUBKIND_ACCESSORSETTER:
+      return SymbolSubKind::AccessorSetter;
+  case INDEXSTORE_SYMBOL_SUBKIND_USINGTYPENAME:
+      return SymbolSubKind::UsingTypename;
+  case INDEXSTORE_SYMBOL_SUBKIND_USINGVALUE:
+      return SymbolSubKind::UsingValue;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORWILLSET:
+    return SymbolSubKind::SwiftAccessorWillSet;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORDIDSET:
+    return SymbolSubKind::SwiftAccessorDidSet;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORADDRESSOR:
+    return SymbolSubKind::SwiftAccessorAddressor;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORMUTABLEADDRESSOR:
+    return SymbolSubKind::SwiftAccessorMutableAddressor;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFSTRUCT:
+    return SymbolSubKind::SwiftExtensionOfStruct;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFCLASS:
+    return SymbolSubKind::SwiftExtensionOfClass;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFENUM:
+    return SymbolSubKind::SwiftExtensionOfEnum;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFPROTOCOL:
+    return SymbolSubKind::SwiftExtensionOfProtocol;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTPREFIXOPERATOR:
+    return SymbolSubKind::SwiftPrefixOperator;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTPOSTFIXOPERATOR:
+    return SymbolSubKind::SwiftPostfixOperator;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTINFIXOPERATOR:
+    return SymbolSubKind::SwiftInfixOperator;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTSUBSCRIPT:
+    return SymbolSubKind::SwiftSubscript;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTASSOCIATEDTYPE:
+    return SymbolSubKind::SwiftAssociatedType;
+  case INDEXSTORE_SYMBOL_SUBKIND_SWIFTGENERICTYPEPARAM:
+    return SymbolSubKind::SwiftGenericTypeParam;
+  }
+}
+
+/// Map an indexstore_symbol_language_t to a SymbolLanguage, handling unknown
+/// values.
+SymbolLanguage index::getSymbolLanguage(indexstore_symbol_language_t L) {
+  switch ((uint64_t)L) {
+  default: // FIXME: add an unknown language?
+  case INDEXSTORE_SYMBOL_LANG_C:
+    return SymbolLanguage::C;
+  case INDEXSTORE_SYMBOL_LANG_OBJC:
+    return SymbolLanguage::ObjC;
+  case INDEXSTORE_SYMBOL_LANG_CXX:
+    return SymbolLanguage::CXX;
+  case INDEXSTORE_SYMBOL_LANG_SWIFT:
+    return SymbolLanguage::Swift;
+  }
+}
+
+/// Map an indexstore representation to a SymbolPropertySet, handling
+/// unknown values.
+SymbolPropertySet index::getSymbolProperties(uint64_t Props) {
+  // FIXME: currently these enums must be kept in sync.
+  return (uint64_t)Props;
+}
+
+/// Map an indexstore representation to a SymbolRoleSet, handling unknown
+/// values.
+SymbolRoleSet index::getSymbolRoles(uint64_t Roles) {
+  // FIXME: currently these enums must be kept in sync.
+  return (uint64_t)Roles;
+}
+
+/// Map a SymbolLanguage to a indexstore_symbol_language_t.
+indexstore_symbol_kind_t index::getIndexStoreKind(SymbolKind K) {
+  switch (K) {
+  case SymbolKind::Unknown:
+    return INDEXSTORE_SYMBOL_KIND_UNKNOWN;
+  case SymbolKind::Module:
+    return INDEXSTORE_SYMBOL_KIND_MODULE;
+  case SymbolKind::Namespace:
+    return INDEXSTORE_SYMBOL_KIND_NAMESPACE;
+  case SymbolKind::NamespaceAlias:
+    return INDEXSTORE_SYMBOL_KIND_NAMESPACEALIAS;
+  case SymbolKind::Macro:
+    return INDEXSTORE_SYMBOL_KIND_MACRO;
+  case SymbolKind::Enum:
+    return INDEXSTORE_SYMBOL_KIND_ENUM;
+  case SymbolKind::Struct:
+    return INDEXSTORE_SYMBOL_KIND_STRUCT;
+  case SymbolKind::Class:
+    return INDEXSTORE_SYMBOL_KIND_CLASS;
+  case SymbolKind::Protocol:
+    return INDEXSTORE_SYMBOL_KIND_PROTOCOL;
+  case SymbolKind::Extension:
+    return INDEXSTORE_SYMBOL_KIND_EXTENSION;
+  case SymbolKind::Union:
+    return INDEXSTORE_SYMBOL_KIND_UNION;
+  case SymbolKind::TypeAlias:
+    return INDEXSTORE_SYMBOL_KIND_TYPEALIAS;
+  case SymbolKind::Function:
+    return INDEXSTORE_SYMBOL_KIND_FUNCTION;
+  case SymbolKind::Variable:
+    return INDEXSTORE_SYMBOL_KIND_VARIABLE;
+  case SymbolKind::Field:
+    return INDEXSTORE_SYMBOL_KIND_FIELD;
+  case SymbolKind::EnumConstant:
+    return INDEXSTORE_SYMBOL_KIND_ENUMCONSTANT;
+  case SymbolKind::InstanceMethod:
+    return INDEXSTORE_SYMBOL_KIND_INSTANCEMETHOD;
+  case SymbolKind::ClassMethod:
+    return INDEXSTORE_SYMBOL_KIND_CLASSMETHOD;
+  case SymbolKind::StaticMethod:
+    return INDEXSTORE_SYMBOL_KIND_STATICMETHOD;
+  case SymbolKind::InstanceProperty:
+    return INDEXSTORE_SYMBOL_KIND_INSTANCEPROPERTY;
+  case SymbolKind::ClassProperty:
+    return INDEXSTORE_SYMBOL_KIND_CLASSPROPERTY;
+  case SymbolKind::StaticProperty:
+    return INDEXSTORE_SYMBOL_KIND_STATICPROPERTY;
+  case SymbolKind::Constructor:
+    return INDEXSTORE_SYMBOL_KIND_CONSTRUCTOR;
+  case SymbolKind::Destructor:
+    return INDEXSTORE_SYMBOL_KIND_DESTRUCTOR;
+  case SymbolKind::ConversionFunction:
+    return INDEXSTORE_SYMBOL_KIND_CONVERSIONFUNCTION;
+  case SymbolKind::Parameter:
+    return INDEXSTORE_SYMBOL_KIND_PARAMETER;
+  case SymbolKind::Using:
+    return INDEXSTORE_SYMBOL_KIND_USING;
+  case SymbolKind::CommentTag:
+    return INDEXSTORE_SYMBOL_KIND_COMMENTTAG;
+  }
+  llvm_unreachable("unexpected symbol kind");
+}
+
+indexstore_symbol_subkind_t index::getIndexStoreSubKind(SymbolSubKind K) {
+  switch (K) {
+  case SymbolSubKind::None:
+    return INDEXSTORE_SYMBOL_SUBKIND_NONE;
+  case SymbolSubKind::CXXCopyConstructor:
+    return INDEXSTORE_SYMBOL_SUBKIND_CXXCOPYCONSTRUCTOR;
+  case SymbolSubKind::CXXMoveConstructor:
+    return INDEXSTORE_SYMBOL_SUBKIND_CXXMOVECONSTRUCTOR;
+  case SymbolSubKind::AccessorGetter:
+    return INDEXSTORE_SYMBOL_SUBKIND_ACCESSORGETTER;
+  case SymbolSubKind::AccessorSetter:
+    return INDEXSTORE_SYMBOL_SUBKIND_ACCESSORSETTER;
+  case SymbolSubKind::UsingTypename:
+    return INDEXSTORE_SYMBOL_SUBKIND_USINGTYPENAME;
+  case SymbolSubKind::UsingValue:
+    return INDEXSTORE_SYMBOL_SUBKIND_USINGVALUE;
+  case SymbolSubKind::SwiftAccessorWillSet:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORWILLSET;
+  case SymbolSubKind::SwiftAccessorDidSet:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORDIDSET;
+  case SymbolSubKind::SwiftAccessorAddressor:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORADDRESSOR;
+  case SymbolSubKind::SwiftAccessorMutableAddressor:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTACCESSORMUTABLEADDRESSOR;
+  case SymbolSubKind::SwiftExtensionOfStruct:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFSTRUCT;
+  case SymbolSubKind::SwiftExtensionOfClass:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFCLASS;
+  case SymbolSubKind::SwiftExtensionOfEnum:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFENUM;
+  case SymbolSubKind::SwiftExtensionOfProtocol:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTEXTENSIONOFPROTOCOL;
+  case SymbolSubKind::SwiftPrefixOperator:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTPREFIXOPERATOR;
+  case SymbolSubKind::SwiftPostfixOperator:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTPOSTFIXOPERATOR;
+  case SymbolSubKind::SwiftInfixOperator:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTINFIXOPERATOR;
+  case SymbolSubKind::SwiftSubscript:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTSUBSCRIPT;
+  case SymbolSubKind::SwiftAssociatedType:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTASSOCIATEDTYPE;
+  case SymbolSubKind::SwiftGenericTypeParam:
+    return INDEXSTORE_SYMBOL_SUBKIND_SWIFTGENERICTYPEPARAM;
+  }
+  llvm_unreachable("unexpected symbol subkind");
+}
+
+/// Map a SymbolLanguage to a indexstore_symbol_language_t.
+indexstore_symbol_language_t index::getIndexStoreLang(SymbolLanguage L) {
+  switch (L) {
+  case SymbolLanguage::C:
+    return INDEXSTORE_SYMBOL_LANG_C;
+  case SymbolLanguage::ObjC:
+    return INDEXSTORE_SYMBOL_LANG_OBJC;
+  case SymbolLanguage::CXX:
+    return INDEXSTORE_SYMBOL_LANG_CXX;
+  case SymbolLanguage::Swift:
+    return INDEXSTORE_SYMBOL_LANG_SWIFT;
+  }
+  llvm_unreachable("unexpected symbol language");
+}
+
+/// Map a SymbolPropertySet to its indexstore representation.
+uint64_t index::getIndexStoreProperties(SymbolPropertySet Props) {
+  uint64_t storeProp = 0;
+  applyForEachSymbolProperty(Props, [&](SymbolProperty prop) {
+    switch (prop) {
+    case SymbolProperty::Generic:
+      storeProp |= INDEXSTORE_SYMBOL_PROPERTY_GENERIC;
+      break;
+    case SymbolProperty::TemplatePartialSpecialization:
+      storeProp |= INDEXSTORE_SYMBOL_PROPERTY_TEMPLATE_PARTIAL_SPECIALIZATION;
+      break;
+    case SymbolProperty::TemplateSpecialization:
+      storeProp |= INDEXSTORE_SYMBOL_PROPERTY_TEMPLATE_SPECIALIZATION;
+      break;
+    case SymbolProperty::UnitTest:
+      storeProp |= INDEXSTORE_SYMBOL_PROPERTY_UNITTEST;
+      break;
+    case SymbolProperty::IBAnnotated:
+      storeProp |= INDEXSTORE_SYMBOL_PROPERTY_IBANNOTATED;
+      break;
+    case SymbolProperty::IBOutletCollection:
+      storeProp |= INDEXSTORE_SYMBOL_PROPERTY_IBOUTLETCOLLECTION;
+      break;
+    case SymbolProperty::GKInspectable:
+      storeProp |= INDEXSTORE_SYMBOL_PROPERTY_GKINSPECTABLE;
+      break;
+    case SymbolProperty::Local:
+      storeProp |= INDEXSTORE_SYMBOL_PROPERTY_LOCAL;
+      break;
+    }
+  });
+  return storeProp;
+}
+
+/// Map a SymbolRoleSet to its indexstore representation.
+uint64_t index::getIndexStoreRoles(SymbolRoleSet Roles) {
+  uint64_t storeRoles = 0;
+  applyForEachSymbolRole(Roles, [&](SymbolRole role) {
+    switch (role) {
+    case SymbolRole::Declaration:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_DECLARATION;
+      break;
+    case SymbolRole::Definition:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_DEFINITION;
+      break;
+    case SymbolRole::Reference:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REFERENCE;
+      break;
+    case SymbolRole::Read:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_READ;
+      break;
+    case SymbolRole::Write:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_WRITE;
+      break;
+    case SymbolRole::Call:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_CALL;
+      break;
+    case SymbolRole::Dynamic:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_DYNAMIC;
+      break;
+    case SymbolRole::AddressOf:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_ADDRESSOF;
+      break;
+    case SymbolRole::Implicit:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_IMPLICIT;
+      break;
+    case SymbolRole::RelationChildOf:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_CHILDOF;
+      break;
+    case SymbolRole::RelationBaseOf:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_BASEOF;
+      break;
+    case SymbolRole::RelationOverrideOf:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_OVERRIDEOF;
+      break;
+    case SymbolRole::RelationReceivedBy:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_RECEIVEDBY;
+      break;
+    case SymbolRole::RelationCalledBy:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_CALLEDBY;
+      break;
+    case SymbolRole::RelationExtendedBy:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_EXTENDEDBY;
+      break;
+    case SymbolRole::RelationAccessorOf:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_ACCESSOROF;
+      break;
+    case SymbolRole::RelationContainedBy:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_CONTAINEDBY;
+      break;
+    case SymbolRole::RelationIBTypeOf:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_IBTYPEOF;
+      break;
+    case SymbolRole::RelationSpecializationOf:
+      storeRoles |= INDEXSTORE_SYMBOL_ROLE_REL_SPECIALIZATIONOF;
+      break;
+    }
+  });
+  return storeRoles;
+}
diff --git a/lib/Index/IndexDataStoreUtils.h b/lib/Index/IndexDataStoreUtils.h
new file mode 100644
index 0000000..ad310e1
--- /dev/null
+++ b/lib/Index/IndexDataStoreUtils.h
@@ -0,0 +1,116 @@
+//===--- IndexDataStoreUtils.h - Functions/constants for the data store ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_INDEX_INDEXDATASTOREUTILS_H
+#define LLVM_CLANG_LIB_INDEX_INDEXDATASTOREUTILS_H
+
+#include "llvm/Bitcode/BitCodes.h"
+#include "clang/Basic/LLVM.h"
+
+namespace llvm {
+  class BitstreamWriter;
+}
+
+namespace clang {
+namespace index {
+namespace store {
+
+static const unsigned STORE_FORMAT_VERSION = 5;
+
+void appendUnitSubDir(SmallVectorImpl<char> &StorePathBuf);
+void appendInteriorUnitPath(StringRef UnitName,
+                            SmallVectorImpl<char> &PathBuf);
+void appendRecordSubDir(SmallVectorImpl<char> &StorePathBuf);
+void appendInteriorRecordPath(StringRef RecordName,
+                              SmallVectorImpl<char> &PathBuf);
+
+enum RecordBitRecord {
+  REC_VERSION         = 0,
+  REC_DECLINFO        = 1,
+  REC_DECLOFFSETS     = 2,
+  REC_DECLOCCURRENCE  = 3,
+};
+
+enum RecordBitBlock {
+  REC_VERSION_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+  REC_DECLS_BLOCK_ID,
+  REC_DECLOFFSETS_BLOCK_ID,
+  REC_DECLOCCURRENCES_BLOCK_ID,
+};
+
+enum UnitBitRecord {
+  UNIT_VERSION        = 0,
+  UNIT_INFO           = 1,
+  UNIT_DEPENDENCY     = 2,
+  UNIT_INCLUDE        = 3,
+  UNIT_PATH           = 4,
+  UNIT_PATH_BUFFER    = 5,
+  UNIT_MODULE         = 6,
+  UNIT_MODULE_BUFFER  = 7,
+};
+
+enum UnitBitBlock {
+  UNIT_VERSION_BLOCK_ID = llvm::bitc::FIRST_APPLICATION_BLOCKID,
+  UNIT_INFO_BLOCK_ID,
+  UNIT_DEPENDENCIES_BLOCK_ID,
+  UNIT_INCLUDES_BLOCK_ID,
+  UNIT_PATHS_BLOCK_ID,
+  UNIT_MODULES_BLOCK_ID,
+};
+
+enum UnitDependencyKind {
+  UNIT_DEPEND_KIND_FILE = 0,
+  UNIT_DEPEND_KIND_RECORD = 1,
+  UNIT_DEPEND_KIND_UNIT = 2,
+};
+static const unsigned UnitDependencyKindBitNum = 2;
+
+enum UnitFilePathPrefixKind {
+  UNIT_PATH_PREFIX_NONE = 0,
+  UNIT_PATH_PREFIX_WORKDIR = 1,
+  UNIT_PATH_PREFIX_SYSROOT = 2,
+};
+static const unsigned UnitFilePathPrefixKindBitNum = 2;
+
+typedef SmallVector<uint64_t, 64> RecordData;
+typedef SmallVectorImpl<uint64_t> RecordDataImpl;
+
+struct BitPathComponent {
+  size_t Offset = 0;
+  size_t Size = 0;
+  BitPathComponent(size_t Offset, size_t Size) : Offset(Offset), Size(Size) {}
+  BitPathComponent() = default;
+};
+
+struct DirBitPath {
+  UnitFilePathPrefixKind PrefixKind = UNIT_PATH_PREFIX_NONE;
+  BitPathComponent Dir;
+  DirBitPath(UnitFilePathPrefixKind Kind,
+             BitPathComponent Dir) : PrefixKind(Kind), Dir(Dir) {}
+  DirBitPath() = default;
+};
+
+struct FileBitPath : DirBitPath {
+  BitPathComponent Filename;
+  FileBitPath(UnitFilePathPrefixKind Kind, BitPathComponent Dir,
+              BitPathComponent Filename) : DirBitPath(Kind, Dir), Filename(Filename) {}
+  FileBitPath() = default;
+};
+
+void emitBlockID(unsigned ID, const char *Name,
+                 llvm::BitstreamWriter &Stream, RecordDataImpl &Record);
+
+void emitRecordID(unsigned ID, const char *Name,
+                  llvm::BitstreamWriter &Stream, RecordDataImpl &Record);
+
+} // end namespace store
+} // end namespace index
+} // end namespace clang
+
+#endif
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp
index c5230c0..ee28ef7 100644
--- a/lib/Index/IndexDecl.cpp
+++ b/lib/Index/IndexDecl.cpp
@@ -267,6 +267,10 @@
                                  TypeNameInfo->getTypeLoc().getLocStart(),
                                  Dtor->getParent(), Dtor->getDeclContext());
       }
+    } else if (const auto *Guide = dyn_cast<CXXDeductionGuideDecl>(D)) {
+      IndexCtx.handleReference(Guide->getDeducedTemplate()->getTemplatedDecl(),
+                               Guide->getLocation(), Guide,
+                               Guide->getDeclContext());
     }
     // Template specialization arguments.
     if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
@@ -607,6 +611,24 @@
                                     SymbolRoleSet());
   }
 
+  bool VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
+    TRY_DECL(D, IndexCtx.handleDecl(D));
+    const DeclContext *DC = D->getDeclContext()->getRedeclContext();
+    const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
+    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
+                                         D->getLexicalDeclContext());
+    return true;
+  }
+
+  bool VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
+    TRY_DECL(D, IndexCtx.handleDecl(D));
+    const DeclContext *DC = D->getDeclContext()->getRedeclContext();
+    const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
+    IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), Parent,
+                                         D->getLexicalDeclContext());
+    return true;
+  }
+
   bool VisitClassTemplateSpecializationDecl(const
                                            ClassTemplateSpecializationDecl *D) {
     // FIXME: Notify subsequent callbacks if info comes from implicit
diff --git a/lib/Index/IndexRecordHasher.cpp b/lib/Index/IndexRecordHasher.cpp
new file mode 100644
index 0000000..1edf4c1
--- /dev/null
+++ b/lib/Index/IndexRecordHasher.cpp
@@ -0,0 +1,480 @@
+//===--- IndexRecordHasher.cpp - Index record hashing ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "IndexRecordHasher.h"
+#include "FileIndexRecord.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclVisitor.h"
+#include "llvm/Support/Path.h"
+
+#define INITIAL_HASH 5381
+#define COMBINE_HASH(...) (Hash = hash_combine(Hash, __VA_ARGS__))
+
+using namespace clang;
+using namespace clang::index;
+using namespace llvm;
+
+static hash_code computeHash(const TemplateArgument &Arg,
+                             IndexRecordHasher &Hasher);
+
+namespace {
+class DeclHashVisitor : public ConstDeclVisitor<DeclHashVisitor, hash_code> {
+  IndexRecordHasher &Hasher;
+
+public:
+  DeclHashVisitor(IndexRecordHasher &Hasher) : Hasher(Hasher) {}
+
+  hash_code VisitDecl(const Decl *D) {
+    return VisitDeclContext(D->getDeclContext());
+  }
+
+  hash_code VisitNamedDecl(const NamedDecl *D) {
+    hash_code Hash = VisitDecl(D);
+    if (auto *attr = D->getExternalSourceSymbolAttr()) {
+      COMBINE_HASH(hash_value(attr->getDefinedIn()));
+    }
+    return COMBINE_HASH(Hasher.hash(D->getDeclName()));
+  }
+
+  hash_code VisitTagDecl(const TagDecl *D) {
+    if (D->getDeclName().isEmpty()) {
+      if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl())
+        return Visit(TD);
+
+      hash_code Hash = VisitDeclContext(D->getDeclContext());
+      if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
+        COMBINE_HASH(hashLoc(D->getLocation(), /*IncludeOffset=*/true));
+      } else
+        COMBINE_HASH('a');
+      return Hash;
+    }
+
+    hash_code Hash = VisitTypeDecl(D);
+    return COMBINE_HASH('T');
+  }
+
+  hash_code VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *D) {
+    hash_code Hash = VisitCXXRecordDecl(D);
+    const TemplateArgumentList &Args = D->getTemplateArgs();
+    COMBINE_HASH('>');
+    for (unsigned I = 0, N = Args.size(); I != N; ++I) {
+      COMBINE_HASH(computeHash(Args.get(I), Hasher));
+    }
+    return Hash;
+  }
+
+  hash_code VisitObjCContainerDecl(const ObjCContainerDecl *D) {
+    hash_code Hash = VisitNamedDecl(D);
+    return COMBINE_HASH('I');
+  }
+
+  hash_code VisitObjCImplDecl(const ObjCImplDecl *D) {
+    if (auto *ID = D->getClassInterface())
+      return VisitObjCInterfaceDecl(ID);
+    else
+      return 0;
+  }
+
+  hash_code VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
+    // FIXME: Differentiate between category and the interface ?
+    if (auto *ID = D->getClassInterface())
+      return VisitObjCInterfaceDecl(ID);
+    else
+      return 0;
+  }
+
+  hash_code VisitFunctionDecl(const FunctionDecl *D) {
+    hash_code Hash = VisitNamedDecl(D);
+    ASTContext &Ctx = Hasher.getASTContext();
+    if ((!Ctx.getLangOpts().CPlusPlus && !D->hasAttr<OverloadableAttr>())
+        || D->isExternC())
+      return Hash;
+
+    for (auto param : D->parameters()) {
+      COMBINE_HASH(Hasher.hash(param->getType()));
+    }
+    return Hash;
+  }
+
+  hash_code VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
+    hash_code Hash = VisitNamedDecl(D);
+    COMBINE_HASH(Hasher.hash(D->getQualifier()));
+    return Hash;
+  }
+
+  hash_code VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
+    hash_code Hash = VisitNamedDecl(D);
+    COMBINE_HASH(Hasher.hash(D->getQualifier()));
+    return Hash;
+  }
+
+  hash_code VisitDeclContext(const DeclContext *DC) {
+    // FIXME: Add location if this is anonymous namespace ?
+    DC = DC->getRedeclContext();
+    const Decl *D = cast<Decl>(DC)->getCanonicalDecl();
+    if (auto *ND = dyn_cast<NamedDecl>(D))
+      return Hasher.hash(ND);
+    else
+      return 0;
+  }
+
+  hash_code hashLoc(SourceLocation Loc, bool IncludeOffset) {
+    if (Loc.isInvalid()) {
+      return 0;
+    }
+    hash_code Hash = INITIAL_HASH;
+    const SourceManager &SM = Hasher.getASTContext().getSourceManager();
+    Loc = SM.getFileLoc(Loc);
+    const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc);
+    const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
+    if (FE) {
+      COMBINE_HASH(llvm::sys::path::filename(FE->getName()));
+    } else {
+      // This case really isn't interesting.
+      return 0;
+    }
+    if (IncludeOffset) {
+      // Use the offest into the FileID to represent the location.  Using
+      // a line/column can cause us to look back at the original source file,
+      // which is expensive.
+      COMBINE_HASH(Decomposed.second);
+    }
+    return Hash;
+  }
+};
+}
+
+hash_code IndexRecordHasher::hashRecord(const FileIndexRecord &Record) {
+  hash_code Hash = INITIAL_HASH;
+  for (auto &Info : Record.getDeclOccurrences()) {
+    COMBINE_HASH(Info.Roles, Info.Offset, hash(Info.Dcl));
+    for (auto &Rel : Info.Relations) {
+      COMBINE_HASH(hash(Rel.RelatedSymbol));
+    }
+  }
+  return Hash;
+}
+
+hash_code IndexRecordHasher::hash(const Decl *D) {
+  assert(D->isCanonicalDecl());
+
+  if (isa<TagDecl>(D) || isa<ObjCContainerDecl>(D)) {
+    return tryCache(D, D);
+  } else  if (auto *NS = dyn_cast<NamespaceDecl>(D)) {
+    if (NS->isAnonymousNamespace())
+      return hash_value(StringRef("@aN"));
+    return tryCache(D, D);
+  } else {
+    // There's a balance between caching results and not growing the cache too
+    // much. Measurements showed that avoiding caching all decls is beneficial
+    // particularly when including all of Cocoa.
+    return hashImpl(D);
+  }
+}
+
+hash_code IndexRecordHasher::hash(QualType NonCanTy) {
+  CanQualType CanTy = Ctx.getCanonicalType(NonCanTy);
+  return hash(CanTy);
+}
+
+hash_code IndexRecordHasher::hash(CanQualType CT) {
+  // Do some hashing without going to the cache, for example we can avoid
+  // storing the hash for both the type and its const-qualified version.
+  hash_code Hash = INITIAL_HASH;
+
+  auto asCanon = [](QualType Ty) -> CanQualType {
+    return CanQualType::CreateUnsafe(Ty);
+  };
+
+  while (true) {
+    Qualifiers Q = CT.getQualifiers();
+    CT = CT.getUnqualifiedType();
+    const Type *T = CT.getTypePtr();
+    unsigned qVal = 0;
+    if (Q.hasConst())
+      qVal |= 0x1;
+    if (Q.hasVolatile())
+      qVal |= 0x2;
+    if (Q.hasRestrict())
+      qVal |= 0x4;
+    if(qVal)
+      COMBINE_HASH(qVal);
+
+    // Hash in ObjC GC qualifiers?
+
+    if (const BuiltinType *BT = dyn_cast<BuiltinType>(T)) {
+      return COMBINE_HASH(BT->getKind());
+    }
+    if (const PointerType *PT = dyn_cast<PointerType>(T)) {
+      COMBINE_HASH('*');
+      CT = asCanon(PT->getPointeeType());
+      continue;
+    }
+    if (const ReferenceType *RT = dyn_cast<ReferenceType>(T)) {
+      COMBINE_HASH('&');
+      CT = asCanon(RT->getPointeeType());
+      continue;
+    }
+    if (const BlockPointerType *BT = dyn_cast<BlockPointerType>(T)) {
+      COMBINE_HASH('B');
+      CT = asCanon(BT->getPointeeType());
+      continue;
+    }
+    if (const ObjCObjectPointerType *OPT = dyn_cast<ObjCObjectPointerType>(T)) {
+      COMBINE_HASH('*');
+      CT = asCanon(OPT->getPointeeType());
+      continue;
+    }
+    if (const TagType *TT = dyn_cast<TagType>(T)) {
+      return COMBINE_HASH('$', hash(TT->getDecl()->getCanonicalDecl()));
+    }
+    if (const ObjCInterfaceType *OIT = dyn_cast<ObjCInterfaceType>(T)) {
+      return COMBINE_HASH('$', hash(OIT->getDecl()->getCanonicalDecl()));
+    }
+    if (const ObjCObjectType *OIT = dyn_cast<ObjCObjectType>(T)) {
+      for (auto *Prot : OIT->getProtocols())
+        COMBINE_HASH(hash(Prot));
+      CT = asCanon(OIT->getBaseType());
+      continue;
+    }
+    if (const TemplateTypeParmType *TTP = dyn_cast<TemplateTypeParmType>(T)) {
+      return COMBINE_HASH('t', TTP->getDepth(), TTP->getIndex());
+    }
+    if (const InjectedClassNameType *InjT = dyn_cast<InjectedClassNameType>(T)) {
+      CT = asCanon(InjT->getInjectedSpecializationType().getCanonicalType());
+      continue;
+    }
+
+    break;
+  }
+
+  return COMBINE_HASH(tryCache(CT.getAsOpaquePtr(), CT));
+}
+
+hash_code IndexRecordHasher::hash(DeclarationName Name) {
+  assert(!Name.isEmpty());
+  // Measurements for using cache or not here, showed significant slowdown when
+  // using the cache for all DeclarationNames when parsing Cocoa, and minor
+  // improvement or no difference for a couple of C++ single translation unit
+  // files. So we avoid caching DeclarationNames.
+  return hashImpl(Name);
+}
+
+hash_code IndexRecordHasher::hash(const NestedNameSpecifier *NNS) {
+  assert(NNS);
+  // Measurements for the C++ single translation unit files did not show much
+  // difference here; choosing to cache them currently.
+  return tryCache(NNS, NNS);
+}
+
+template <typename T>
+hash_code IndexRecordHasher::tryCache(const void *Ptr, T Obj) {
+  auto It = HashByPtr.find(Ptr);
+  if (It != HashByPtr.end())
+    return It->second;
+
+  hash_code Hash = hashImpl(Obj);
+  // hashImpl() may call into tryCache recursively and mutate
+  // HashByPtr, so we use find() earlier and insert the hash with another
+  // lookup here instead of calling insert() earlier and utilizing the iterator
+  // that insert() returns.
+  HashByPtr[Ptr] = Hash;
+  return Hash;
+}
+
+hash_code IndexRecordHasher::hashImpl(const Decl *D) {
+  return DeclHashVisitor(*this).Visit(D);
+}
+
+static hash_code computeHash(const IdentifierInfo *II) {
+  return hash_value(II->getName());
+}
+
+static hash_code computeHash(Selector Sel) {
+  unsigned N = Sel.getNumArgs();
+  if (N == 0)
+    ++N;
+  hash_code Hash = INITIAL_HASH;
+  for (unsigned I = 0; I != N; ++I)
+    if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I))
+      COMBINE_HASH(computeHash(II));
+  return Hash;
+}
+
+static hash_code computeHash(TemplateName Name, IndexRecordHasher &Hasher) {
+  hash_code Hash = INITIAL_HASH;
+  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
+    if (TemplateTemplateParmDecl *TTP
+        = dyn_cast<TemplateTemplateParmDecl>(Template)) {
+      return COMBINE_HASH('t', TTP->getDepth(), TTP->getIndex());
+    }
+
+    return COMBINE_HASH(Hasher.hash(Template->getCanonicalDecl()));
+  }
+
+  // FIXME: Hash dependent template names.
+  return Hash;
+}
+
+static hash_code computeHash(const TemplateArgument &Arg,
+                             IndexRecordHasher &Hasher) {
+  hash_code Hash = INITIAL_HASH;
+
+  switch (Arg.getKind()) {
+  case TemplateArgument::Null:
+    break;
+
+  case TemplateArgument::Declaration:
+    COMBINE_HASH(Hasher.hash(Arg.getAsDecl()));
+    break;
+
+  case TemplateArgument::NullPtr:
+    break;
+
+  case TemplateArgument::TemplateExpansion:
+    COMBINE_HASH('P'); // pack expansion of...
+    // Fall through
+  case TemplateArgument::Template:
+    COMBINE_HASH(computeHash(Arg.getAsTemplateOrTemplatePattern(), Hasher));
+    break;
+      
+  case TemplateArgument::Expression:
+    // FIXME: Hash expressions.
+    break;
+      
+  case TemplateArgument::Pack:
+    COMBINE_HASH('p');
+    for (const auto &P : Arg.pack_elements())
+      COMBINE_HASH(computeHash(P, Hasher));
+    break;
+      
+  case TemplateArgument::Type:
+    COMBINE_HASH(Hasher.hash(Arg.getAsType()));
+    break;
+      
+  case TemplateArgument::Integral:
+    COMBINE_HASH('V', Hasher.hash(Arg.getIntegralType()), Arg.getAsIntegral());
+    break;
+  }
+
+  return Hash;
+}
+
+hash_code IndexRecordHasher::hashImpl(CanQualType CQT) {
+  hash_code Hash = INITIAL_HASH;
+
+  auto asCanon = [](QualType Ty) -> CanQualType {
+    return CanQualType::CreateUnsafe(Ty);
+  };
+
+  const Type *T = CQT.getTypePtr();
+
+  if (const PackExpansionType *Expansion = dyn_cast<PackExpansionType>(T)) {
+    return COMBINE_HASH('P', hash(asCanon(Expansion->getPattern())));
+  }
+  if (const RValueReferenceType *RT = dyn_cast<RValueReferenceType>(T)) {
+    return COMBINE_HASH('%', hash(asCanon(RT->getPointeeType())));
+  }
+  if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(T)) {
+    COMBINE_HASH('F', hash(asCanon(FT->getReturnType())));
+    for (const auto &I : FT->param_types())
+      COMBINE_HASH(hash(asCanon(I)));
+    return COMBINE_HASH(FT->isVariadic());
+  }
+  if (const ComplexType *CT = dyn_cast<ComplexType>(T)) {
+    return COMBINE_HASH('<', hash(asCanon(CT->getElementType())));
+  }
+  if (const TemplateSpecializationType *Spec
+      = dyn_cast<TemplateSpecializationType>(T)) {
+    COMBINE_HASH('>', computeHash(Spec->getTemplateName(), *this));
+    for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
+      COMBINE_HASH(computeHash(Spec->getArg(I), *this));
+    return Hash;
+  }
+  if (const DependentNameType *DNT = dyn_cast<DependentNameType>(T)) {
+    COMBINE_HASH('^');
+    if (const NestedNameSpecifier *NNS = DNT->getQualifier())
+      COMBINE_HASH(hash(NNS));
+    return COMBINE_HASH(computeHash(DNT->getIdentifier()));
+  }
+
+  // Unhandled type.
+  return Hash;
+}
+
+hash_code IndexRecordHasher::hashImpl(DeclarationName Name) {
+  hash_code Hash = INITIAL_HASH;
+  COMBINE_HASH(Name.getNameKind());
+
+  switch (Name.getNameKind()) {
+    case DeclarationName::Identifier:
+      COMBINE_HASH(computeHash(Name.getAsIdentifierInfo()));
+      break;
+    case DeclarationName::ObjCZeroArgSelector:
+    case DeclarationName::ObjCOneArgSelector:
+    case DeclarationName::ObjCMultiArgSelector:
+      COMBINE_HASH(computeHash(Name.getObjCSelector()));
+      break;
+    case DeclarationName::CXXConstructorName:
+    case DeclarationName::CXXDestructorName:
+    case DeclarationName::CXXConversionFunctionName:
+      break;
+    case DeclarationName::CXXOperatorName:
+      COMBINE_HASH(Name.getCXXOverloadedOperator());
+      break;
+    case DeclarationName::CXXLiteralOperatorName:
+      COMBINE_HASH(computeHash(Name.getCXXLiteralIdentifier()));
+    case DeclarationName::CXXUsingDirective:
+      break;
+    case DeclarationName::CXXDeductionGuideName:
+      COMBINE_HASH(computeHash(Name.getCXXDeductionGuideTemplate()
+                 ->getDeclName().getAsIdentifierInfo()));
+      break;
+  }
+
+  return Hash;
+}
+
+hash_code IndexRecordHasher::hashImpl(const NestedNameSpecifier *NNS) {
+  hash_code Hash = INITIAL_HASH;
+  if (auto *Pre = NNS->getPrefix())
+    COMBINE_HASH(hash(Pre));
+
+  COMBINE_HASH(NNS->getKind());
+
+  switch (NNS->getKind()) {
+  case NestedNameSpecifier::Identifier:
+    COMBINE_HASH(computeHash(NNS->getAsIdentifier()));
+    break;
+
+  case NestedNameSpecifier::Namespace:
+    COMBINE_HASH(hash(NNS->getAsNamespace()->getCanonicalDecl()));
+    break;
+
+  case NestedNameSpecifier::NamespaceAlias:
+    COMBINE_HASH(hash(NNS->getAsNamespaceAlias()->getCanonicalDecl()));
+    break;
+
+  case NestedNameSpecifier::Global:
+    break;
+
+  case NestedNameSpecifier::Super:
+    break;
+
+  case NestedNameSpecifier::TypeSpecWithTemplate:
+    // Fall through to hash the type.
+
+  case NestedNameSpecifier::TypeSpec:
+    COMBINE_HASH(hash(QualType(NNS->getAsType(), 0)));
+    break;
+  }
+
+  return Hash;
+}
diff --git a/lib/Index/IndexRecordHasher.h b/lib/Index/IndexRecordHasher.h
new file mode 100644
index 0000000..af3accc
--- /dev/null
+++ b/lib/Index/IndexRecordHasher.h
@@ -0,0 +1,58 @@
+//===--- IndexRecordHasher.h - Index record hashing -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_INDEX_INDEXRECORDHASHER_H
+#define LLVM_CLANG_LIB_INDEX_INDEXRECORDHASHER_H
+
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
+
+namespace clang {
+  class ASTContext;
+  class Decl;
+  class DeclarationName;
+  class NestedNameSpecifier;
+  class QualType;
+  class Type;
+  template <typename> class CanQual;
+  typedef CanQual<Type> CanQualType;
+
+namespace index {
+  class FileIndexRecord;
+
+class IndexRecordHasher {
+  ASTContext &Ctx;
+  llvm::DenseMap<const void *, llvm::hash_code> HashByPtr;
+
+public:
+  explicit IndexRecordHasher(ASTContext &Ctx) : Ctx(Ctx) {}
+  ASTContext &getASTContext() { return Ctx; }
+
+  llvm::hash_code hashRecord(const FileIndexRecord &Record);
+  llvm::hash_code hash(const Decl *D);
+  llvm::hash_code hash(QualType Ty);
+  llvm::hash_code hash(CanQualType Ty);
+  llvm::hash_code hash(DeclarationName Name);
+  llvm::hash_code hash(const NestedNameSpecifier *NNS);
+
+private:
+  template <typename T>
+  llvm::hash_code tryCache(const void *Ptr, T Obj);
+
+  llvm::hash_code hashImpl(const Decl *D);
+  llvm::hash_code hashImpl(CanQualType Ty);
+  llvm::hash_code hashImpl(DeclarationName Name);
+  llvm::hash_code hashImpl(const NestedNameSpecifier *NNS);
+};
+
+} // end namespace index
+} // end namespace clang
+
+#endif
diff --git a/lib/Index/IndexRecordReader.cpp b/lib/Index/IndexRecordReader.cpp
new file mode 100644
index 0000000..bd2ec1f
--- /dev/null
+++ b/lib/Index/IndexRecordReader.cpp
@@ -0,0 +1,407 @@
+//===--- IndexRecordReader.cpp - Index record deserialization -------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/IndexRecordReader.h"
+#include "IndexDataStoreUtils.h"
+#include "BitstreamVisitor.h"
+#include "clang/Index/IndexDataStoreSymbolUtils.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::index;
+using namespace clang::index::store;
+using namespace llvm;
+
+struct IndexRecordReader::Implementation {
+  BumpPtrAllocator Allocator;
+  std::unique_ptr<MemoryBuffer> Buffer;
+  llvm::BitstreamCursor DeclCursor;
+  llvm::BitstreamCursor OccurCursor;
+  ArrayRef<uint32_t> DeclOffsets;
+  const IndexRecordDecl **Decls;
+
+  void setDeclOffsets(ArrayRef<uint32_t> Offs) {
+    DeclOffsets = Offs;
+    Decls = Allocator.Allocate<const IndexRecordDecl*>(Offs.size());
+    memset(Decls, 0, sizeof(IndexRecordDecl*)*Offs.size());
+  }
+
+  unsigned getNumDecls() const { return DeclOffsets.size(); }
+
+  const IndexRecordDecl *getDeclByID(unsigned DeclID) {
+    if (DeclID == 0)
+      return nullptr;
+    return getDecl(DeclID-1);
+  }
+
+  const IndexRecordDecl *getDecl(unsigned Index) {
+    assert(Index < getNumDecls());
+    if (const IndexRecordDecl *D = Decls[Index])
+      return D;
+
+    IndexRecordDecl *D = Allocator.Allocate<IndexRecordDecl>();
+    readDecl(Index, *D);
+    Decls[Index] = D;
+    return D;
+  }
+
+  /// Goes through the decls and populates a vector of record decls, based on
+  /// what the given function returns.
+  ///
+  /// The advantage of this function is to allocate memory only for the record
+  /// decls that the caller is interested in.
+  bool searchDecls(llvm::function_ref<DeclSearchCheck> Checker,
+                   llvm::function_ref<void(const IndexRecordDecl *)> Receiver) {
+    for (unsigned I = 0, E = getNumDecls(); I != E; ++I) {
+      if (const IndexRecordDecl *D = Decls[I]) {
+        DeclSearchReturn Ret = Checker(*D);
+        if (Ret.AcceptDecl)
+          Receiver(D);
+        if (!Ret.ContinueSearch)
+          return false;
+        continue;
+      }
+
+      IndexRecordDecl LocalD;
+      readDecl(I, LocalD);
+      DeclSearchReturn Ret = Checker(LocalD);
+      if (Ret.AcceptDecl) {
+        IndexRecordDecl *D = Allocator.Allocate<IndexRecordDecl>();
+        *D = LocalD;
+        Decls[I] = D;
+        Receiver(D);
+      }
+      if (!Ret.ContinueSearch)
+        return false;
+    }
+    return true;
+  }
+
+  void readDecl(unsigned Index, IndexRecordDecl &RecD) {
+    RecordData Record;
+    StringRef Blob;
+    DeclCursor.JumpToBit(DeclOffsets[Index]);
+    unsigned Code = DeclCursor.ReadCode();
+    unsigned RecID = DeclCursor.readRecord(Code, Record, &Blob);
+    assert(RecID == REC_DECLINFO);
+    (void)RecID;
+
+    unsigned I = 0;
+    RecD.DeclID = Index+1;
+    RecD.SymInfo.Kind = getSymbolKind((indexstore_symbol_kind_t)read(Record, I));
+    RecD.SymInfo.SubKind = getSymbolSubKind((indexstore_symbol_subkind_t)read(Record, I));
+    RecD.SymInfo.Lang =
+        getSymbolLanguage((indexstore_symbol_language_t)read(Record, I));
+    RecD.SymInfo.Properties = getSymbolProperties(read(Record, I));
+    RecD.Roles = getSymbolRoles(read(Record, I));
+    RecD.RelatedRoles = getSymbolRoles(read(Record, I));
+    size_t NameLen = read(Record, I);
+    size_t USRLen = read(Record, I);
+    RecD.Name = Blob.substr(0, NameLen);
+    RecD.USR = Blob.substr(NameLen, USRLen);
+    RecD.CodeGenName = Blob.substr(NameLen+USRLen);
+  }
+
+  /// Reads occurrence data.
+  /// \param DeclsFilter if non-empty indicates the list of decls that we want
+  /// to get occurrences for. If empty then indicates that we want occurrences
+  /// for all decls.
+  /// \param RelatedDeclsFilter Same as \c DeclsFilter but for related decls.
+  /// \returns true if the occurrence info was filled out, false if occurrence
+  /// was ignored.
+  bool readOccurrence(RecordDataImpl &Record, StringRef Blob,
+                      ArrayRef<const IndexRecordDecl *> DeclsFilter,
+                      ArrayRef<const IndexRecordDecl *> RelatedDeclsFilter,
+                      IndexRecordOccurrence &RecOccur) {
+
+    auto isDeclIDContained = [](unsigned DeclID,
+                                ArrayRef<const IndexRecordDecl *> Ds) -> bool {
+      if (Ds.empty())
+        return true; // empty means accept all.
+      auto pred = [DeclID](const IndexRecordDecl *D) { return D->DeclID == DeclID; };
+      return std::find_if(Ds.begin(), Ds.end(), pred) != Ds.end();
+    };
+
+    unsigned I = 0;
+    unsigned DeclID = read(Record, I);
+    if (!isDeclIDContained(DeclID, DeclsFilter))
+      return false;
+
+    if (!RelatedDeclsFilter.empty()) {
+      unsigned RelI = I+3;
+      unsigned NumRelated = read(Record, RelI);
+      bool FoundRelated = false;
+      while (NumRelated--) {
+        ++RelI; // roles;
+        unsigned RelDID = read(Record, RelI);
+        if (isDeclIDContained(RelDID, RelatedDeclsFilter)) {
+          FoundRelated = true;
+          break;
+        }
+      }
+      if (!FoundRelated)
+        return false;
+    }
+
+    RecOccur.Dcl = getDeclByID(DeclID);
+    RecOccur.Roles = getSymbolRoles(read(Record, I));
+    RecOccur.Line = read(Record, I);
+    RecOccur.Column = read(Record, I);
+
+    unsigned NumRelated = read(Record, I);
+    while (NumRelated--) {
+      SymbolRoleSet RelRoles = getSymbolRoles(read(Record, I));
+      const IndexRecordDecl *RelD = getDeclByID(read(Record, I));
+      RecOccur.Relations.emplace_back(RelRoles, RelD);
+    }
+
+    return true;
+  }
+
+  bool foreachDecl(bool NoCache,
+                   function_ref<bool(const IndexRecordDecl *)> Receiver) {
+    for (unsigned I = 0, E = getNumDecls(); I != E; ++I) {
+      if (const IndexRecordDecl *D = Decls[I]) {
+        if (!Receiver(D))
+          return false;
+        continue;
+      }
+
+      if (NoCache) {
+        IndexRecordDecl LocalD;
+        readDecl(I, LocalD);
+        if (!Receiver(&LocalD))
+          return false;
+      } else {
+        if (!Receiver(getDecl(I)))
+          return false;
+      }
+    }
+    return true;
+  }
+
+  bool foreachOccurrence(ArrayRef<const IndexRecordDecl *> DeclsFilter,
+                         ArrayRef<const IndexRecordDecl *> RelatedDeclsFilter,
+                         function_ref<bool(const IndexRecordOccurrence &)> Receiver) {
+    class OccurBitVisitor : public BitstreamVisitor<OccurBitVisitor> {
+      IndexRecordReader::Implementation &Reader;
+      ArrayRef<const IndexRecordDecl *> DeclsFilter;
+      ArrayRef<const IndexRecordDecl *> RelatedDeclsFilter;
+      function_ref<bool(const IndexRecordOccurrence &)> Receiver;
+
+    public:
+      OccurBitVisitor(llvm::BitstreamCursor &Stream,
+                      IndexRecordReader::Implementation &Reader,
+                      ArrayRef<const IndexRecordDecl *> DeclsFilter,
+                      ArrayRef<const IndexRecordDecl *> RelatedDeclsFilter,
+                      function_ref<bool(const IndexRecordOccurrence &)> Receiver)
+        : BitstreamVisitor(Stream),
+          Reader(Reader),
+          DeclsFilter(DeclsFilter),
+          RelatedDeclsFilter(RelatedDeclsFilter),
+          Receiver(std::move(Receiver)) {}
+
+      StreamVisit visitRecord(unsigned BlockID, unsigned RecID,
+                              RecordDataImpl &Record, StringRef Blob) {
+        assert(RecID == REC_DECLOCCURRENCE);
+        IndexRecordOccurrence RecOccur;
+        if (Reader.readOccurrence(Record, Blob, DeclsFilter, RelatedDeclsFilter,
+                                   RecOccur))
+          if (!Receiver(RecOccur))
+            return StreamVisit::Abort;
+        return StreamVisit::Continue;
+      }
+    };
+
+    SavedStreamPosition SavedPosition(OccurCursor);
+    OccurBitVisitor Visitor(OccurCursor, *this, DeclsFilter, RelatedDeclsFilter,
+                            Receiver);
+    std::string Error;
+    return Visitor.visit(Error);
+  }
+
+  bool foreachOccurrenceInLineRange(unsigned lineStart, unsigned lineCount,
+            llvm::function_ref<bool(const IndexRecordOccurrence &)> receiver) {
+    // FIXME: Use binary search and make this more efficient.
+    unsigned lineEnd = lineStart+lineCount;
+    return foreachOccurrence(None, None, [&](const IndexRecordOccurrence &occur) -> bool {
+      if (occur.Line > lineEnd)
+        return false; // we're done.
+      if (occur.Line >= lineStart) {
+        if (!receiver(occur))
+          return false;
+      }
+      return true;
+    });
+  }
+
+  static uint64_t read(RecordDataImpl &Record, unsigned &I) {
+    return Record[I++];
+  }
+};
+
+namespace {
+
+class IndexBitstreamVisitor : public BitstreamVisitor<IndexBitstreamVisitor> {
+  IndexRecordReader::Implementation &Reader;
+
+public:
+  IndexBitstreamVisitor(llvm::BitstreamCursor &Stream,
+                        IndexRecordReader::Implementation &Reader)
+    : BitstreamVisitor(Stream), Reader(Reader) {}
+
+  StreamVisit visitBlock(unsigned ID) {
+    switch ((RecordBitBlock)ID) {
+    case REC_VERSION_BLOCK_ID:
+    case REC_DECLOFFSETS_BLOCK_ID:
+      return StreamVisit::Continue;
+
+    case REC_DECLS_BLOCK_ID:
+      Reader.DeclCursor = Stream;
+      if (Reader.DeclCursor.EnterSubBlock(ID)) {
+        *Error = "malformed block record";
+        return StreamVisit::Abort;
+      }
+      readBlockAbbrevs(Reader.DeclCursor);
+      return StreamVisit::Skip;
+
+    case REC_DECLOCCURRENCES_BLOCK_ID:
+      Reader.OccurCursor = Stream;
+      if (Reader.OccurCursor.EnterSubBlock(ID)) {
+        *Error = "malformed block record";
+        return StreamVisit::Abort;
+      }
+      readBlockAbbrevs(Reader.OccurCursor);
+      return StreamVisit::Skip;
+    }
+
+    // Some newly introduced block in a minor version update that we cannot
+    // handle.
+    return StreamVisit::Skip;
+  }
+
+  StreamVisit visitRecord(unsigned BlockID, unsigned RecID,
+                          RecordDataImpl &Record, StringRef Blob) {
+    switch (BlockID) {
+    case REC_VERSION_BLOCK_ID: {
+      unsigned StoreFormatVersion = Record[0];
+      if (StoreFormatVersion != STORE_FORMAT_VERSION) {
+        llvm::raw_string_ostream OS(*Error);
+        OS << "Store format version mismatch: " << StoreFormatVersion;
+        OS << " , expected: " << STORE_FORMAT_VERSION;
+        return StreamVisit::Abort;
+      }
+      break;
+    }
+    case REC_DECLOFFSETS_BLOCK_ID:
+      assert(RecID == REC_DECLOFFSETS);
+      Reader.setDeclOffsets(makeArrayRef((uint32_t*)Blob.data(), Record[0]));
+      break;
+
+    case REC_DECLS_BLOCK_ID:
+    case REC_DECLOCCURRENCES_BLOCK_ID:
+      llvm_unreachable("shouldn't visit this block'");
+    }
+    return StreamVisit::Continue;
+  }
+};
+
+} // anonymous namespace
+
+std::unique_ptr<IndexRecordReader>
+IndexRecordReader::createWithRecordFilename(StringRef RecordFilename,
+                                            StringRef StorePath,
+                                            std::string &Error) {
+  SmallString<128> PathBuf = StorePath;
+  appendRecordSubDir(PathBuf);
+  appendInteriorRecordPath(RecordFilename, PathBuf);
+  return createWithFilePath(PathBuf.str(), Error);
+}
+
+std::unique_ptr<IndexRecordReader>
+IndexRecordReader::createWithFilePath(StringRef FilePath, std::string &Error) {
+  auto ErrOrBuf = MemoryBuffer::getFile(FilePath, /*FileSize=*/-1,
+                                        /*RequiresNullTerminator=*/false);
+  if (!ErrOrBuf) {
+    raw_string_ostream(Error) << "failed opening index record '"
+      << FilePath << "': " << ErrOrBuf.getError().message();
+    return nullptr;
+  }
+  return createWithBuffer(std::move(*ErrOrBuf), Error);
+}
+
+std::unique_ptr<IndexRecordReader>
+IndexRecordReader::createWithBuffer(std::unique_ptr<llvm::MemoryBuffer> Buffer,
+                                    std::string &Error) {
+
+  std::unique_ptr<IndexRecordReader> Reader;
+  Reader.reset(new IndexRecordReader());
+  auto &Impl = Reader->Impl;
+  Impl.Buffer = std::move(Buffer);
+  llvm::BitstreamCursor Stream(*Impl.Buffer);
+
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'I' ||
+      Stream.Read(8) != 'D' ||
+      Stream.Read(8) != 'X' ||
+      Stream.Read(8) != 'R') {
+    Error = "not a serialized index record file";
+    return nullptr;
+  }
+
+  IndexBitstreamVisitor BitVisitor(Stream, Impl);
+  if (!BitVisitor.visit(Error))
+    return nullptr;
+
+  return Reader;
+}
+
+IndexRecordReader::IndexRecordReader()
+  : Impl(*new Implementation()) {
+
+}
+
+IndexRecordReader::~IndexRecordReader() {
+  delete &Impl;
+}
+
+bool IndexRecordReader::searchDecls(
+                        llvm::function_ref<DeclSearchCheck> Checker,
+                  llvm::function_ref<void(const IndexRecordDecl *)> Receiver) {
+  return Impl.searchDecls(std::move(Checker), std::move(Receiver));
+}
+
+bool IndexRecordReader::foreachDecl(bool NoCache,
+                                    function_ref<bool(const IndexRecordDecl *)> Receiver) {
+  return Impl.foreachDecl(NoCache, std::move(Receiver));
+}
+
+bool IndexRecordReader::foreachOccurrence(
+                  ArrayRef<const IndexRecordDecl *> DeclsFilter,
+                  ArrayRef<const IndexRecordDecl *> RelatedDeclsFilter,
+                  function_ref<bool(const IndexRecordOccurrence &)> Receiver) {
+  return Impl.foreachOccurrence(DeclsFilter, RelatedDeclsFilter,
+                                std::move(Receiver));
+}
+
+bool IndexRecordReader::foreachOccurrence(
+            llvm::function_ref<bool(const IndexRecordOccurrence &)> Receiver) {
+  return foreachOccurrence(None, None, std::move(Receiver));
+}
+
+bool IndexRecordReader::foreachOccurrenceInLineRange(unsigned lineStart,
+                                                     unsigned lineCount,
+             llvm::function_ref<bool(const IndexRecordOccurrence &)> Receiver) {
+  return Impl.foreachOccurrenceInLineRange(lineStart, lineCount, Receiver);
+}
diff --git a/lib/Index/IndexRecordWriter.cpp b/lib/Index/IndexRecordWriter.cpp
new file mode 100644
index 0000000..c4e6d50
--- /dev/null
+++ b/lib/Index/IndexRecordWriter.cpp
@@ -0,0 +1,366 @@
+//===--- IndexRecordWriter.cpp - Index record serialization ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/IndexRecordWriter.h"
+#include "IndexDataStoreUtils.h"
+#include "indexstore/indexstore.h"
+#include "clang/Index/IndexDataStoreSymbolUtils.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringSet.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::index;
+using namespace clang::index::store;
+using namespace llvm;
+
+using writer::OpaqueDecl;
+
+namespace {
+struct DeclInfo {
+  OpaqueDecl D;
+  SymbolRoleSet Roles;
+  SymbolRoleSet RelatedRoles;
+};
+
+struct OccurrenceInfo {
+  unsigned DeclID;
+  OpaqueDecl D;
+  SymbolRoleSet Roles;
+  unsigned Line;
+  unsigned Column;
+  SmallVector<std::pair<writer::SymbolRelation, unsigned>, 4> Related;
+};
+
+struct RecordState {
+  std::string RecordPath;
+  SmallString<512> Buffer;
+  BitstreamWriter Stream;
+
+  DenseMap<OpaqueDecl, unsigned> IndexForDecl;
+  std::vector<DeclInfo> Decls;
+  std::vector<OccurrenceInfo> Occurrences;
+
+  RecordState(std::string &&RecordPath)
+      : RecordPath(std::move(RecordPath)), Stream(Buffer) {}
+};
+} // end anonymous namespace
+
+static void writeBlockInfo(BitstreamWriter &Stream) {
+  RecordData Record;
+
+  Stream.EnterBlockInfoBlock();
+#define BLOCK(X) emitBlockID(X ## _ID, #X, Stream, Record)
+#define RECORD(X) emitRecordID(X, #X, Stream, Record)
+
+  BLOCK(REC_VERSION_BLOCK);
+  RECORD(REC_VERSION);
+
+  BLOCK(REC_DECLS_BLOCK);
+  RECORD(REC_DECLINFO);
+
+  BLOCK(REC_DECLOFFSETS_BLOCK);
+  RECORD(REC_DECLOFFSETS);
+
+  BLOCK(REC_DECLOCCURRENCES_BLOCK);
+  RECORD(REC_DECLOCCURRENCE);
+
+#undef RECORD
+#undef BLOCK
+  Stream.ExitBlock();
+}
+
+static void writeVersionInfo(BitstreamWriter &Stream) {
+  using namespace llvm::sys;
+
+  Stream.EnterSubblock(REC_VERSION_BLOCK_ID, 3);
+
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(REC_VERSION));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Store format version
+  unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+  RecordData Record;
+  Record.push_back(REC_VERSION);
+  Record.push_back(STORE_FORMAT_VERSION);
+  Stream.EmitRecordWithAbbrev(AbbrevCode, Record);
+
+  Stream.ExitBlock();
+}
+
+template <typename T, typename Allocator>
+static StringRef data(const std::vector<T, Allocator> &v) {
+  if (v.empty())
+    return StringRef();
+  return StringRef(reinterpret_cast<const char *>(&v[0]), sizeof(T) * v.size());
+}
+
+template <typename T> static StringRef data(const SmallVectorImpl<T> &v) {
+  return StringRef(reinterpret_cast<const char *>(v.data()),
+                   sizeof(T) * v.size());
+}
+
+static void writeDecls(BitstreamWriter &Stream, ArrayRef<DeclInfo> Decls,
+                       ArrayRef<OccurrenceInfo> Occurrences,
+                       writer::SymbolWriterCallback GetSymbolForDecl) {
+  SmallVector<uint32_t, 32> DeclOffsets;
+  DeclOffsets.reserve(Decls.size());
+
+  //===--------------------------------------------------------------------===//
+  // DECLS_BLOCK_ID
+  //===--------------------------------------------------------------------===//
+
+  Stream.EnterSubblock(REC_DECLS_BLOCK_ID, 3);
+
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(REC_DECLINFO));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 5)); // Kind
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 5)); // SubKind
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 5)); // Language
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, SymbolPropertyBitNum)); // Properties
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, SymbolRoleBitNum)); // Roles
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, SymbolRoleBitNum)); // Related Roles
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Length of name in block
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Length of USR in block
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name + USR + CodeGen symbol name
+  unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+#ifndef NDEBUG
+  StringSet<> USRSet;
+#endif
+
+  RecordData Record;
+  llvm::SmallString<256> Blob;
+  llvm::SmallString<256> Scratch;
+  for (auto &Info : Decls) {
+    DeclOffsets.push_back(Stream.GetCurrentBitNo());
+    Blob.clear();
+    Scratch.clear();
+
+    writer::Symbol SymInfo = GetSymbolForDecl(Info.D, Scratch);
+    assert(SymInfo.SymInfo.Kind != SymbolKind::Unknown);
+    assert(!SymInfo.USR.empty() && "Recorded decl without USR!");
+
+    Blob += SymInfo.Name;
+    Blob += SymInfo.USR;
+    Blob += SymInfo.CodeGenName;
+
+#ifndef NDEBUG
+    bool IsNew = USRSet.insert(SymInfo.USR).second;
+    if (!IsNew) {
+      llvm::errs() << "Index: Duplicate USR! " << SymInfo.USR << "\n";
+      // FIXME: print more information so it's easier to find the declaration.
+    }
+#endif
+
+    Record.clear();
+    Record.push_back(REC_DECLINFO);
+    Record.push_back(getIndexStoreKind(SymInfo.SymInfo.Kind));
+    Record.push_back(getIndexStoreSubKind(SymInfo.SymInfo.SubKind));
+    Record.push_back(getIndexStoreLang(SymInfo.SymInfo.Lang));
+    Record.push_back(getIndexStoreProperties(SymInfo.SymInfo.Properties));
+    Record.push_back(getIndexStoreRoles(Info.Roles));
+    Record.push_back(getIndexStoreRoles(Info.RelatedRoles));
+    Record.push_back(SymInfo.Name.size());
+    Record.push_back(SymInfo.USR.size());
+    Stream.EmitRecordWithBlob(AbbrevCode, Record, Blob);
+  }
+
+  Stream.ExitBlock();
+
+  //===--------------------------------------------------------------------===//
+  // DECLOFFSETS_BLOCK_ID
+  //===--------------------------------------------------------------------===//
+
+  Stream.EnterSubblock(REC_DECLOFFSETS_BLOCK_ID, 3);
+
+  Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(REC_DECLOFFSETS));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // Number of Decls
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Offsets array
+  AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+  Record.clear();
+  Record.push_back(REC_DECLOFFSETS);
+  Record.push_back(DeclOffsets.size());
+  Stream.EmitRecordWithBlob(AbbrevCode, Record, data(DeclOffsets));
+
+  Stream.ExitBlock();
+
+  //===--------------------------------------------------------------------===//
+  // DECLOCCURRENCES_BLOCK_ID
+  //===--------------------------------------------------------------------===//
+
+  Stream.EnterSubblock(REC_DECLOCCURRENCES_BLOCK_ID, 3);
+
+  Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(REC_DECLOCCURRENCE));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Decl ID
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, SymbolRoleBitNum)); // Roles
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // Line
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Column
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Num related
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); // Related Roles/IDs
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // Roles or ID
+  AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+  for (auto &Occur : Occurrences) {
+    Record.clear();
+    Record.push_back(REC_DECLOCCURRENCE);
+    Record.push_back(Occur.DeclID);
+    Record.push_back(getIndexStoreRoles(Occur.Roles));
+    Record.push_back(Occur.Line);
+    Record.push_back(Occur.Column);
+    Record.push_back(Occur.Related.size());
+    for (auto &Rel : Occur.Related) {
+      Record.push_back(getIndexStoreRoles(Rel.first.Roles));
+      Record.push_back(Rel.second);
+    }
+    Stream.EmitRecordWithAbbrev(AbbrevCode, Record);
+  }
+  Stream.ExitBlock();
+}
+
+IndexRecordWriter::IndexRecordWriter(StringRef IndexPath)
+    : RecordsPath(IndexPath) {
+  store::appendRecordSubDir(RecordsPath);
+}
+
+IndexRecordWriter::Result
+IndexRecordWriter::beginRecord(StringRef Filename, hash_code RecordHash,
+                               std::string &Error, std::string *OutRecordFile) {
+  using namespace llvm::sys;
+  assert(!Record && "called beginRecord before calling endRecord on previous");
+
+  std::string RecordName;
+  {
+    llvm::raw_string_ostream RN(RecordName);
+    RN << path::filename(Filename);
+    RN << "-" << APInt(64, RecordHash).toString(36, /*Signed=*/false);
+  }
+  SmallString<256> RecordPath = RecordsPath.str();
+  appendInteriorRecordPath(RecordName, RecordPath);
+
+  if (OutRecordFile)
+    *OutRecordFile = RecordName;
+
+  if (std::error_code EC =
+          fs::access(RecordPath.c_str(), fs::AccessMode::Exist)) {
+    if (EC != errc::no_such_file_or_directory) {
+      llvm::raw_string_ostream Err(Error);
+      Err << "could not access record '" << RecordPath
+          << "': " << EC.message();
+      return Result::Failure;
+    }
+  } else {
+    return Result::AlreadyExists;
+  }
+
+  // Write the record header.
+  auto *State = new RecordState(RecordPath.str());
+  Record = State;
+  llvm::BitstreamWriter &Stream = State->Stream;
+  Stream.Emit('I', 8);
+  Stream.Emit('D', 8);
+  Stream.Emit('X', 8);
+  Stream.Emit('R', 8);
+
+  writeBlockInfo(Stream);
+  writeVersionInfo(Stream);
+
+  return Result::Success;
+}
+
+IndexRecordWriter::Result
+IndexRecordWriter::endRecord(std::string &Error,
+                             writer::SymbolWriterCallback GetSymbolForDecl) {
+  assert(Record && "called endRecord without calling beginRecord");
+  auto &State = *static_cast<RecordState *>(Record);
+  Record = nullptr;
+  struct ScopedDelete {
+    RecordState *S;
+    ScopedDelete(RecordState *S) : S(S) {}
+    ~ScopedDelete() { delete S; }
+  } Deleter(&State);
+
+  if (!State.Decls.empty()) {
+    writeDecls(State.Stream, State.Decls, State.Occurrences, GetSymbolForDecl);
+  }
+
+  if (std::error_code EC = sys::fs::create_directory(sys::path::parent_path(State.RecordPath))) {
+    llvm::raw_string_ostream Err(Error);
+    Err << "failed to create directory '" << sys::path::parent_path(State.RecordPath) << "': " << EC.message();
+    return Result::Failure;
+  }
+
+  // Create a unique file to write to so that we can move the result into place
+  // atomically. If this process crashes we don't want to interfere with any
+  // other concurrent processes.
+  SmallString<128> TempPath(State.RecordPath);
+  TempPath += "-temp-%%%%%%%%";
+  int TempFD;
+  if (sys::fs::createUniqueFile(TempPath.str(), TempFD, TempPath)) {
+    llvm::raw_string_ostream Err(Error);
+    Err << "failed to create temporary file: " << TempPath;
+    return Result::Failure;
+  }
+
+  raw_fd_ostream OS(TempFD, /*shouldClose=*/true);
+  OS.write(State.Buffer.data(), State.Buffer.size());
+  OS.close();
+
+  // Atomically move the unique file into place.
+  if (std::error_code EC =
+          sys::fs::rename(TempPath.c_str(), State.RecordPath.c_str())) {
+    llvm::raw_string_ostream Err(Error);
+    Err << "failed to rename '" << TempPath << "' to '" << State.RecordPath << "': " << EC.message();
+    return Result::Failure;
+  }
+
+  return Result::Success;
+}
+
+void IndexRecordWriter::addOccurrence(
+    OpaqueDecl D, SymbolRoleSet Roles, unsigned Line, unsigned Column,
+    ArrayRef<writer::SymbolRelation> Related) {
+  assert(Record && "called addOccurrence without calling beginRecord");
+  auto &State = *static_cast<RecordState *>(Record);
+
+  auto insertDecl = [&](OpaqueDecl D, SymbolRoleSet Roles,
+                        SymbolRoleSet RelatedRoles) -> unsigned {
+    auto Insert =
+        State.IndexForDecl.insert(std::make_pair(D, State.Decls.size()));
+    unsigned Index = Insert.first->second;
+
+    if (Insert.second) {
+      State.Decls.push_back(DeclInfo{D, Roles, RelatedRoles});
+    } else {
+      State.Decls[Index].Roles |= Roles;
+      State.Decls[Index].RelatedRoles |= RelatedRoles;
+    }
+    return Index + 1;
+  };
+
+  unsigned DeclID = insertDecl(D, Roles, SymbolRoleSet());
+
+  decltype(OccurrenceInfo::Related) RelatedDecls;
+  RelatedDecls.reserve(Related.size());
+  for (auto &Rel : Related) {
+    unsigned ID = insertDecl(Rel.RelatedSymbol, SymbolRoleSet(), Rel.Roles);
+    RelatedDecls.emplace_back(Rel, ID);
+  }
+
+  State.Occurrences.push_back(
+      OccurrenceInfo{DeclID, D, Roles, Line, Column, std::move(RelatedDecls)});
+}
diff --git a/lib/Index/IndexSymbol.cpp b/lib/Index/IndexSymbol.cpp
index 0dc3720..1f8410d 100644
--- a/lib/Index/IndexSymbol.cpp
+++ b/lib/Index/IndexSymbol.cpp
@@ -201,25 +201,22 @@
         Info.Properties |= (unsigned)SymbolProperty::UnitTest;
       break;
     }
-    case Decl::ObjCMethod:
-      if (cast<ObjCMethodDecl>(D)->isInstanceMethod()) {
-        const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
-        Info.Kind = SymbolKind::InstanceMethod;
-        if (MD->isPropertyAccessor()) {
-          if (MD->param_size())
-            Info.SubKind = SymbolSubKind::AccessorSetter;
-          else
-            Info.SubKind = SymbolSubKind::AccessorGetter;
-        }
-      } else {
-        Info.Kind = SymbolKind::ClassMethod;
+    case Decl::ObjCMethod: {
+      const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(D);
+      Info.Kind = MD->isInstanceMethod() ? SymbolKind::InstanceMethod : SymbolKind::ClassMethod;
+      if (MD->isPropertyAccessor()) {
+        if (MD->param_size())
+          Info.SubKind = SymbolSubKind::AccessorSetter;
+        else
+          Info.SubKind = SymbolSubKind::AccessorGetter;
       }
       Info.Lang = SymbolLanguage::ObjC;
-      if (isUnitTest(cast<ObjCMethodDecl>(D)))
+      if (isUnitTest(MD))
         Info.Properties |= (unsigned)SymbolProperty::UnitTest;
       if (D->hasAttr<IBActionAttr>())
         Info.Properties |= (unsigned)SymbolProperty::IBAnnotated;
       break;
+    }
     case Decl::ObjCProperty:
       Info.Kind = SymbolKind::InstanceProperty;
       Info.Lang = SymbolLanguage::ObjC;
@@ -303,6 +300,18 @@
       Info.Kind = SymbolKind::TypeAlias;
       Info.Lang = SymbolLanguage::CXX;
       break;
+    case Decl::UnresolvedUsingTypename:
+      Info.Kind = SymbolKind::Using;
+      Info.SubKind = SymbolSubKind::UsingTypename;
+      Info.Lang = SymbolLanguage::CXX;
+      Info.Properties |= (unsigned)SymbolProperty::Generic;
+      break;
+    case Decl::UnresolvedUsingValue:
+      Info.Kind = SymbolKind::Using;
+      Info.SubKind = SymbolSubKind::UsingValue;
+      Info.Lang = SymbolLanguage::CXX;
+      Info.Properties |= (unsigned)SymbolProperty::Generic;
+      break;
     case Decl::Binding:
       Info.Kind = SymbolKind::Variable;
       Info.Lang = SymbolLanguage::CXX;
@@ -451,6 +460,8 @@
   case SymbolKind::Destructor: return "destructor";
   case SymbolKind::ConversionFunction: return "coversion-func";
   case SymbolKind::Parameter: return "param";
+  case SymbolKind::Using: return "using";
+  case SymbolKind::CommentTag: return "comment-tag";
   }
   llvm_unreachable("invalid symbol kind");
 }
@@ -462,6 +473,22 @@
   case SymbolSubKind::CXXMoveConstructor: return "cxx-move-ctor";
   case SymbolSubKind::AccessorGetter: return "acc-get";
   case SymbolSubKind::AccessorSetter: return "acc-set";
+  case SymbolSubKind::UsingTypename: return "using-typename";
+  case SymbolSubKind::UsingValue: return "using-value";
+  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");
 }
diff --git a/lib/Index/IndexTypeSourceInfo.cpp b/lib/Index/IndexTypeSourceInfo.cpp
index ae27ebe..c8ff3d7 100644
--- a/lib/Index/IndexTypeSourceInfo.cpp
+++ b/lib/Index/IndexTypeSourceInfo.cpp
@@ -126,8 +126,9 @@
     return true;
   }
 
-  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
-    if (const TemplateSpecializationType *T = TL.getTypePtr()) {
+  template<typename TypeLocType>
+  bool HandleTemplateSpecializationTypeLoc(TypeLocType TL) {
+    if (const auto *T = TL.getTypePtr()) {
       if (IndexCtx.shouldIndexImplicitTemplateInsts()) {
         if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
           IndexCtx.handleReference(RD, TL.getTemplateNameLoc(),
@@ -141,6 +142,14 @@
     return true;
   }
 
+  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
+    return HandleTemplateSpecializationTypeLoc(TL);
+  }
+
+  bool VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL) {
+    return HandleTemplateSpecializationTypeLoc(TL);
+  }
+
   bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
     const DependentNameType *DNT = TL.getTypePtr();
     const NestedNameSpecifier *NNS = DNT->getQualifier();
diff --git a/lib/Index/IndexUnitReader.cpp b/lib/Index/IndexUnitReader.cpp
new file mode 100644
index 0000000..12a9056
--- /dev/null
+++ b/lib/Index/IndexUnitReader.cpp
@@ -0,0 +1,516 @@
+//===--- IndexUnitReader.cpp - Index unit deserialization -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/IndexUnitReader.h"
+#include "IndexDataStoreUtils.h"
+#include "BitstreamVisitor.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/Chrono.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <unistd.h>
+
+using namespace clang;
+using namespace clang::index;
+using namespace clang::index::store;
+using namespace llvm;
+
+namespace {
+
+typedef function_ref<bool(const IndexUnitReader::DependencyInfo &)> DependencyReceiver;
+typedef function_ref<bool(const IndexUnitReader::IncludeInfo &)> IncludeReceiver;
+
+class IndexUnitReaderImpl {
+  sys::TimePoint<> ModTime;
+  std::unique_ptr<MemoryBuffer> MemBuf;
+
+public:
+  StringRef ProviderIdentifier;
+  StringRef ProviderVersion;
+  llvm::BitstreamCursor DependCursor;
+  llvm::BitstreamCursor IncludeCursor;
+  bool IsSystemUnit;
+  bool IsModuleUnit;
+  bool IsDebugCompilation;
+  StringRef WorkingDir;
+  StringRef OutputFile;
+  StringRef SysrootPath;
+  StringRef ModuleName;
+  SmallString<128> MainFilePath;
+  StringRef Target;
+  std::vector<FileBitPath> Paths;
+  StringRef PathsBuffer;
+
+  struct ModuleInfo {
+    unsigned NameOffset;
+    unsigned NameSize;
+  };
+  std::vector<ModuleInfo> Modules;
+  StringRef ModuleNamesBuffer;
+
+  bool init(std::unique_ptr<MemoryBuffer> Buf, sys::TimePoint<> ModTime,
+            std::string &Error);
+
+  StringRef getProviderIdentifier() const { return ProviderIdentifier; }
+  StringRef getProviderVersion() const { return ProviderVersion; }
+
+  sys::TimePoint<> getModificationTime() const { return ModTime; }
+  StringRef getWorkingDirectory() const { return WorkingDir; }
+  StringRef getOutputFile() const { return OutputFile; }
+  StringRef getSysrootPath() const { return SysrootPath; }
+  StringRef getTarget() const { return Target; }
+
+  StringRef getModuleName() const { return ModuleName; }
+  StringRef getMainFilePath() const { return MainFilePath.str(); }
+  bool hasMainFile() const { return !MainFilePath.empty(); }
+  bool isSystemUnit() const { return IsSystemUnit; }
+  bool isModuleUnit() const { return IsModuleUnit; }
+  bool isDebugCompilation() const { return IsDebugCompilation; }
+
+  /// Unit dependencies are provided ahead of record ones, record ones
+  /// ahead of the file ones.
+  bool foreachDependency(DependencyReceiver Receiver);
+
+  bool foreachInclude(IncludeReceiver Receiver);
+
+  StringRef getPathFromBuffer(size_t Offset, size_t Size) {
+    return PathsBuffer.substr(Offset, Size);
+  }
+
+  void constructFilePath(SmallVectorImpl<char> &Path, int PathIndex);
+
+  StringRef getModuleName(int ModuleIndex);
+};
+
+class IndexUnitBitstreamVisitor : public BitstreamVisitor<IndexUnitBitstreamVisitor> {
+  IndexUnitReaderImpl &Reader;
+  size_t WorkDirOffset;
+  size_t WorkDirSize;
+  size_t OutputFileOffset;
+  size_t OutputFileSize;
+  size_t SysrootOffset;
+  size_t SysrootSize;
+  int MainPathIndex;
+
+public:
+  IndexUnitBitstreamVisitor(llvm::BitstreamCursor &Stream,
+                            IndexUnitReaderImpl &Reader)
+    : BitstreamVisitor(Stream), Reader(Reader) {}
+
+  StreamVisit visitBlock(unsigned ID) {
+    switch ((UnitBitBlock)ID) {
+    case UNIT_VERSION_BLOCK_ID:
+    case UNIT_INFO_BLOCK_ID:
+    case UNIT_PATHS_BLOCK_ID:
+    case UNIT_MODULES_BLOCK_ID:
+      return StreamVisit::Continue;
+
+    case UNIT_DEPENDENCIES_BLOCK_ID:
+      Reader.DependCursor = Stream;
+      if (Reader.DependCursor.EnterSubBlock(ID)) {
+        *Error = "malformed unit dependencies block record";
+        return StreamVisit::Abort;
+      }
+      readBlockAbbrevs(Reader.DependCursor);
+      return StreamVisit::Skip;
+    case UNIT_INCLUDES_BLOCK_ID:
+      Reader.IncludeCursor = Stream;
+      if (Reader.IncludeCursor.EnterSubBlock(ID)) {
+        *Error = "malformed unit includes block record";
+        return StreamVisit::Abort;
+      }
+      readBlockAbbrevs(Reader.IncludeCursor);
+      return StreamVisit::Skip;
+    }
+
+    // Some newly introduced block in a minor version update that we cannot
+    // handle.
+    return StreamVisit::Skip;
+  }
+
+  StreamVisit visitRecord(unsigned BlockID, unsigned RecID,
+                          RecordDataImpl &Record, StringRef Blob) {
+    switch (BlockID) {
+    case UNIT_VERSION_BLOCK_ID: {
+      unsigned StoreFormatVersion = Record[0];
+      if (StoreFormatVersion != STORE_FORMAT_VERSION) {
+        llvm::raw_string_ostream OS(*Error);
+        OS << "Store format version mismatch: " << StoreFormatVersion;
+        OS << " , expected: " << STORE_FORMAT_VERSION;
+        return StreamVisit::Abort;
+      }
+      break;
+    }
+
+    case UNIT_INFO_BLOCK_ID: {
+      assert(RecID == UNIT_INFO);
+      unsigned I = 0;
+      Reader.IsSystemUnit = Record[I++];
+
+      // Save these to lookup them up after we get the paths buffer.
+      WorkDirOffset = Record[I++];
+      WorkDirSize = Record[I++];
+      OutputFileOffset = Record[I++];
+      OutputFileSize = Record[I++];
+      SysrootOffset = Record[I++];
+      SysrootSize = Record[I++];
+      MainPathIndex = (int)Record[I++] - 1;
+      Reader.IsDebugCompilation = Record[I++];
+      Reader.IsModuleUnit = Record[I++];
+
+      size_t moduleNameSize = Record[I++];
+      size_t providerIdentifierSize = Record[I++];
+      size_t providerVersionSize = Record[I++];
+      I++; // Reserved for ProviderDataVersion.
+      Reader.ModuleName = Blob.substr(0, moduleNameSize);
+      Blob = Blob.drop_front(moduleNameSize);
+      Reader.ProviderIdentifier = Blob.substr(0, providerIdentifierSize);
+      Blob = Blob.drop_front(providerIdentifierSize);
+      Reader.ProviderVersion = Blob.substr(0, providerVersionSize);
+      Reader.Target = Blob.drop_front(providerVersionSize);
+      break;
+    }
+
+    case UNIT_PATHS_BLOCK_ID:
+      switch (RecID) {
+      case UNIT_PATH:
+        {
+          unsigned I = 0;
+          UnitFilePathPrefixKind Kind = (UnitFilePathPrefixKind)Record[I++];
+          size_t DirOffset = Record[I++];
+          size_t DirSize = Record[I++];
+          size_t FilenameOffset = Record[I++];
+          size_t FilenameSize = Record[I++];
+
+          Reader.Paths.emplace_back(Kind, BitPathComponent(DirOffset, DirSize),
+                                  BitPathComponent(FilenameOffset, FilenameSize));
+        }
+        break;
+      case UNIT_PATH_BUFFER:
+        Reader.PathsBuffer = Blob;
+        Reader.WorkingDir = Reader.getPathFromBuffer(WorkDirOffset, WorkDirSize);
+        Reader.OutputFile = Reader.getPathFromBuffer(OutputFileOffset, OutputFileSize);
+        Reader.SysrootPath = Reader.getPathFromBuffer(SysrootOffset, SysrootSize);
+
+        // now we can populate the main file's path
+        Reader.constructFilePath(Reader.MainFilePath, MainPathIndex);
+        break;
+      default:
+          llvm_unreachable("shouldn't visit this record");
+      }
+      break;
+
+    case UNIT_MODULES_BLOCK_ID:
+      switch (RecID) {
+      case UNIT_MODULE:
+        {
+          unsigned I = 0;
+          unsigned NameOffset = Record[I++];
+          unsigned NameSize = Record[I++];
+          Reader.Modules.push_back({NameOffset, NameSize});
+        }
+        break;
+      case UNIT_MODULE_BUFFER:
+        Reader.ModuleNamesBuffer = Blob;
+        break;
+      default:
+          llvm_unreachable("shouldn't visit this record");
+      }
+      break;
+
+    case UNIT_DEPENDENCIES_BLOCK_ID:
+    case UNIT_INCLUDES_BLOCK_ID:
+      llvm_unreachable("shouldn't visit this block'");
+    }
+    return StreamVisit::Continue;
+  }
+};
+
+typedef std::function<bool(RecordDataImpl& Record, StringRef Blob)>
+  BlockVisitorCallback;
+
+class IndexUnitBlockBitstreamVisitor : public BitstreamVisitor<IndexUnitBlockBitstreamVisitor> {
+  unsigned RecID;
+  BlockVisitorCallback Visit;
+
+public:
+  IndexUnitBlockBitstreamVisitor(unsigned RecID,
+                                 llvm::BitstreamCursor &BlockStream,
+                                 BlockVisitorCallback Visit)
+  : BitstreamVisitor(BlockStream), RecID(RecID), Visit(std::move(Visit)) {}
+
+  StreamVisit visitRecord(unsigned BlockID, unsigned RecID,
+                          RecordDataImpl &Record, StringRef Blob) {
+    if (RecID != this->RecID)
+      llvm_unreachable("shouldn't be called with this RecID");
+
+    if (Visit(Record, Blob))
+      return StreamVisit::Continue;
+    return StreamVisit::Abort;
+  }
+};
+
+} // anonymous namespace
+
+bool IndexUnitReaderImpl::init(std::unique_ptr<MemoryBuffer> Buf,
+                               sys::TimePoint<> ModTime, std::string &Error) {
+  this->ModTime = ModTime;
+  this->MemBuf = std::move(Buf);
+  llvm::BitstreamCursor Stream(*MemBuf);
+
+  // Sniff for the signature.
+  if (Stream.Read(8) != 'I' ||
+      Stream.Read(8) != 'D' ||
+      Stream.Read(8) != 'X' ||
+      Stream.Read(8) != 'U') {
+    Error = "not a serialized index unit file";
+    return true;
+  }
+
+  IndexUnitBitstreamVisitor BitVisitor(Stream, *this);
+  return !BitVisitor.visit(Error);
+}
+
+/// Unit dependencies are provided ahead of record ones, record ones
+/// ahead of the file ones.
+bool IndexUnitReaderImpl::foreachDependency(DependencyReceiver Receiver) {
+  store::SavedStreamPosition SavedDepPosition(DependCursor);
+  IndexUnitBlockBitstreamVisitor Visitor(UNIT_DEPENDENCY, DependCursor,
+  [&](RecordDataImpl& Record, StringRef Blob) {
+    unsigned I = 0;
+    UnitDependencyKind UnitDepKind = (UnitDependencyKind)Record[I++];
+    bool IsSystem = Record[I++];
+    int PathIndex = (int)Record[I++] - 1;
+    int ModuleIndex = (int)Record[I++] - 1;
+    time_t ModTime = (time_t)Record[I++];
+    size_t FileSize = Record[I++];
+    StringRef Name = Blob;
+
+    IndexUnitReader::DependencyKind DepKind;
+    switch (UnitDepKind) {
+      case UNIT_DEPEND_KIND_UNIT:
+        DepKind = IndexUnitReader::DependencyKind::Unit; break;
+      case UNIT_DEPEND_KIND_RECORD:
+        DepKind = IndexUnitReader::DependencyKind::Record; break;
+      case UNIT_DEPEND_KIND_FILE:
+        DepKind = IndexUnitReader::DependencyKind::File; break;
+    }
+
+    SmallString<512> PathBuf;
+    this->constructFilePath(PathBuf, PathIndex);
+    StringRef ModuleName = this->getModuleName(ModuleIndex);
+
+    return Receiver(IndexUnitReader::DependencyInfo{DepKind, IsSystem, Name,
+      PathBuf.str(), ModuleName, FileSize, ModTime});
+  });
+
+  std::string Error;
+  return Visitor.visit(Error);
+}
+
+bool IndexUnitReaderImpl::foreachInclude(IncludeReceiver Receiver) {
+  store::SavedStreamPosition SavedIncPosition(IncludeCursor);
+  IndexUnitBlockBitstreamVisitor Visitor(UNIT_INCLUDE, IncludeCursor,
+  [&](RecordDataImpl& Record, StringRef Blob) {
+    unsigned I = 0;
+    int SourcePathIndex = (int)Record[I++] - 1;
+    unsigned Line = Record[I++];
+    int TargetPathIndex = (int)Record[I++] - 1;
+
+    SmallString<512> SourceBuf, TargetBuf;
+    this->constructFilePath(SourceBuf, SourcePathIndex);
+    this->constructFilePath(TargetBuf, TargetPathIndex);
+    return Receiver(IndexUnitReader::IncludeInfo{SourceBuf.str(), Line, TargetBuf.str()});
+  });
+
+  std::string Error;
+  return Visitor.visit(Error);
+}
+
+
+void IndexUnitReaderImpl::constructFilePath(SmallVectorImpl<char> &PathBuf,
+                       int PathIndex) {
+
+  if (PathIndex < 0) return;
+  FileBitPath &Path = Paths[PathIndex];
+  StringRef Prefix;
+  switch (Path.PrefixKind) {
+  case UNIT_PATH_PREFIX_NONE:
+    break;
+  case UNIT_PATH_PREFIX_WORKDIR:
+    Prefix = getWorkingDirectory();
+    break;
+  case UNIT_PATH_PREFIX_SYSROOT:
+    Prefix = getSysrootPath();
+    break;
+  }
+  PathBuf.append(Prefix.begin(), Prefix.end());
+  sys::path::append(PathBuf,
+                    getPathFromBuffer(Path.Dir.Offset, Path.Dir.Size),
+                    getPathFromBuffer(Path.Filename.Offset, Path.Filename.Size));
+}
+
+StringRef IndexUnitReaderImpl::getModuleName(int ModuleIndex) {
+  if (ModuleIndex < 0)
+    return StringRef();
+  auto &ModInfo = Modules[ModuleIndex];
+  return StringRef(ModuleNamesBuffer.data()+ModInfo.NameOffset, ModInfo.NameSize);
+}
+
+
+//===----------------------------------------------------------------------===//
+// IndexUnitReader
+//===----------------------------------------------------------------------===//
+
+std::unique_ptr<IndexUnitReader>
+IndexUnitReader::createWithUnitFilename(StringRef UnitFilename,
+                                        StringRef StorePath,
+                                        std::string &Error) {
+  SmallString<128> PathBuf = StorePath;
+  appendUnitSubDir(PathBuf);
+  sys::path::append(PathBuf, UnitFilename);
+  return createWithFilePath(PathBuf.str(), Error);
+}
+
+std::unique_ptr<IndexUnitReader>
+IndexUnitReader::createWithFilePath(StringRef FilePath, std::string &Error) {
+  int FD;
+  std::error_code EC = sys::fs::openFileForRead(FilePath, FD);
+  if (EC) {
+    raw_string_ostream(Error) << "Failed opening '" << FilePath << "': "
+      << EC.message();
+    return nullptr;
+  }
+
+  assert(FD != -1);
+  struct AutoFDClose {
+    int FD;
+    AutoFDClose(int FD) : FD(FD) {}
+    ~AutoFDClose() {
+      ::close(FD);
+    }
+  } AutoFDClose(FD);
+
+  sys::fs::file_status FileStat;
+  EC = sys::fs::status(FD, FileStat);
+  if (EC) {
+    Error = EC.message();
+    return nullptr;
+  }
+
+  auto ErrOrBuf = MemoryBuffer::getOpenFile(FD, FilePath, /*FileSize=*/-1,
+                                            /*RequiresNullTerminator=*/false);
+  if (!ErrOrBuf) {
+    raw_string_ostream(Error) << "Failed opening '" << FilePath << "': "
+      << ErrOrBuf.getError().message();
+    return nullptr;
+  }
+
+  std::unique_ptr<IndexUnitReaderImpl> Impl(new IndexUnitReaderImpl());
+  bool Err = Impl->init(std::move(*ErrOrBuf), FileStat.getLastModificationTime(),
+                        Error);
+  if (Err)
+    return nullptr;
+
+  std::unique_ptr<IndexUnitReader> Reader;
+  Reader.reset(new IndexUnitReader(Impl.release()));
+  return Reader;
+}
+
+Optional<sys::TimePoint<>>
+IndexUnitReader::getModificationTimeForUnit(StringRef UnitFilename,
+                                            StringRef StorePath,
+                                            std::string &Error) {
+  SmallString<128> PathBuf = StorePath;
+  appendUnitSubDir(PathBuf);
+  sys::path::append(PathBuf, UnitFilename);
+
+  sys::fs::file_status FileStat;
+  std::error_code EC = sys::fs::status(PathBuf.str(), FileStat);
+  if (EC) {
+    Error = EC.message();
+    return None;
+  }
+  return FileStat.getLastModificationTime();
+}
+
+#define IMPL static_cast<IndexUnitReaderImpl*>(Impl)
+
+IndexUnitReader::~IndexUnitReader() {
+  delete IMPL;
+}
+
+StringRef IndexUnitReader::getProviderIdentifier() const {
+  return IMPL->getProviderIdentifier();
+}
+
+StringRef IndexUnitReader::getProviderVersion() const {
+  return IMPL->getProviderVersion();
+}
+
+llvm::sys::TimePoint<> IndexUnitReader::getModificationTime() const {
+  return IMPL->getModificationTime();
+}
+
+StringRef IndexUnitReader::getWorkingDirectory() const {
+  return IMPL->getWorkingDirectory();
+}
+
+StringRef IndexUnitReader::getOutputFile() const {
+  return IMPL->getOutputFile();
+}
+
+StringRef IndexUnitReader::getSysrootPath() const {
+  return IMPL->getSysrootPath();
+}
+
+StringRef IndexUnitReader::getMainFilePath() const {
+  return IMPL->getMainFilePath();
+}
+
+StringRef IndexUnitReader::getModuleName() const {
+  return IMPL->getModuleName();
+}
+
+StringRef IndexUnitReader::getTarget() const {
+  return IMPL->getTarget();
+}
+
+bool IndexUnitReader::hasMainFile() const {
+  return IMPL->hasMainFile();
+}
+
+bool IndexUnitReader::isSystemUnit() const {
+  return IMPL->isSystemUnit();
+}
+
+bool IndexUnitReader::isModuleUnit() const {
+  return IMPL->isModuleUnit();
+}
+
+bool IndexUnitReader::isDebugCompilation() const {
+  return IMPL->isDebugCompilation();
+}
+
+/// \c Index is the index in the \c getDependencies array.
+/// Unit dependencies are provided ahead of record ones.
+bool IndexUnitReader::foreachDependency(DependencyReceiver Receiver) {
+  return IMPL->foreachDependency(std::move(Receiver));
+}
+
+bool IndexUnitReader::foreachInclude(IncludeReceiver Receiver) {
+  return IMPL->foreachInclude(std::move(Receiver));
+}
diff --git a/lib/Index/IndexUnitWriter.cpp b/lib/Index/IndexUnitWriter.cpp
new file mode 100644
index 0000000..7c981ae
--- /dev/null
+++ b/lib/Index/IndexUnitWriter.cpp
@@ -0,0 +1,628 @@
+//===--- IndexUnitWriter.cpp - Index unit serialization -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/IndexUnitWriter.h"
+#include "IndexDataStoreUtils.h"
+#include "clang/Basic/FileManager.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Hashing.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Bitcode/BitstreamWriter.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::index;
+using namespace clang::index::store;
+using namespace llvm;
+
+
+class IndexUnitWriter::PathStorage {
+  std::string WorkDir;
+  std::string SysrootPath;
+  SmallString<512> PathsBuf;
+  StringMap<DirBitPath, BumpPtrAllocator> Dirs;
+  std::vector<FileBitPath> FileBitPaths;
+  DenseMap<const FileEntry *, size_t> FileToIndex;
+
+public:
+  PathStorage(StringRef workDir, StringRef sysrootPath) {
+    WorkDir = workDir;
+    if (sysrootPath == "/")
+      sysrootPath = StringRef();
+    SysrootPath = sysrootPath;
+  }
+
+  StringRef getPathsBuffer() const { return PathsBuf.str(); }
+
+  ArrayRef<FileBitPath> getBitPaths() const { return FileBitPaths; }
+
+  int getPathIndex(const FileEntry *FE) {
+    if (!FE)
+      return -1;
+    auto Pair = FileToIndex.insert(std::make_pair(FE, FileBitPaths.size()));
+    bool IsNew = Pair.second;
+    size_t Index = Pair.first->getSecond();
+
+    if (IsNew) {
+      StringRef Filename = sys::path::filename(FE->getName());
+      DirBitPath Dir = getDirBitPath(sys::path::parent_path(FE->getName()));
+      FileBitPaths.emplace_back(Dir.PrefixKind, Dir.Dir,
+                                BitPathComponent(getPathOffset(Filename),
+                                                 Filename.size()));
+    }
+    return Index;
+  }
+
+  size_t getPathOffset(StringRef Path) {
+    if (Path.empty())
+      return 0;
+    size_t offset = PathsBuf.size();
+    PathsBuf += Path;
+    return offset;
+  }
+  
+private:
+  DirBitPath getDirBitPath(StringRef dirStr) {
+    auto pair = Dirs.insert(std::make_pair(dirStr, DirBitPath()));
+    bool isNew = pair.second;
+    auto &dirPath = pair.first->second;
+
+    if (isNew) {
+      if (isPathInDir(SysrootPath, dirStr)) {
+        dirPath.PrefixKind = UNIT_PATH_PREFIX_SYSROOT;
+        dirStr = dirStr.drop_front(SysrootPath.size());
+        while (!dirStr.empty() && dirStr[0] == '/')
+          dirStr = dirStr.drop_front();
+      } else if (isPathInDir(WorkDir, dirStr)) {
+        dirPath.PrefixKind = UNIT_PATH_PREFIX_WORKDIR;
+        dirStr = dirStr.drop_front(WorkDir.size());
+        while (!dirStr.empty() && dirStr[0] == '/')
+          dirStr = dirStr.drop_front();
+      }
+      dirPath.Dir.Offset = getPathOffset(dirStr);
+      dirPath.Dir.Size = dirStr.size();
+    }
+    return dirPath;
+  }
+
+  static bool isPathInDir(StringRef dir, StringRef path) {
+    if (dir.empty() || !path.startswith(dir))
+      return false;
+    StringRef rest = path.drop_front(dir.size());
+    return !rest.empty() && sys::path::is_separator(rest.front());
+  }
+};
+
+IndexUnitWriter::IndexUnitWriter(FileManager &FileMgr,
+                                 StringRef StorePath,
+                                 StringRef ProviderIdentifier,
+                                 StringRef ProviderVersion,
+                                 StringRef OutputFile,
+                                 StringRef ModuleName,
+                                 const FileEntry *MainFile,
+                                 bool IsSystem,
+                                 bool IsModuleUnit,
+                                 bool IsDebugCompilation,
+                                 StringRef TargetTriple,
+                                 StringRef SysrootPath,
+                                 writer::ModuleInfoWriterCallback GetInfoForModule)
+: FileMgr(FileMgr) {
+  this->UnitsPath = StorePath;
+  store::appendUnitSubDir(this->UnitsPath);
+  this->ProviderIdentifier = ProviderIdentifier;
+  this->ProviderVersion = ProviderVersion;
+  this->OutputFile = OutputFile;
+  this->ModuleName = ModuleName;
+  this->MainFile = MainFile;
+  this->IsSystemUnit = IsSystem;
+  this->IsModuleUnit = IsModuleUnit;
+  this->IsDebugCompilation = IsDebugCompilation;
+  this->TargetTriple = TargetTriple;
+  this->SysrootPath = SysrootPath;
+  this->GetInfoForModuleFn = GetInfoForModule;
+}
+
+IndexUnitWriter::~IndexUnitWriter() {}
+
+int IndexUnitWriter::addModule(writer::OpaqueModule Mod) {
+  if (!Mod)
+    return -1;
+
+  auto Pair = IndexByModule.insert(std::make_pair(Mod, Modules.size()));
+  bool WasInserted = Pair.second;
+  if (WasInserted) {
+    Modules.push_back(Mod);
+  }
+  return Pair.first->second;
+}
+
+int IndexUnitWriter::addFileDependency(const FileEntry *File, bool IsSystem,
+                                       writer::OpaqueModule Mod) {
+  assert(File);
+  auto Pair = IndexByFile.insert(std::make_pair(File, Files.size()));
+  bool WasInserted = Pair.second;
+  if (WasInserted) {
+    Files.push_back(FileEntryData{File, IsSystem, addModule(Mod), {}});
+  }
+  return Pair.first->second;
+}
+
+void IndexUnitWriter::addRecordFile(StringRef RecordFile, const FileEntry *File,
+                                    bool IsSystem, writer::OpaqueModule Mod) {
+  int Dep = File ? addFileDependency(File, IsSystem, /*module=*/nullptr) : -1;
+  Records.push_back(RecordOrUnitData{RecordFile, Dep, addModule(Mod), IsSystem});
+}
+
+void IndexUnitWriter::addASTFileDependency(const FileEntry *File, bool IsSystem,
+                                           writer::OpaqueModule Mod,
+                                           bool withoutUnitName) {
+  assert(File);
+  if (!SeenASTFiles.insert(File).second)
+    return;
+
+  SmallString<64> UnitName;
+  if (!withoutUnitName)
+    getUnitNameForOutputFile(File->getName(), UnitName);
+  addUnitDependency(UnitName.str(), File, IsSystem, Mod);
+}
+
+void IndexUnitWriter::addUnitDependency(StringRef UnitFile,
+                                        const FileEntry *File, bool IsSystem,
+                                        writer::OpaqueModule Mod) {
+  int Dep = File ? addFileDependency(File, IsSystem, /*module=*/nullptr) : -1;
+  ASTFileUnits.emplace_back(RecordOrUnitData{UnitFile, Dep, addModule(Mod), IsSystem});
+}
+
+bool IndexUnitWriter::addInclude(const FileEntry *Source, unsigned Line,
+                                 const FileEntry *Target) {
+  // FIXME: This will ignore includes of headers that resolve to module imports
+  // because the 'target' header has not been added as a file dependency earlier
+  // so it is missing from \c IndexByFile.
+
+  auto It = IndexByFile.find(Source);
+  if (It == IndexByFile.end())
+    return false;
+  int SourceIndex = It->getSecond();
+  It = IndexByFile.find(Target);
+  if (It == IndexByFile.end())
+    return false;
+  int TargetIndex = It->getSecond();
+  Files[SourceIndex].Includes.emplace_back(FileInclude{TargetIndex, Line});
+  return true;
+};
+
+void IndexUnitWriter::getUnitNameForOutputFile(StringRef FilePath,
+                                               SmallVectorImpl<char> &Str) {
+  SmallString<256> AbsPath(FilePath);
+  FileMgr.makeAbsolutePath(AbsPath);
+  return getUnitNameForAbsoluteOutputFile(AbsPath, Str);
+}
+
+void IndexUnitWriter::getUnitPathForOutputFile(StringRef FilePath,
+                                               SmallVectorImpl<char> &Str) {
+  Str.append(UnitsPath.begin(), UnitsPath.end());
+  Str.push_back('/');
+  return getUnitNameForOutputFile(FilePath, Str);
+}
+
+Optional<bool> IndexUnitWriter::isUnitUpToDateForOutputFile(StringRef FilePath,
+                                                            Optional<StringRef> TimeCompareFilePath,
+                                                            std::string &Error) {
+  SmallString<256> UnitPath;
+  getUnitPathForOutputFile(FilePath, UnitPath);
+
+  llvm::sys::fs::file_status UnitStat;
+  if (std::error_code EC = llvm::sys::fs::status(UnitPath.c_str(), UnitStat)) {
+    if (EC != llvm::errc::no_such_file_or_directory) {
+      llvm::raw_string_ostream Err(Error);
+      Err << "could not access path '" << UnitPath
+          << "': " << EC.message();
+      return None;
+    }
+    return false;
+  }
+
+  if (!TimeCompareFilePath.hasValue())
+    return true;
+
+  llvm::sys::fs::file_status CompareStat;
+  if (std::error_code EC = llvm::sys::fs::status(*TimeCompareFilePath, CompareStat)) {
+    if (EC != llvm::errc::no_such_file_or_directory) {
+      llvm::raw_string_ostream Err(Error);
+      Err << "could not access path '" << *TimeCompareFilePath
+          << "': " << EC.message();
+      return None;
+    }
+    return true;
+  }
+
+  // Return true (unit is up-to-date) if the file to compare is older than the
+  // unit file.
+  return CompareStat.getLastModificationTime() <= UnitStat.getLastModificationTime();
+}
+
+void IndexUnitWriter::getUnitNameForAbsoluteOutputFile(StringRef FilePath,
+                                                   SmallVectorImpl<char> &Str) {
+  StringRef Fname = sys::path::filename(FilePath);
+  Str.append(Fname.begin(), Fname.end());
+  Str.push_back('-');
+  llvm::hash_code PathHashVal = llvm::hash_value(FilePath);
+  llvm::APInt(64, PathHashVal).toString(Str, 36, /*Signed=*/false);
+}
+
+static void writeBlockInfo(BitstreamWriter &Stream) {
+  RecordData Record;
+
+  Stream.EnterBlockInfoBlock();
+#define BLOCK(X) emitBlockID(X ## _ID, #X, Stream, Record)
+#define RECORD(X) emitRecordID(X, #X, Stream, Record)
+
+  BLOCK(UNIT_VERSION_BLOCK);
+  RECORD(UNIT_VERSION);
+
+  BLOCK(UNIT_INFO_BLOCK);
+  RECORD(UNIT_INFO);
+
+  BLOCK(UNIT_DEPENDENCIES_BLOCK);
+  RECORD(UNIT_DEPENDENCY);
+
+  BLOCK(UNIT_INCLUDES_BLOCK);
+  RECORD(UNIT_INCLUDE);
+
+  BLOCK(UNIT_PATHS_BLOCK);
+  RECORD(UNIT_PATH);
+  RECORD(UNIT_PATH_BUFFER);
+
+  BLOCK(UNIT_MODULES_BLOCK);
+  RECORD(UNIT_MODULE);
+  RECORD(UNIT_MODULE_BUFFER);
+
+#undef RECORD
+#undef BLOCK
+  Stream.ExitBlock();
+}
+
+static void writeVersionInfo(BitstreamWriter &Stream) {
+  using namespace llvm::sys;
+
+  Stream.EnterSubblock(UNIT_VERSION_BLOCK_ID, 3);
+
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(UNIT_VERSION));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Store format version
+  unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+  RecordData Record;
+  Record.push_back(UNIT_VERSION);
+  Record.push_back(STORE_FORMAT_VERSION);
+  Stream.EmitRecordWithAbbrev(AbbrevCode, Record);
+
+  Stream.ExitBlock();
+}
+
+bool IndexUnitWriter::write(std::string &Error) {
+  using namespace llvm::sys;
+
+  // Determine the working directory.
+  SmallString<128> CWDPath;
+  if (!FileMgr.getFileSystemOpts().WorkingDir.empty()) {
+    CWDPath = FileMgr.getFileSystemOpts().WorkingDir;
+    if (!path::is_absolute(CWDPath)) {
+      fs::make_absolute(CWDPath);
+    }
+  } else {
+    std::error_code EC = sys::fs::current_path(CWDPath);
+    if (EC) {
+      llvm::raw_string_ostream Err(Error);
+      Err << "failed to determine current working directory: " << EC.message();
+      return true;
+    }
+  }
+  WorkDir = CWDPath.str();
+
+  SmallString<512> Buffer;
+  BitstreamWriter Stream(Buffer);
+  Stream.Emit('I', 8);
+  Stream.Emit('D', 8);
+  Stream.Emit('X', 8);
+  Stream.Emit('U', 8);
+
+  PathStorage PathStore(WorkDir, SysrootPath);
+
+  writeBlockInfo(Stream);
+  writeVersionInfo(Stream);
+  writeUnitInfo(Stream, PathStore);
+  writeDependencies(Stream, PathStore);
+  writeIncludes(Stream, PathStore);
+  writePaths(Stream, PathStore);
+  writeModules(Stream);
+
+  SmallString<256> UnitPath;
+  getUnitPathForOutputFile(OutputFile, UnitPath);
+
+  SmallString<128> TempPath;
+  TempPath = path::parent_path(UnitsPath);
+  TempPath += '/';
+  TempPath += path::filename(UnitPath);
+  TempPath += "-%%%%%%%%";
+  int TempFD;
+  if (llvm::sys::fs::createUniqueFile(TempPath.str(), TempFD, TempPath)) {
+    llvm::raw_string_ostream Err(Error);
+    Err << "failed to create temporary file: " << TempPath;
+    return true;
+  }
+
+  raw_fd_ostream OS(TempFD, /*shouldClose=*/true);
+  OS.write(Buffer.data(), Buffer.size());
+  OS.close();
+
+  std::error_code EC = fs::rename(/*from=*/TempPath.c_str(), /*to=*/UnitPath.c_str());
+  if (EC) {
+    llvm::raw_string_ostream Err(Error);
+    Err << "failed to rename '" << TempPath << "' to '" << UnitPath << "': " << EC.message();
+    return true;
+  }
+
+  return false;
+}
+
+void IndexUnitWriter::writeUnitInfo(llvm::BitstreamWriter &Stream,
+                                    PathStorage &PathStore) {
+  Stream.EnterSubblock(UNIT_INFO_BLOCK_ID, 3);
+
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(UNIT_INFO));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystemUnit
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 10)); // WorkDir offset
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // WorkDir size
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 10)); // OutputFile offset
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // OutputFile size
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 10)); // Sysroot offset
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // Sysroot size
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 10)); // Main path id
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsDebugCompilation
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsModuleUnit
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 5)); // Module name size
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 5)); // ProviderIdentifier size
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 5)); // ProviderVersion size
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 5)); // ProviderDataVersion
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Module name + ProviderIdentifier + ProviderVersion + target triple
+  unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+  RecordData Record;
+  Record.push_back(UNIT_INFO);
+  Record.push_back(IsSystemUnit);
+  Record.push_back(PathStore.getPathOffset(WorkDir));
+  Record.push_back(WorkDir.size());
+  Record.push_back(PathStore.getPathOffset(OutputFile));
+  Record.push_back(OutputFile.size());
+  Record.push_back(PathStore.getPathOffset(SysrootPath));
+  Record.push_back(SysrootPath.size());
+  Record.push_back(PathStore.getPathIndex(MainFile) + 1); // Make 1-based with 0=invalid
+  Record.push_back(IsDebugCompilation);
+  Record.push_back(IsModuleUnit);
+  Record.push_back(ModuleName.size());
+  Record.push_back(ProviderIdentifier.size());
+  Record.push_back(ProviderVersion.size());
+  // ProviderDataVersion is reserved. Not sure it is a good to idea to have
+  // clients consider the specifics of a 'provider data version', but reserving
+  // to avoid store format version change in case there is a use case in the
+  // future.
+  Record.push_back(0); // ProviderDataVersion
+  SmallString<128> InfoStrings;
+  InfoStrings += ModuleName;
+  InfoStrings += ProviderIdentifier;
+  InfoStrings += ProviderVersion;
+  InfoStrings += TargetTriple;
+  Stream.EmitRecordWithBlob(AbbrevCode, Record, InfoStrings);
+
+  Stream.ExitBlock();
+}
+
+void IndexUnitWriter::writeDependencies(llvm::BitstreamWriter &Stream,
+                                        PathStorage &PathStore) {
+  std::vector<bool> FileUsedForRecordOrUnit;
+  FileUsedForRecordOrUnit.resize(Files.size());
+
+  Stream.EnterSubblock(UNIT_DEPENDENCIES_BLOCK_ID, 3);
+
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(UNIT_DEPENDENCY));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, UnitDependencyKindBitNum)); // Dependency kind
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // IsSystem
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 10)); // PathIndex (1-based, 0 = none)
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // ModuleIndex (1-based, 0 = none)
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 32)); // time_t
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 16)); // file size
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
+  unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+  RecordData Record;
+
+  auto addRecordOrUnitData = [&](UnitDependencyKind K, const RecordOrUnitData &Data) {
+    Record.push_back(UNIT_DEPENDENCY);
+    Record.push_back(K);
+    Record.push_back(Data.IsSystem);
+    if (Data.FileIndex != -1) {
+      Record.push_back(PathStore.getPathIndex(Files[Data.FileIndex].File) + 1);
+      FileUsedForRecordOrUnit[Data.FileIndex] = true;
+    } else {
+      Record.push_back(0);
+    }
+    if (Data.ModuleIndex != -1) {
+      Record.push_back(Data.ModuleIndex + 1);
+    } else {
+      Record.push_back(0);
+    }
+    if (Data.FileIndex != -1) {
+      Record.push_back(Files[Data.FileIndex].File->getModificationTime());
+      Record.push_back(Files[Data.FileIndex].File->getSize());
+    } else {
+      Record.push_back(0);
+      Record.push_back(0);
+    }
+    Stream.EmitRecordWithBlob(AbbrevCode, Record, Data.Name);
+  };
+
+  for (auto &ASTData : ASTFileUnits) {
+    Record.clear();
+    addRecordOrUnitData(UNIT_DEPEND_KIND_UNIT, ASTData);
+  }
+  for (auto &recordData : Records) {
+    Record.clear();
+    addRecordOrUnitData(UNIT_DEPEND_KIND_RECORD, recordData);
+  }
+  size_t FileIndex = 0;
+  for (auto &File : Files) {
+    if (FileUsedForRecordOrUnit[FileIndex++])
+      continue;
+    Record.clear();
+    Record.push_back(UNIT_DEPENDENCY);
+    Record.push_back(UNIT_DEPEND_KIND_FILE);
+    Record.push_back(File.IsSystem);
+    Record.push_back(PathStore.getPathIndex(File.File) + 1);
+    if (File.ModuleIndex != -1) {
+      Record.push_back(File.ModuleIndex + 1);
+    } else {
+      Record.push_back(0);
+    }
+    Record.push_back(File.File->getModificationTime());
+    Record.push_back(File.File->getSize());
+    Stream.EmitRecordWithBlob(AbbrevCode, Record, StringRef());
+  }
+
+  Stream.ExitBlock();
+}
+
+void IndexUnitWriter::writeIncludes(llvm::BitstreamWriter &Stream,
+                                    PathStorage &PathStore) {
+  Stream.EnterSubblock(UNIT_INCLUDES_BLOCK_ID, 3);
+
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(UNIT_INCLUDE));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 10)); // source path index (1-based, 0 = no path)
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 12)); // source include line
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 10)); // target path index (1-based, 0 = no path)
+  unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+  RecordData Record;
+
+  for (auto &Including : Files) {
+    for(auto &Included: Including.Includes) {
+      Record.clear();
+      Record.push_back(UNIT_INCLUDE);
+      Record.push_back(PathStore.getPathIndex(Including.File) + 1);
+      Record.push_back(Included.Line);
+      Record.push_back(PathStore.getPathIndex(Files[Included.Index].File) + 1);
+      Stream.EmitRecordWithAbbrev(AbbrevCode, Record);
+    }
+  }
+  Stream.ExitBlock();
+}
+
+void IndexUnitWriter::writePaths(llvm::BitstreamWriter &Stream,
+                                 PathStorage &PathStore) {
+  Stream.EnterSubblock(UNIT_PATHS_BLOCK_ID, 3);
+
+  auto PathAbbrev = std::make_shared<BitCodeAbbrev>();
+  PathAbbrev->Add(BitCodeAbbrevOp(UNIT_PATH));
+  PathAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, UnitFilePathPrefixKindBitNum)); // Path prefix kind
+  PathAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 10)); // DirPath offset
+  PathAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // DirPath size
+  PathAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 10)); // Filename offset
+  PathAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Filename size
+  unsigned PathAbbrevCode = Stream.EmitAbbrev(std::move(PathAbbrev));
+
+  auto PathBufferAbbrev = std::make_shared<BitCodeAbbrev>();
+  PathBufferAbbrev->Add(BitCodeAbbrevOp(UNIT_PATH_BUFFER));
+  PathBufferAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Paths buffer
+  unsigned PathBufferAbbrevCode = Stream.EmitAbbrev(PathBufferAbbrev);
+
+  RecordData Record;
+  for(auto &BitPath: PathStore.getBitPaths()) {
+    Record.push_back(UNIT_PATH);
+    Record.push_back(BitPath.PrefixKind);
+    Record.push_back(BitPath.Dir.Offset);
+    Record.push_back(BitPath.Dir.Size);
+    Record.push_back(BitPath.Filename.Offset);
+    Record.push_back(BitPath.Filename.Size);
+    Stream.EmitRecordWithAbbrev(PathAbbrevCode, Record);
+    Record.clear();
+  }
+
+  Record.push_back(UNIT_PATH_BUFFER);
+  Stream.EmitRecordWithBlob(PathBufferAbbrevCode, Record, PathStore.getPathsBuffer());
+
+  Stream.ExitBlock();
+}
+
+void IndexUnitWriter::writeModules(llvm::BitstreamWriter &Stream) {
+  Stream.EnterSubblock(UNIT_MODULES_BLOCK_ID, 3);
+
+  auto Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(UNIT_MODULE));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 9)); // Module name offset
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Module name size
+  unsigned AbbrevCode = Stream.EmitAbbrev(std::move(Abbrev));
+
+  auto BufferAbbrev = std::make_shared<BitCodeAbbrev>();
+  BufferAbbrev->Add(BitCodeAbbrevOp(UNIT_MODULE_BUFFER));
+  BufferAbbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Module names buffer
+  unsigned BufferAbbrevCode = Stream.EmitAbbrev(BufferAbbrev);
+
+  SmallString<512> ModuleNamesBuf;
+
+  RecordData Record;
+  for (auto &Mod : Modules) {
+    SmallString<64> ModuleName;
+    StringRef name = GetInfoForModuleFn(Mod, ModuleName).Name;
+    size_t offset = ModuleNamesBuf.size();
+    ModuleNamesBuf += name;
+
+    Record.push_back(UNIT_MODULE);
+    Record.push_back(offset);
+    Record.push_back(name.size());
+    Stream.EmitRecordWithAbbrev(AbbrevCode, Record);
+    Record.clear();
+  }
+
+  Record.push_back(UNIT_MODULE_BUFFER);
+  Stream.EmitRecordWithBlob(BufferAbbrevCode, Record, ModuleNamesBuf.str());
+
+  Stream.ExitBlock();
+}
+
+bool IndexUnitWriter::initIndexDirectory(StringRef StorePath,
+                                         std::string &Error) {
+  using namespace llvm::sys;
+  SmallString<128> SubPath = StorePath;
+  store::appendRecordSubDir(SubPath);
+  std::error_code EC = fs::create_directories(SubPath);
+  if (EC) {
+    llvm::raw_string_ostream Err(Error);
+    Err << "failed to create directory '" << SubPath << "': " << EC.message();
+    return true;
+  }
+
+  SubPath = StorePath;
+  store::appendUnitSubDir(SubPath);
+  EC = fs::create_directory(SubPath);
+  if (EC) {
+    llvm::raw_string_ostream Err(Error);
+    Err << "failed to create directory '" << SubPath << "': " << EC.message();
+    return true;
+  }
+
+  return false;
+}
diff --git a/lib/Index/IndexingAction.cpp b/lib/Index/IndexingAction.cpp
index 84d3120..14263b1 100644
--- a/lib/Index/IndexingAction.cpp
+++ b/lib/Index/IndexingAction.cpp
@@ -9,9 +9,16 @@
 
 #include "clang/Index/IndexingAction.h"
 #include "clang/Index/IndexDataConsumer.h"
+#include "FileIndexRecord.h"
 #include "IndexingContext.h"
+#include "ClangIndexRecordWriter.h"
+#include "IndexDataStoreUtils.h"
+#include "clang/Index/IndexUnitWriter.h"
+#include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/MultiplexConsumer.h"
+#include "clang/Frontend/Utils.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Serialization/ASTReader.h"
 
@@ -80,7 +87,8 @@
     : DataConsumer(std::move(dataConsumer)),
       IndexCtx(Opts, *DataConsumer) {}
 
-  std::unique_ptr<IndexASTConsumer> createIndexASTConsumer() {
+  std::unique_ptr<IndexASTConsumer> createIndexASTConsumer(CompilerInstance &CI) {
+    IndexCtx.setSysrootPath(CI.getHeaderSearchOpts().Sysroot);
     return llvm::make_unique<IndexASTConsumer>(IndexCtx);
   }
 
@@ -98,7 +106,7 @@
 protected:
   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                  StringRef InFile) override {
-    return createIndexASTConsumer();
+    return createIndexASTConsumer(CI);
   }
 
   void EndSourceFileAction() override {
@@ -108,7 +116,7 @@
 };
 
 class WrappingIndexAction : public WrapperFrontendAction, IndexActionBase {
-  bool IndexActionFailed = false;
+  bool CreatedASTConsumer = false;
 
 public:
   WrappingIndexAction(std::unique_ptr<FrontendAction> WrappedAction,
@@ -128,21 +136,20 @@
 void WrappingIndexAction::EndSourceFileAction() {
   // Invoke wrapped action's method.
   WrapperFrontendAction::EndSourceFileAction();
-  if (!IndexActionFailed)
+  if (CreatedASTConsumer)
     finish();
 }
 
 std::unique_ptr<ASTConsumer>
 WrappingIndexAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   auto OtherConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
-  if (!OtherConsumer) {
-    IndexActionFailed = true;
+  if (!OtherConsumer)
     return nullptr;
-  }
 
+  CreatedASTConsumer = true;
   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
   Consumers.push_back(std::move(OtherConsumer));
-  Consumers.push_back(createIndexASTConsumer());
+  Consumers.push_back(createIndexASTConsumer(CI));
   return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
 }
 
@@ -203,3 +210,628 @@
   }
   DataConsumer->finish();
 }
+
+//===----------------------------------------------------------------------===//
+// Index Data Recording
+//===----------------------------------------------------------------------===//
+
+namespace {
+
+class IndexDataRecorder : public IndexDataConsumer {
+  IndexingContext *IndexCtx = nullptr;
+  const Preprocessor *PP = nullptr;
+  typedef llvm::DenseMap<FileID, std::unique_ptr<FileIndexRecord>> RecordByFileTy;
+  RecordByFileTy RecordByFile;
+
+public:
+  void init(IndexingContext *idxCtx, const CompilerInstance &CI) {
+    IndexCtx = idxCtx;
+    PP = &CI.getPreprocessor();
+    initialize(CI.getASTContext());
+  }
+
+  RecordByFileTy::const_iterator record_begin() const { return RecordByFile.begin(); }
+  RecordByFileTy::const_iterator record_end() const { return RecordByFile.end(); }
+  bool record_empty() const { return RecordByFile.empty(); }
+
+private:
+  bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles,
+                           ArrayRef<SymbolRelation> Relations,
+                           FileID FID, unsigned Offset,
+                           ASTNodeInfo ASTNode) override {
+    // Ignore the predefines buffer.
+    if (FID == PP->getPredefinesFileID())
+      return true;
+
+    FileIndexRecord &Rec = getFileIndexRecord(FID);
+    Rec.addDeclOccurence(Roles, Offset, D, Relations);
+    return true;
+  }
+
+  FileIndexRecord &getFileIndexRecord(FileID FID) {
+    auto &Entry = RecordByFile[FID];
+    if (!Entry) {
+      Entry.reset(new FileIndexRecord(FID, IndexCtx->isSystemFile(FID)));
+    }
+    return *Entry;
+  }
+};
+
+struct IncludeLocation {
+  const FileEntry *Source;
+  const FileEntry *Target;
+  unsigned Line;
+};
+
+class IncludePPCallbacks : public PPCallbacks {
+  IndexingContext &IndexCtx;
+  RecordingOptions RecordOpts;
+  std::vector<IncludeLocation> &Includes;
+  SourceManager &SourceMgr;
+
+public:
+  IncludePPCallbacks(IndexingContext &indexCtx, RecordingOptions recordOpts,
+                     std::vector<IncludeLocation> &IncludesForFile,
+                     SourceManager &SourceMgr) :
+    IndexCtx(indexCtx), RecordOpts(recordOpts),
+    Includes(IncludesForFile), SourceMgr(SourceMgr) {}
+
+private:
+  void addInclude(SourceLocation From, const FileEntry *To) {
+    assert(To);
+    if (RecordOpts.RecordIncludes == RecordingOptions::IncludesRecordingKind::None)
+      return;
+
+    std::pair<FileID, unsigned> LocInfo = SourceMgr.getDecomposedExpansionLoc(From);
+    switch (RecordOpts.RecordIncludes) {
+      case RecordingOptions::IncludesRecordingKind::None:
+        llvm_unreachable("should have already checked in the beginning");
+      case RecordingOptions::IncludesRecordingKind::UserOnly:
+        if (IndexCtx.isSystemFile(LocInfo.first))
+          return; // Ignore includes of system headers.
+        break;
+      case RecordingOptions::IncludesRecordingKind::All:
+        break;
+    }
+    auto *FE = SourceMgr.getFileEntryForID(LocInfo.first);
+    if (!FE)
+      return;
+    auto lineNo = SourceMgr.getLineNumber(LocInfo.first, LocInfo.second);
+    Includes.push_back({FE, To, lineNo});
+  }
+
+  virtual void InclusionDirective(SourceLocation HashLoc,
+                                  const Token &IncludeTok,
+                                  StringRef FileName,
+                                  bool IsAngled,
+                                  CharSourceRange FilenameRange,
+                                  const FileEntry *File,
+                                  StringRef SearchPath,
+                                  StringRef RelativePath,
+                                  const Module *Imported) override {
+    if (HashLoc.isFileID() && File && File->isValid())
+      addInclude(HashLoc, File);
+  }
+};
+
+class IndexDependencyProvider {
+public:
+  virtual ~IndexDependencyProvider() {}
+
+  virtual void visitFileDependencies(const CompilerInstance &CI,
+      llvm::function_ref<void(const FileEntry *FE, bool isSystem)> visitor) = 0;
+  virtual void visitIncludes(
+                 llvm::function_ref<void(const FileEntry *Source, unsigned Line,
+                                         const FileEntry *Target)> visitor) = 0;
+  virtual void visitModuleImports(const CompilerInstance &CI,
+                 llvm::function_ref<void(serialization::ModuleFile &Mod,
+                                         bool isSystem)> visitor) = 0;
+};
+
+class SourceFilesIndexDependencyCollector : public DependencyCollector, public IndexDependencyProvider {
+  IndexingContext &IndexCtx;
+  RecordingOptions RecordOpts;
+  llvm::SetVector<const FileEntry *> Entries;
+  llvm::BitVector IsSystemByUID;
+  std::vector<IncludeLocation> Includes;
+  SourceManager *SourceMgr = nullptr;
+  std::string SysrootPath;
+
+public:
+  SourceFilesIndexDependencyCollector(IndexingContext &indexCtx, RecordingOptions recordOpts)
+    : IndexCtx(indexCtx), RecordOpts(recordOpts) {}
+
+  virtual void attachToPreprocessor(Preprocessor &PP) override {
+    DependencyCollector::attachToPreprocessor(PP);
+    PP.addPPCallbacks(llvm::make_unique<IncludePPCallbacks>(IndexCtx,
+                                                            RecordOpts,
+                                                            Includes,
+                                                            PP.getSourceManager()));
+  }
+
+  void setSourceManager(SourceManager *SourceMgr) {
+    this->SourceMgr = SourceMgr;
+  }
+  void setSysrootPath(StringRef sysroot) { SysrootPath = sysroot; }
+
+  void visitFileDependencies(const CompilerInstance &CI,
+      llvm::function_ref<void(const FileEntry *FE, bool isSystem)> visitor) override {
+    for (auto *FE : getEntries()) {
+      visitor(FE, isSystemFile(FE));
+    }
+  }
+
+  void visitIncludes(
+                 llvm::function_ref<void(const FileEntry *Source, unsigned Line,
+                                         const FileEntry *Target)> visitor) override {
+    for (auto &Include : Includes) {
+      visitor(Include.Source, Include.Line, Include.Target);
+    }
+  }
+
+  void visitModuleImports(const CompilerInstance &CI,
+                 llvm::function_ref<void(serialization::ModuleFile &Mod,
+                                         bool isSystem)> visitor) override {
+    HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
+
+    if (auto Reader = CI.getModuleManager()) {
+      Reader->getModuleManager().visit([&](serialization::ModuleFile &Mod) -> bool {
+        bool isSystemMod = false;
+        if (Mod.isModule()) {
+          if (auto *M = HS.lookupModule(Mod.ModuleName, /*AllowSearch=*/false))
+            isSystemMod = M->IsSystem;
+        }
+        if (!isSystemMod || needSystemDependencies())
+          visitor(Mod, isSystemMod);
+        return true; // skip module dependencies.
+      });
+    }
+  }
+
+private:
+  bool isSystemFile(const FileEntry *FE) {
+    auto UID = FE->getUID();
+    return IsSystemByUID.size() > UID && IsSystemByUID[UID];
+  }
+
+  ArrayRef<const FileEntry *> getEntries() const {
+    return Entries.getArrayRef();
+  }
+
+  bool needSystemDependencies() override {
+    return RecordOpts.RecordSystemDependencies;
+  }
+
+  bool sawDependency(StringRef Filename, bool FromModule,
+                     bool IsSystem, bool IsModuleFile, bool IsMissing) override {
+    bool sawIt = DependencyCollector::sawDependency(Filename, FromModule,
+                                                    IsSystem, IsModuleFile,
+                                                    IsMissing);
+    if (auto *FE = SourceMgr->getFileManager().getFile(Filename)) {
+      if (sawIt)
+        Entries.insert(FE);
+      // Record system-ness for all files that we pass through.
+      if (IsSystemByUID.size() < FE->getUID()+1)
+        IsSystemByUID.resize(FE->getUID()+1);
+        IsSystemByUID[FE->getUID()] = IsSystem || isInSysroot(Filename);
+    }
+    return sawIt;
+  }
+
+  bool isInSysroot(StringRef Filename) {
+    return !SysrootPath.empty() && Filename.startswith(SysrootPath);
+  }
+};
+
+class IndexRecordActionBase {
+protected:
+  RecordingOptions RecordOpts;
+  IndexDataRecorder Recorder;
+  IndexingContext IndexCtx;
+  SourceFilesIndexDependencyCollector DepCollector;
+
+  IndexRecordActionBase(IndexingOptions IndexOpts, RecordingOptions recordOpts)
+    : RecordOpts(std::move(recordOpts)),
+      IndexCtx(IndexOpts, Recorder),
+      DepCollector(IndexCtx, RecordOpts) {
+  }
+
+  std::unique_ptr<IndexASTConsumer>
+  createIndexASTConsumer(CompilerInstance &CI) {
+    IndexCtx.setSysrootPath(CI.getHeaderSearchOpts().Sysroot);
+    Recorder.init(&IndexCtx, CI);
+
+    Preprocessor &PP = CI.getPreprocessor();
+    DepCollector.setSourceManager(&CI.getSourceManager());
+    DepCollector.setSysrootPath(IndexCtx.getSysrootPath());
+    DepCollector.attachToPreprocessor(PP);
+
+    return llvm::make_unique<IndexASTConsumer>(IndexCtx);
+  }
+
+  void finish(CompilerInstance &CI);
+};
+
+class IndexRecordAction : public ASTFrontendAction, IndexRecordActionBase {
+public:
+  IndexRecordAction(IndexingOptions IndexOpts, RecordingOptions RecordOpts)
+    : IndexRecordActionBase(std::move(IndexOpts), std::move(RecordOpts)) {}
+
+protected:
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 StringRef InFile) override {
+    return createIndexASTConsumer(CI);
+  }
+
+  void EndSourceFileAction() override {
+    FrontendAction::EndSourceFileAction();
+    finish(getCompilerInstance());
+  }
+};
+
+class WrappingIndexRecordAction : public WrapperFrontendAction, IndexRecordActionBase {
+  bool CreatedASTConsumer = false;
+
+public:
+  WrappingIndexRecordAction(std::unique_ptr<FrontendAction> WrappedAction,
+                            IndexingOptions IndexOpts,
+                            RecordingOptions RecordOpts)
+    : WrapperFrontendAction(std::move(WrappedAction)),
+      IndexRecordActionBase(std::move(IndexOpts), std::move(RecordOpts)) {}
+
+protected:
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 StringRef InFile) override {
+    auto OtherConsumer = WrapperFrontendAction::CreateASTConsumer(CI, InFile);
+    if (!OtherConsumer)
+      return nullptr;
+
+    CreatedASTConsumer = true;
+    std::vector<std::unique_ptr<ASTConsumer>> Consumers;
+    Consumers.push_back(std::move(OtherConsumer));
+    Consumers.push_back(createIndexASTConsumer(CI));
+    return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
+  }
+
+  void EndSourceFileAction() override {
+    // Invoke wrapped action's method.
+    WrapperFrontendAction::EndSourceFileAction();
+    if (CreatedASTConsumer)
+      finish(getCompilerInstance());
+  }
+};
+
+} // anonymous namespace
+
+static std::string getClangVersion() {
+  // Try picking the version from an Apple Clang tag.
+  std::string RepositoryPath = getClangRepositoryPath();
+  StringRef BuildNumber = StringRef(RepositoryPath);
+  size_t DashOffset = BuildNumber.find('-');
+  if (BuildNumber.startswith("clang") && DashOffset != StringRef::npos) {
+    BuildNumber = BuildNumber.substr(DashOffset + 1);
+    return BuildNumber;
+  }
+  // Fallback to the generic version.
+  return CLANG_VERSION_STRING;
+}
+
+static void writeUnitData(const CompilerInstance &CI,
+                          IndexDataRecorder &Recorder,
+                          IndexDependencyProvider &DepProvider,
+                          IndexingOptions IndexOpts,
+                          RecordingOptions RecordOpts,
+                          StringRef OutputFile,
+                          const FileEntry *RootFile,
+                          Module *UnitModule,
+                          StringRef SysrootPath);
+
+void IndexRecordActionBase::finish(CompilerInstance &CI) {
+  // We may emit more diagnostics so do the begin/end source file invocations
+  // on the diagnostic client.
+  // FIXME: FrontendAction::EndSourceFile() should probably not call
+  // CI.getDiagnosticClient().EndSourceFile()' until after it has called
+  // 'EndSourceFileAction()', so that code executing during EndSourceFileAction()
+  // can emit diagnostics. If this is fixed, DiagClientBeginEndRAII can go away.
+  struct DiagClientBeginEndRAII {
+    CompilerInstance &CI;
+    DiagClientBeginEndRAII(CompilerInstance &CI) : CI(CI) {
+      CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts());
+    }
+    ~DiagClientBeginEndRAII() {
+      CI.getDiagnosticClient().EndSourceFile();
+    }
+  } diagClientBeginEndRAII(CI);
+
+  SourceManager &SM = CI.getSourceManager();
+  DiagnosticsEngine &Diag = CI.getDiagnostics();
+  HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
+  StringRef DataPath = RecordOpts.DataDirPath;
+
+  std::string Error;
+  if (IndexUnitWriter::initIndexDirectory(DataPath, Error)) {
+    unsigned DiagID = Diag.getCustomDiagID(
+        DiagnosticsEngine::Error, "failed creating index directory %0");
+    Diag.Report(DiagID) << Error;
+    return;
+  }
+
+  std::string OutputFile = CI.getFrontendOpts().OutputFile;
+  if (OutputFile.empty()) {
+    OutputFile = CI.getFrontendOpts().Inputs[0].getFile();
+    OutputFile += ".o";
+  }
+
+  const FileEntry *RootFile = nullptr;
+  Module *UnitMod = nullptr;
+  bool isModuleGeneration = CI.getLangOpts().isCompilingModule();
+  if (!isModuleGeneration &&
+      CI.getFrontendOpts().ProgramAction != frontend::GeneratePCH) {
+    RootFile = SM.getFileEntryForID(SM.getMainFileID());
+  }
+  if (isModuleGeneration) {
+    UnitMod = HS.lookupModule(CI.getLangOpts().CurrentModule,
+                              /*AllowSearch=*/false);
+  }
+
+  writeUnitData(CI, Recorder, DepCollector, IndexCtx.getIndexOpts(), RecordOpts,
+                OutputFile, RootFile, UnitMod,
+                IndexCtx.getSysrootPath());
+}
+
+/// Checks if the unit file exists for module file, if it doesn't it generates
+/// index data for it.
+static bool produceIndexDataForModuleFile(
+                                      serialization::ModuleFile &Mod,
+                                      const CompilerInstance &CI,
+                                      IndexingOptions IndexOpts,
+                                      RecordingOptions RecordOpts,
+                                      IndexUnitWriter &ParentUnitWriter);
+
+static void writeUnitData(const CompilerInstance &CI,
+                          IndexDataRecorder &Recorder,
+                          IndexDependencyProvider &DepProvider,
+                          IndexingOptions IndexOpts,
+                          RecordingOptions RecordOpts,
+                          StringRef OutputFile,
+                          const FileEntry *RootFile,
+                          Module *UnitModule,
+                          StringRef SysrootPath) {
+
+  SourceManager &SM = CI.getSourceManager();
+  DiagnosticsEngine &Diag = CI.getDiagnostics();
+  HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
+  StringRef DataPath = RecordOpts.DataDirPath;
+  bool IsSystemUnit = UnitModule ? UnitModule->IsSystem : false;
+  bool IsModuleUnit = UnitModule != nullptr;
+  bool IsDebugCompilation = CI.getCodeGenOpts().OptimizationLevel == 0;
+  std::string ModuleName = UnitModule ? UnitModule->getFullModuleName() : std::string();
+
+  auto getModuleInfo = [](writer::OpaqueModule mod, SmallVectorImpl<char> &Scratch) -> writer::ModuleInfo {
+    assert(mod);
+    writer::ModuleInfo info;
+    std::string fullName = static_cast<const Module*>(mod)->getFullModuleName();
+    unsigned offset = Scratch.size();
+    Scratch.append(fullName.begin(), fullName.end());
+    info.Name = StringRef(Scratch.data()+offset, fullName.size());
+    return info;
+  };
+
+  auto findModuleForHeader = [&](const FileEntry *FE) -> Module * {
+    if (!UnitModule)
+      return nullptr;
+    if (auto Mod = HS.findModuleForHeader(FE).getModule())
+      if (Mod->isSubModuleOf(UnitModule))
+        return Mod;
+    return nullptr;
+  };
+
+  IndexUnitWriter UnitWriter(CI.getFileManager(),
+                             DataPath,
+                             "clang", getClangVersion(),
+                             OutputFile,
+                             ModuleName,
+                             RootFile,
+                             IsSystemUnit,
+                             IsModuleUnit,
+                             IsDebugCompilation,
+                             CI.getTargetOpts().Triple,
+                             SysrootPath,
+                             getModuleInfo);
+
+  DepProvider.visitFileDependencies(CI, [&](const FileEntry *FE, bool isSystemFile) {
+    UnitWriter.addFileDependency(FE, isSystemFile, findModuleForHeader(FE));
+  });
+  DepProvider.visitIncludes([&](const FileEntry *Source, unsigned Line, const FileEntry *Target) {
+    UnitWriter.addInclude(Source, Line, Target);
+  });
+  DepProvider.visitModuleImports(CI, [&](serialization::ModuleFile &Mod, bool isSystemMod) {
+    Module *UnitMod = HS.lookupModule(Mod.ModuleName, /*AllowSearch=*/false);
+    UnitWriter.addASTFileDependency(Mod.File, isSystemMod, UnitMod);
+    if (Mod.isModule()) {
+      produceIndexDataForModuleFile(Mod, CI, IndexOpts, RecordOpts, UnitWriter);
+    }
+  });
+
+  ClangIndexRecordWriter RecordWriter(CI.getASTContext(), RecordOpts);
+  for (auto I = Recorder.record_begin(), E = Recorder.record_end(); I != E; ++I) {
+    FileID FID = I->first;
+    const FileIndexRecord &Rec = *I->second;
+    const FileEntry *FE = SM.getFileEntryForID(FID);
+    std::string RecordFile;
+    std::string Error;
+
+    if (RecordWriter.writeRecord(FE->getName(), Rec, Error, &RecordFile)) {
+      unsigned DiagID = Diag.getCustomDiagID(DiagnosticsEngine::Error,
+                                             "failed writing record '%0': %1");
+      Diag.Report(DiagID) << RecordFile << Error;
+      return;
+    }
+    UnitWriter.addRecordFile(RecordFile, FE, Rec.isSystem(),
+                             findModuleForHeader(FE));
+  }
+
+  std::string Error;
+  if (UnitWriter.write(Error)) {
+    unsigned DiagID = Diag.getCustomDiagID(DiagnosticsEngine::Error,
+                                           "failed writing unit data: %0");
+    Diag.Report(DiagID) << Error;
+    return;
+  }
+}
+
+namespace {
+class ModuleFileIndexDependencyCollector : public IndexDependencyProvider {
+  serialization::ModuleFile &ModFile;
+  RecordingOptions RecordOpts;
+
+public:
+  ModuleFileIndexDependencyCollector(serialization::ModuleFile &Mod,
+                                     RecordingOptions recordOpts)
+  : ModFile(Mod), RecordOpts(recordOpts) {}
+
+  void visitFileDependencies(const CompilerInstance &CI,
+      llvm::function_ref<void(const FileEntry *FE, bool isSystem)> visitor) override {
+    auto Reader = CI.getModuleManager();
+    Reader->visitInputFiles(ModFile, RecordOpts.RecordSystemDependencies,
+                            /*Complain=*/false,
+                        [&](const serialization::InputFile &IF, bool isSystem) {
+      auto *FE = IF.getFile();
+      if (!FE)
+        return;
+      // Ignore module map files, they are not as important to track as source
+      // files and they may be auto-generated which would create an undesirable
+      // dependency on an intermediate build byproduct.
+      if (FE->getName().endswith("module.modulemap"))
+        return;
+
+      visitor(FE, isSystem);
+    });
+  }
+
+  void visitIncludes(
+           llvm::function_ref<void(const FileEntry *Source, unsigned Line,
+                                   const FileEntry *Target)> visitor) override {
+   // FIXME: Module files without a preprocessing record do not have info about
+   // include locations. Serialize enough data to be able to retrieve such info.
+  }
+
+  void visitModuleImports(const CompilerInstance &CI,
+                 llvm::function_ref<void(serialization::ModuleFile &Mod,
+                                         bool isSystem)> visitor) override {
+    HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
+    for (auto *Mod : ModFile.Imports) {
+      bool isSystemMod = false;
+      if (auto *M = HS.lookupModule(Mod->ModuleName, /*AllowSearch=*/false))
+        isSystemMod = M->IsSystem;
+      if (!isSystemMod || RecordOpts.RecordSystemDependencies)
+        visitor(*Mod, isSystemMod);
+    }
+  }
+};
+} // anonymous namespace.
+
+static void indexModule(serialization::ModuleFile &Mod,
+                        const CompilerInstance &CI,
+                        IndexingOptions IndexOpts,
+                        RecordingOptions RecordOpts) {
+  DiagnosticsEngine &Diag = CI.getDiagnostics();
+  Diag.Report(Mod.ImportLoc, diag::remark_index_producing_module_file_data)
+    << Mod.FileName;
+
+  StringRef SysrootPath = CI.getHeaderSearchOpts().Sysroot;
+  HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
+  Module *UnitMod = HS.lookupModule(Mod.ModuleName, /*AllowSearch=*/false);
+
+  IndexDataRecorder Recorder;
+  IndexingContext IndexCtx(IndexOpts, Recorder);
+
+  IndexCtx.setASTContext(CI.getASTContext());
+  IndexCtx.setSysrootPath(SysrootPath);
+  Recorder.init(&IndexCtx, CI);
+
+  for (const Decl *D : CI.getModuleManager()->getModuleFileLevelDecls(Mod)) {
+    IndexCtx.indexTopLevelDecl(D);
+  }
+  Recorder.finish();
+
+  ModuleFileIndexDependencyCollector DepCollector(Mod, RecordOpts);
+  writeUnitData(CI, Recorder, DepCollector, IndexOpts, RecordOpts,
+                Mod.FileName, /*RootFile=*/nullptr, UnitMod, SysrootPath);
+
+}
+
+static bool produceIndexDataForModuleFile(
+                                      serialization::ModuleFile &Mod,
+                                      const CompilerInstance &CI,
+                                      IndexingOptions IndexOpts,
+                                      RecordingOptions RecordOpts,
+                                      IndexUnitWriter &ParentUnitWriter) {
+  DiagnosticsEngine &Diag = CI.getDiagnostics();
+  std::string Error;
+  // We don't do timestamp check with the PCM file, on purpose. The PCM may get
+  // touched for various reasons which would cause unnecessary work to emit
+  // index data. User modules normally will get rebuilt and their index data
+  // re-emitted, and system modules are generally stable (and they can also can
+  // get rebuilt along with their index data).
+  auto IsUptodateOpt = ParentUnitWriter.isUnitUpToDateForOutputFile(Mod.FileName, None, Error);
+  if (!IsUptodateOpt.hasValue()) {
+    unsigned DiagID = Diag.getCustomDiagID(DiagnosticsEngine::Error,
+                                           "failed file status check: %0");
+    Diag.Report(DiagID) << Error;
+    return false;
+  }
+  if (*IsUptodateOpt)
+    return false;
+
+  indexModule(Mod, CI, IndexOpts, RecordOpts);
+  return true;
+}
+
+static std::unique_ptr<FrontendAction>
+createIndexDataRecordingAction(IndexingOptions IndexOpts,
+                               RecordingOptions RecordOpts,
+                               std::unique_ptr<FrontendAction> WrappedAction) {
+  if (WrappedAction)
+    return llvm::make_unique<WrappingIndexRecordAction>(std::move(WrappedAction),
+                                                        std::move(IndexOpts),
+                                                        std::move(RecordOpts));
+  return llvm::make_unique<IndexRecordAction>(std::move(IndexOpts),
+                                              std::move(RecordOpts));
+}
+
+static std::pair<IndexingOptions, RecordingOptions>
+getIndexOptionsFromFrontendOptions(const FrontendOptions &FEOpts) {
+  index::IndexingOptions IndexOpts;
+  index::RecordingOptions RecordOpts;
+  RecordOpts.DataDirPath = FEOpts.IndexStorePath;
+  if (FEOpts.IndexIgnoreSystemSymbols) {
+    IndexOpts.SystemSymbolFilter =
+    index::IndexingOptions::SystemSymbolFilterKind::None;
+  }
+  RecordOpts.RecordSymbolCodeGenName = FEOpts.IndexRecordCodegenName;
+  return { IndexOpts, RecordOpts };
+}
+
+std::unique_ptr<FrontendAction>
+index::createIndexDataRecordingAction(const FrontendOptions &FEOpts,
+                                std::unique_ptr<FrontendAction> WrappedAction) {
+  index::IndexingOptions IndexOpts;
+  index::RecordingOptions RecordOpts;
+  std::tie(IndexOpts, RecordOpts) = getIndexOptionsFromFrontendOptions(FEOpts);
+  return ::createIndexDataRecordingAction(IndexOpts, RecordOpts,
+                                          std::move(WrappedAction));
+}
+
+bool index::emitIndexDataForModuleFile(const Module *Mod,
+                                       const CompilerInstance &CI,
+                                       IndexUnitWriter &ParentUnitWriter) {
+  index::IndexingOptions IndexOpts;
+  index::RecordingOptions RecordOpts;
+  std::tie(IndexOpts, RecordOpts) = getIndexOptionsFromFrontendOptions(CI.getFrontendOpts());
+
+  auto astReader = CI.getModuleManager();
+  serialization::ModuleFile *ModFile = astReader->getModuleManager().lookup(Mod->getASTFile());
+  assert(ModFile && "no module file loaded for module ?");
+  return produceIndexDataForModuleFile(*ModFile, CI, IndexOpts, RecordOpts, ParentUnitWriter);
+}
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index addee69..c1ce8bc 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -93,12 +93,7 @@
   if (FID.isInvalid())
     return true;
 
-  bool Invalid = false;
-  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
-  if (Invalid || !SEntry.isFile())
-    return true;
-
-  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
+  if (isSystemFile(FID)) {
     switch (IndexOpts.SystemSymbolFilter) {
     case IndexingOptions::SystemSymbolFilterKind::None:
       return true;
@@ -161,6 +156,56 @@
   return true;
 }
 
+void IndexingContext::setSysrootPath(StringRef path) {
+  // Ignore sysroot path if it points to root, otherwise every header will be
+  // treated as system one.
+  if (path == "/")
+    path = StringRef();
+  SysrootPath = path;
+}
+
+bool IndexingContext::isSystemFile(FileID FID) {
+  if (LastFileCheck.first == FID)
+    return LastFileCheck.second;
+
+  auto result = [&](bool res) -> bool {
+    LastFileCheck = { FID, res };
+    return res;
+  };
+
+  bool Invalid = false;
+  const SrcMgr::SLocEntry &SEntry =
+    Ctx->getSourceManager().getSLocEntry(FID, &Invalid);
+  if (Invalid || !SEntry.isFile())
+    return result(false);
+
+  const SrcMgr::FileInfo &FI = SEntry.getFile();
+  if (FI.getFileCharacteristic() != SrcMgr::C_User)
+    return result(true);
+
+  auto *CC = FI.getContentCache();
+  if (!CC)
+    return result(false);
+  auto *FE = CC->OrigEntry;
+  if (!FE)
+    return result(false);
+
+  if (SysrootPath.empty())
+    return result(false);
+
+  // Check if directory is in sysroot so that we can consider system headers
+  // even the headers found via a user framework search path, pointing inside
+  // sysroot.
+  auto dirEntry = FE->getDir();
+  auto pair = DirEntries.insert(std::make_pair(dirEntry, false));
+  bool &isSystemDir = pair.first->second;
+  bool wasInserted = pair.second;
+  if (wasInserted) {
+    isSystemDir = StringRef(dirEntry->getName()).startswith(SysrootPath);
+  }
+  return result(isSystemDir);
+}
+
 static const CXXRecordDecl *
 getDeclContextForTemplateInstationPattern(const Decl *D) {
   if (const auto *CTSD =
@@ -231,8 +276,8 @@
 
 /// Whether the given NamedDecl should be skipped because it has no name.
 static bool shouldSkipNamelessDecl(const NamedDecl *ND) {
-  return ND->getDeclName().isEmpty() && !isa<TagDecl>(ND) &&
-         !isa<ObjCCategoryDecl>(ND);
+  return (ND->getDeclName().isEmpty() && !isa<TagDecl>(ND) &&
+          !isa<ObjCCategoryDecl>(ND)) || isa<CXXDeductionGuideDecl>(ND);
 }
 
 static const Decl *adjustParent(const Decl *Parent) {
@@ -321,7 +366,7 @@
                                            const Expr *OrigE,
                                            const Decl *OrigD,
                                            const DeclContext *ContainerDC) {
-  if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
+  if (D->isImplicit() && !(isa<ObjCMethodDecl>(D) || isa<ObjCIvarDecl>(D)))
     return true;
   if (!isa<NamedDecl>(D) || shouldSkipNamelessDecl(cast<NamedDecl>(D)))
     return true;
@@ -337,12 +382,7 @@
   if (FID.isInvalid())
     return true;
 
-  bool Invalid = false;
-  const SrcMgr::SLocEntry &SEntry = SM.getSLocEntry(FID, &Invalid);
-  if (Invalid || !SEntry.isFile())
-    return true;
-
-  if (SEntry.getFile().getFileCharacteristic() != SrcMgr::C_User) {
+  if (isSystemFile(FID)) {
     switch (IndexOpts.SystemSymbolFilter) {
     case IndexingOptions::SystemSymbolFilterKind::None:
       return true;
diff --git a/lib/Index/IndexingContext.h b/lib/Index/IndexingContext.h
index 566651c..70e72e1 100644
--- a/lib/Index/IndexingContext.h
+++ b/lib/Index/IndexingContext.h
@@ -11,9 +11,11 @@
 #define LLVM_CLANG_LIB_INDEX_INDEXINGCONTEXT_H
 
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Index/IndexSymbol.h"
 #include "clang/Index/IndexingAction.h"
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
 
 namespace clang {
   class ASTContext;
@@ -29,7 +31,7 @@
   class Stmt;
   class Expr;
   class TypeLoc;
-  class SourceLocation;
+  class DirectoryEntry;
 
 namespace index {
   class IndexDataConsumer;
@@ -38,6 +40,13 @@
   IndexingOptions IndexOpts;
   IndexDataConsumer &DataConsumer;
   ASTContext *Ctx = nullptr;
+  std::string SysrootPath;
+
+  // Records whether a directory entry is system or not.
+  llvm::DenseMap<const DirectoryEntry *, bool> DirEntries;
+  // Keeps track of the last check for whether a FileID is system or
+  // not. This is used to speed up isSystemFile() call.
+  std::pair<FileID, bool> LastFileCheck;
 
 public:
   IndexingContext(IndexingOptions IndexOpts, IndexDataConsumer &DataConsumer)
@@ -47,6 +56,10 @@
   IndexDataConsumer &getDataConsumer() { return DataConsumer; }
 
   void setASTContext(ASTContext &ctx) { Ctx = &ctx; }
+  void setSysrootPath(StringRef path);
+  StringRef getSysrootPath() const { return SysrootPath; }
+
+  bool isSystemFile(FileID FID);
 
   bool shouldIndex(const Decl *D);
 
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index 21054b0..c4fe737 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -99,6 +99,8 @@
   void VisitVarDecl(const VarDecl *D);
   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
+  void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
+  void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
 
   void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
     IgnoreResults = true;
@@ -112,14 +114,6 @@
     IgnoreResults = true;
   }
 
-  void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
-    IgnoreResults = true;
-  }
-
-  void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
-    IgnoreResults = true;
-  }
-
   bool ShouldGenerateLocation(const NamedDecl *D);
 
   bool isLocal(const NamedDecl *D) {
@@ -609,6 +603,16 @@
   return IgnoreResults;
 }
 
+static void printQualifier(llvm::raw_ostream &Out, ASTContext &Ctx, NestedNameSpecifier *NNS) {
+  // FIXME: Encode the qualifier, don't just print it.
+  PrintingPolicy PO(Ctx.getLangOpts());
+  PO.SuppressTagKeyword = true;
+  PO.SuppressUnwrittenScope = true;
+  PO.ConstantArraySizeAsWritten = false;
+  PO.AnonymousTagLocations = false;
+  NNS->print(Out, PO);
+}
+
 void USRGenerator::VisitType(QualType T) {
   // This method mangles in USR information for types.  It can possibly
   // just reuse the naming-mangling logic used by codegen, although the
@@ -797,13 +801,7 @@
     }
     if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
       Out << '^';
-      // FIXME: Encode the qualifier, don't just print it.
-      PrintingPolicy PO(Ctx.getLangOpts());
-      PO.SuppressTagKeyword = true;
-      PO.SuppressUnwrittenScope = true;
-      PO.ConstantArraySizeAsWritten = false;
-      PO.AnonymousTagLocations = false;
-      DNT->getQualifier()->print(Out, PO);
+      printQualifier(Out, Ctx, DNT->getQualifier());
       Out << ':' << DNT->getIdentifier()->getName();
       return;
     }
@@ -912,6 +910,26 @@
   }
 }
 
+void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
+    return;
+  VisitDeclContext(D->getDeclContext());
+  Out << "@UUV@";
+  printQualifier(Out, D->getASTContext(), D->getQualifier());
+  EmitDeclName(D);
+}
+
+void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
+  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
+    return;
+  VisitDeclContext(D->getDeclContext());
+  Out << "@UUT@";
+  printQualifier(Out, D->getASTContext(), D->getQualifier());
+  Out << D->getName(); // Simple name.
+}
+
+
+
 //===----------------------------------------------------------------------===//
 // USR generation functions.
 //===----------------------------------------------------------------------===//
diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp
index 1ebcc0a..b9fb005 100644
--- a/lib/Lex/HeaderSearch.cpp
+++ b/lib/Lex/HeaderSearch.cpp
@@ -1108,6 +1108,7 @@
 
   // Get information about this file.
   HeaderFileInfo &FileInfo = getFileInfo(File);
+  bool isCompilingModule = ModMap.getLangOpts().isCompilingModule();
 
   // FIXME: this is a workaround for the lack of proper modules-aware support
   // for #import / #pragma once
@@ -1143,7 +1144,7 @@
     // 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 &&
+    if ((isCompilingModule || !isImport) && !FileInfo.isModuleHeader &&
         FileInfo.getControllingMacro(ExternalLookup))
       TryEnterHdr = true;
     return TryEnterHdr;
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index 61bcef8..c42443c 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -1259,6 +1259,35 @@
   return TokenLoc.getLocWithOffset(Tok.getLength() + NumWhitespaceChars);
 }
 
+SourceLocation Lexer::findNextTokenLocationAfterTokenAt(
+    SourceLocation Loc, const SourceManager &SM, const LangOptions &LangOpts) {
+  // TODO: Share the code with the function above when upstreaming.
+  if (Loc.isMacroID()) {
+    if (!Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc))
+      return SourceLocation();
+  }
+  Loc = Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts);
+
+  // Break down the source location.
+  std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
+
+  // Try to load the file buffer.
+  bool InvalidTemp = false;
+  StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp);
+  if (InvalidTemp)
+    return SourceLocation();
+
+  const char *TokenBegin = File.data() + LocInfo.second;
+
+  // Lex from the start of the given location.
+  Lexer lexer(SM.getLocForStartOfFile(LocInfo.first), LangOpts, File.begin(),
+              TokenBegin, File.end());
+  // Find the token.
+  Token Tok;
+  lexer.LexFromRawLexer(Tok);
+  return Tok.getLocation();
+}
+
 /// getCharAndSizeSlow - Peek a single 'character' from the specified buffer,
 /// get its size, and return it.  This is tricky in several cases:
 ///   1. If currently at the start of a trigraph, we warn about the trigraph,
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 40f78ce..8c0da2c 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -742,10 +742,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");
@@ -888,6 +903,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) {
@@ -1186,6 +1203,7 @@
       ExcludeKeyword,
       ExplicitKeyword,
       ExportKeyword,
+      ExportAsKeyword,
       ExternKeyword,
       FrameworkKeyword,
       LinkKeyword,
@@ -1297,6 +1315,7 @@
                          SourceLocation LeadingLoc);
     void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
     void parseExportDecl();
+    void parseExportAsDecl();
     void parseUseDecl();
     void parseLinkDecl();
     void parseConfigMacros();
@@ -1348,6 +1367,7 @@
                  .Case("exclude", MMToken::ExcludeKeyword)
                  .Case("explicit", MMToken::ExplicitKeyword)
                  .Case("export", MMToken::ExportKeyword)
+                 .Case("export_as", MMToken::ExportAsKeyword)
                  .Case("extern", MMToken::ExternKeyword)
                  .Case("framework", MMToken::FrameworkKeyword)
                  .Case("header", MMToken::HeaderKeyword)
@@ -1558,6 +1578,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
   };
@@ -1575,6 +1597,7 @@
 ///     header-declaration
 ///     submodule-declaration
 ///     export-declaration
+///     export-as-declaration
 ///     link-declaration
 ///
 ///   submodule-declaration:
@@ -1694,6 +1717,7 @@
   SourceLocation LBraceLoc = consumeToken();
   
   // Determine whether this (sub)module has already been defined.
+  Module *ShadowingModule = nullptr;
   if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
     // We might see a (re)definition of a module that we already have a
     // definition for in two cases:
@@ -1719,23 +1743,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;
@@ -1809,6 +1845,10 @@
       parseExportDecl();
       break;
 
+    case MMToken::ExportAsKeyword:
+      parseExportAsDecl();
+      break;
+
     case MMToken::UseKeyword:
       parseUseDecl();
       break;
@@ -2269,6 +2309,41 @@
   ActiveModule->UnresolvedExports.push_back(Unresolved);
 }
 
+/// \brief Parse a module export_as declaration.
+///
+///   export-as-declaration:
+///     'export_as' identifier
+void ModuleMapParser::parseExportAsDecl() {
+  assert(Tok.is(MMToken::ExportAsKeyword));
+  consumeToken();
+
+  if (!Tok.is(MMToken::Identifier)) {
+    Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
+    HadError = true;
+    return;
+  }
+
+  if (ActiveModule->Parent) {
+    Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
+    consumeToken();
+    return;
+  }
+  
+  if (!ActiveModule->ExportAsModule.empty()) {
+    if (ActiveModule->ExportAsModule == Tok.getString()) {
+      Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)
+        << ActiveModule->Name << Tok.getString();
+    } else {
+      Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)
+        << ActiveModule->Name << ActiveModule->ExportAsModule
+        << Tok.getString();
+    }
+  }
+  
+  ActiveModule->ExportAsModule = Tok.getString();
+  consumeToken();
+}
+
 /// \brief Parse a module use declaration.
 ///
 ///   use-declaration:
@@ -2611,6 +2686,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:
@@ -2626,6 +2702,10 @@
       Attrs.IsExternC = true;
       break;
 
+    case AT_swift_infer_import_as_member:
+      Attrs.IsSwiftInferImportAsMember = true;
+      break;
+
     case AT_exhaustive:
       Attrs.IsExhaustive = true;
       break;
@@ -2674,6 +2754,7 @@
     case MMToken::Exclaim:
     case MMToken::ExcludeKeyword:
     case MMToken::ExportKeyword:
+    case MMToken::ExportAsKeyword:
     case MMToken::HeaderKeyword:
     case MMToken::Identifier:
     case MMToken::LBrace:
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index b2450f5..946a29d 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -78,7 +78,8 @@
 }
 
 /// \brief Read and discard all tokens remaining on the current line until
-/// the tok::eod token is found.
+/// the tok::eod token is found. If the discarded tokens are in a skipped range,
+/// complete the range and pass it to the \c SourceRangeSkipped callback.
 void Preprocessor::DiscardUntilEndOfDirective() {
   Token Tmp;
   do {
@@ -349,7 +350,8 @@
 /// If ElseOk is true, then \#else directives are ok, if not, then we have
 /// already seen one so a \#else directive is a duplicate.  When this returns,
 /// the caller can lex the first valid token.
-void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc,
+void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken,
+                                                SourceLocation IfTokenLoc,
                                                 bool FoundNonSkipPortion,
                                                 bool FoundElse,
                                                 SourceLocation ElseLoc) {
@@ -557,10 +559,10 @@
   // the #if block.
   CurPPLexer->LexingRawMode = false;
 
-  if (Callbacks) {
-    SourceLocation BeginLoc = ElseLoc.isValid() ? ElseLoc : IfTokenLoc;
-    Callbacks->SourceRangeSkipped(SourceRange(BeginLoc, Tok.getLocation()));
-  }
+  if (Callbacks)
+    Callbacks->SourceRangeSkipped(
+        SourceRange(HashToken.getLocation(), CurPPLexer->getSourceLocation()),
+        Tok.getLocation());
 }
 
 void Preprocessor::PTHSkipExcludedConditionalBlock() {
@@ -948,15 +950,17 @@
     default: break;
     // C99 6.10.1 - Conditional Inclusion.
     case tok::pp_if:
-      return HandleIfDirective(Result, ReadAnyTokensBeforeDirective);
+      return HandleIfDirective(Result, SavedHash, ReadAnyTokensBeforeDirective);
     case tok::pp_ifdef:
-      return HandleIfdefDirective(Result, false, true/*not valid for miopt*/);
+      return HandleIfdefDirective(Result, SavedHash, false,
+                                  true /*not valid for miopt*/);
     case tok::pp_ifndef:
-      return HandleIfdefDirective(Result, true, ReadAnyTokensBeforeDirective);
+      return HandleIfdefDirective(Result, SavedHash, true,
+                                  ReadAnyTokensBeforeDirective);
     case tok::pp_elif:
-      return HandleElifDirective(Result);
+      return HandleElifDirective(Result, SavedHash);
     case tok::pp_else:
-      return HandleElseDirective(Result);
+      return HandleElseDirective(Result, SavedHash);
     case tok::pp_endif:
       return HandleEndifDirective(Result);
 
@@ -1652,12 +1656,18 @@
                                           DiagnosticsEngine &Diags, Module *M) {
   Module::Requirement Requirement;
   Module::UnresolvedHeaderDirective MissingHeader;
-  if (M->isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader))
+  Module *ShadowingModule = nullptr;
+  if (M->isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader,
+                     ShadowingModule))
     return false;
 
   if (MissingHeader.FileNameLoc.isValid()) {
     Diags.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
         << MissingHeader.IsUmbrella << MissingHeader.FileName;
+  } else if (ShadowingModule) {
+    Diags.Report(M->DefinitionLoc, diag::err_module_shadowed) << M->Name;
+    Diags.Report(ShadowingModule->DefinitionLoc,
+                 diag::note_previous_definition);
   } else {
     // FIXME: Track the location at which the requirement was specified, and
     // use it here.
@@ -2614,7 +2624,9 @@
 /// true if any tokens have been returned or pp-directives activated before this
 /// \#ifndef has been lexed.
 ///
-void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef,
+void Preprocessor::HandleIfdefDirective(Token &Result,
+                                        const Token &HashToken,
+                                        bool isIfndef,
                                         bool ReadAnyTokensBeforeDirective) {
   ++NumIf;
   Token DirectiveTok = Result;
@@ -2626,8 +2638,8 @@
   if (MacroNameTok.is(tok::eod)) {
     // Skip code until we get to #endif.  This helps with recovery by not
     // emitting an error when the #endif is reached.
-    SkipExcludedConditionalBlock(DirectiveTok.getLocation(),
-                                 /*Foundnonskip*/false, /*FoundElse*/false);
+    SkipExcludedConditionalBlock(HashToken, DirectiveTok.getLocation(),
+                                 /*Foundnonskip*/ false, /*FoundElse*/ false);
     return;
   }
 
@@ -2675,15 +2687,16 @@
                                      /*foundelse*/false);
   } else {
     // No, skip the contents of this block.
-    SkipExcludedConditionalBlock(DirectiveTok.getLocation(),
-                                 /*Foundnonskip*/false,
-                                 /*FoundElse*/false);
+    SkipExcludedConditionalBlock(HashToken, DirectiveTok.getLocation(),
+                                 /*Foundnonskip*/ false,
+                                 /*FoundElse*/ false);
   }
 }
 
 /// HandleIfDirective - Implements the \#if directive.
 ///
 void Preprocessor::HandleIfDirective(Token &IfToken,
+                                     const Token &HashToken,
                                      bool ReadAnyTokensBeforeDirective) {
   ++NumIf;
 
@@ -2721,8 +2734,9 @@
                                    /*foundnonskip*/true, /*foundelse*/false);
   } else {
     // No, skip the contents of this block.
-    SkipExcludedConditionalBlock(IfToken.getLocation(), /*Foundnonskip*/false,
-                                 /*FoundElse*/false);
+    SkipExcludedConditionalBlock(HashToken, IfToken.getLocation(),
+                                 /*Foundnonskip*/ false,
+                                 /*FoundElse*/ false);
   }
 }
 
@@ -2754,7 +2768,7 @@
 
 /// HandleElseDirective - Implements the \#else directive.
 ///
-void Preprocessor::HandleElseDirective(Token &Result) {
+void Preprocessor::HandleElseDirective(Token &Result, const Token &HashToken) {
   ++NumElse;
 
   // #else directive in a non-skipping conditional... start skipping.
@@ -2785,13 +2799,14 @@
   }
 
   // Finally, skip the rest of the contents of this block.
-  SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
-                               /*FoundElse*/true, Result.getLocation());
+  SkipExcludedConditionalBlock(HashToken, CI.IfLoc, /*Foundnonskip*/ true,
+                               /*FoundElse*/ true, Result.getLocation());
 }
 
 /// HandleElifDirective - Implements the \#elif directive.
 ///
-void Preprocessor::HandleElifDirective(Token &ElifToken) {
+void Preprocessor::HandleElifDirective(Token &ElifToken,
+                                       const Token &HashToken) {
   ++NumElse;
 
   // #elif directive in a non-skipping conditional... start skipping.
@@ -2828,7 +2843,7 @@
   }
 
   // Finally, skip the rest of the contents of this block.
-  SkipExcludedConditionalBlock(CI.IfLoc, /*Foundnonskip*/true,
-                               /*FoundElse*/CI.FoundElse,
+  SkipExcludedConditionalBlock(HashToken, CI.IfLoc, /*Foundnonskip*/ true,
+                               /*FoundElse*/ CI.FoundElse,
                                ElifToken.getLocation());
 }
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 3f8ede2..15968d5 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)
@@ -1131,6 +1132,7 @@
       .Case("cxx_exceptions", LangOpts.CXXExceptions)
       .Case("cxx_rtti", LangOpts.RTTI && LangOpts.RTTIData)
       .Case("enumerator_attributes", true)
+      .Case("generalized_swift_name", true)
       .Case("nullability", true)
       .Case("nullability_on_arrays", true)
       .Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory))
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
index 03c4cbe..954b569 100644
--- a/lib/Lex/PreprocessingRecord.cpp
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -400,8 +400,9 @@
                       MacroNameTok.getLocation());
 }
 
-void PreprocessingRecord::SourceRangeSkipped(SourceRange Range) {
-  SkippedRanges.push_back(Range);
+void PreprocessingRecord::SourceRangeSkipped(SourceRange Range,
+                                             SourceLocation EndifLoc) {
+  SkippedRanges.emplace_back(Range.getBegin(), EndifLoc);
 }
 
 void PreprocessingRecord::MacroExpands(const Token &Id,
diff --git a/lib/Parse/ParseCXXInlineMethods.cpp b/lib/Parse/ParseCXXInlineMethods.cpp
index 27651c9..32724c4 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 a461069..2397e51 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,
@@ -370,6 +402,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);
@@ -880,7 +916,7 @@
 ///
 /// version-arg:
 ///   'introduced' '=' version
-///   'deprecated' '=' version
+///   'deprecated' ['=' version]
 ///   'obsoleted' = version
 ///   'unavailable'
 /// opt-replacement:
@@ -912,13 +948,18 @@
     return;
   }
   IdentifierLoc *Platform = ParseIdentifierLoc();
-  // Canonicalize platform name from "macosx" to "macos".
-  if (Platform->Ident && Platform->Ident->getName() == "macosx")
-    Platform->Ident = PP.getIdentifierInfo("macos");
-  // Canonicalize platform name from "macosx_app_extension" to
-  // "macos_app_extension".
-  if (Platform->Ident && Platform->Ident->getName() == "macosx_app_extension")
-    Platform->Ident = PP.getIdentifierInfo("macos_app_extension");
+  if (const IdentifierInfo *const Ident = Platform->Ident) {
+    // Canonicalize platform name from "macosx" to "macos".
+    if (Ident->getName() == "macosx")
+      Platform->Ident = PP.getIdentifierInfo("macos");
+    // Canonicalize platform name from "macosx_app_extension" to
+    // "macos_app_extension".
+    else if (Ident->getName() == "macosx_app_extension")
+      Platform->Ident = PP.getIdentifierInfo("macos_app_extension");
+    else
+      Platform->Ident = PP.getIdentifierInfo(
+          AvailabilityAttr::canonicalizePlatformName(Ident->getName()));
+  }
 
   // Parse the ',' following the platform name.
   if (ExpectAndConsume(tok::comma)) {
@@ -968,6 +1009,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);
@@ -6785,3 +6841,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 2301284..030f17a 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -2772,8 +2772,10 @@
         // initialize it.
         ThisDecl = VT->getTemplatedDecl();
 
-      if (ThisDecl && AccessAttrs)
+      if (ThisDecl) {
         Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);
+        Actions.ProcessAPINotes(ThisDecl);
+      }
     }
 
     // Error recovery might have converted a non-static member into a static
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index dcafbad..7332bfb 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -966,6 +966,8 @@
     // that would be an error.
 
     ParsedType InitCaptureType;
+    if (!Init.isInvalid())
+      Init = Actions.CorrectDelayedTyposInExpr(Init.get());
     if (Init.isUsable()) {
       // Get the pointer and store it in an lvalue, so we can use it as an
       // out argument.
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index 01b1bf4..d1bd67a 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -211,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) {
diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp
index d6f16bb..181bd41 100644
--- a/lib/Parse/ParseStmtAsm.cpp
+++ b/lib/Parse/ParseStmtAsm.cpp
@@ -578,8 +578,7 @@
 
   llvm::SourceMgr TempSrcMgr;
   llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr);
-  MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, llvm::CodeModel::Default,
-                             Ctx);
+  MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, Ctx);
   std::unique_ptr<llvm::MemoryBuffer> Buffer =
       llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>");
 
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 1ed7ef9..d2f70fc 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -67,6 +67,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) {
@@ -406,6 +411,9 @@
 //===----------------------------------------------------------------------===//
 
 Parser::~Parser() {
+  // Clear out the parse-type-from-string callback.
+  Actions.ParseTypeFromStringCallback = nullptr;
+
   // If we still have scopes active, delete the scope tree.
   delete getCurScope();
   Actions.CurScope = nullptr;
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 7d9ae62..75fca76 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -21,6 +21,7 @@
   Sema.cpp
   SemaAccess.cpp
   SemaAttr.cpp
+  SemaAPINotes.cpp
   SemaCXXScopeSpec.cpp
   SemaCast.cpp
   SemaChecking.cpp
@@ -62,4 +63,5 @@
   clangBasic
   clangEdit
   clangLex
+  clangAPINotes
   )
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index a18f714..6f22620 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -75,7 +75,13 @@
     : ExternalSource(nullptr), isMultiplexExternalSource(false),
       FPFeatures(pp.getLangOpts()), LangOpts(pp.getLangOpts()), PP(pp),
       Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()),
-      SourceMgr(PP.getSourceManager()), CollectStats(false),
+      SourceMgr(PP.getSourceManager()),
+
+      // Don't you dare clang-format this.
+      // APINotes is a never-ending source of conflicts. Don't make it worse.
+      APINotes(SourceMgr, LangOpts),
+
+      CollectStats(false),
       CodeCompleter(CodeCompleter), CurContext(nullptr),
       OriginalLexicalContext(nullptr), MSStructPragmaOn(false),
       MSPointerToMemberRepresentationMethod(
diff --git a/lib/Sema/SemaAPINotes.cpp b/lib/Sema/SemaAPINotes.cpp
new file mode 100644
index 0000000..0b3cdbb
--- /dev/null
+++ b/lib/Sema/SemaAPINotes.cpp
@@ -0,0 +1,899 @@
+//===--- 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
+  };
+  enum IsReplacement_t : bool {
+    IsNotReplacement,
+    IsReplacement
+  };
+
+  struct VersionedInfoMetadata {
+    /// An empty version refers to unversioned metadata.
+    VersionTuple Version;
+    unsigned IsActive: 1;
+    unsigned IsReplacement: 1;
+
+    VersionedInfoMetadata(VersionTuple version, IsActive_t active,
+                          IsReplacement_t replacement)
+      : Version(version), IsActive(active == IsActive_t::IsActive),
+        IsReplacement(replacement == IsReplacement_t::IsReplacement) {}
+  };
+} // 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, metadata.Version, *existing, /*IsReplacedByActive*/true);
+
+        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,
+              /*IsReplacedByActive*/metadata.IsReplacement);
+          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,
+            /*IsReplacedByActive*/metadata.IsReplacement);
+        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(SelectedVersion, IsNotActive,
+                                            IsReplacement);
+  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;
+    auto Replacement = IsNotReplacement;
+    if (Active == IsNotActive && Version.empty()) {
+      Replacement = IsReplacement;
+      Version = Info[Selected].first;
+    }
+    ProcessAPINotes(S, D, InfoSlice, VersionedInfoMetadata(Version, Active,
+                                                           Replacement));
+  }
+}
+
+/// 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/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index d603101..ad63486 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -2458,24 +2458,17 @@
     // GCC's cast to union extension.
     if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) {
       RecordDecl *RD = DestRecordTy->getDecl();
-      RecordDecl::field_iterator Field, FieldEnd;
-      for (Field = RD->field_begin(), FieldEnd = RD->field_end();
-           Field != FieldEnd; ++Field) {
-        if (Self.Context.hasSameUnqualifiedType(Field->getType(), SrcType) &&
-            !Field->isUnnamedBitfield()) {
-          Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
-            << SrcExpr.get()->getSourceRange();
-          break;
-        }
-      }
-      if (Field == FieldEnd) {
+      if (CastExpr::getTargetFieldForToUnionCast(RD, SrcType)) {
+        Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
+          << SrcExpr.get()->getSourceRange();
+        Kind = CK_ToUnion;
+        return;
+      } else {
         Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
           << SrcType << SrcExpr.get()->getSourceRange();
         SrcExpr = ExprError();
         return;
       }
-      Kind = CK_ToUnion;
-      return;
     }
 
     // OpenCL v2.0 s6.13.10 - Allow casts from '0' to event_t type.
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index b2223b7..fb78159 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -3797,23 +3797,33 @@
   if (checkVAStartIsInVariadicFunction(*this, Func))
     return true;
 
-  const struct {
-    unsigned ArgNo;
-    QualType Type;
-  } ArgumentTypes[] = {
-    { 1, Context.getPointerType(Context.CharTy.withConst()) },
-    { 2, Context.getSizeType() },
-  };
+  // __va_start on Windows does not validate the parameter qualifiers
 
-  for (const auto &AT : ArgumentTypes) {
-    const Expr *Arg = Call->getArg(AT.ArgNo)->IgnoreParens();
-    if (Arg->getType().getCanonicalType() == AT.Type.getCanonicalType())
-      continue;
-    Diag(Arg->getLocStart(), diag::err_typecheck_convert_incompatible)
-      << Arg->getType() << AT.Type << 1 /* different class */
-      << 0 /* qualifier difference */ << 3 /* parameter mismatch */
-      << AT.ArgNo + 1 << Arg->getType() << AT.Type;
-  }
+  const Expr *Arg1 = Call->getArg(1)->IgnoreParens();
+  const Type *Arg1Ty = Arg1->getType().getCanonicalType().getTypePtr();
+
+  const Expr *Arg2 = Call->getArg(2)->IgnoreParens();
+  const Type *Arg2Ty = Arg2->getType().getCanonicalType().getTypePtr();
+
+  const QualType &ConstCharPtrTy =
+      Context.getPointerType(Context.CharTy.withConst());
+  if (!Arg1Ty->isPointerType() ||
+      Arg1Ty->getPointeeType().withoutLocalFastQualifiers() != Context.CharTy)
+    Diag(Arg1->getLocStart(), diag::err_typecheck_convert_incompatible)
+        << Arg1->getType() << ConstCharPtrTy
+        << 1 /* different class */
+        << 0 /* qualifier difference */
+        << 3 /* parameter mismatch */
+        << 2 << Arg1->getType() << ConstCharPtrTy;
+
+  const QualType SizeTy = Context.getSizeType();
+  if (Arg2Ty->getCanonicalTypeInternal().withoutLocalFastQualifiers() != SizeTy)
+    Diag(Arg2->getLocStart(), diag::err_typecheck_convert_incompatible)
+        << Arg2->getType() << SizeTy
+        << 1 /* different class */
+        << 0 /* qualifier difference */
+        << 3 /* parameter mismatch */
+        << 3 << Arg2->getType() << SizeTy;
 
   return false;
 }
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 4de7d42..700cf38 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -432,53 +432,6 @@
   return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
 }
 
-/// \brief Compute the qualification required to get from the current context
-/// (\p CurContext) to the target context (\p TargetContext).
-///
-/// \param Context the AST context in which the qualification will be used.
-///
-/// \param CurContext the context where an entity is being named, which is
-/// typically based on the current scope.
-///
-/// \param TargetContext the context in which the named entity actually 
-/// resides.
-///
-/// \returns a nested name specifier that refers into the target context, or
-/// NULL if no qualification is needed.
-static NestedNameSpecifier *
-getRequiredQualification(ASTContext &Context,
-                         const DeclContext *CurContext,
-                         const DeclContext *TargetContext) {
-  SmallVector<const DeclContext *, 4> TargetParents;
-  
-  for (const DeclContext *CommonAncestor = TargetContext;
-       CommonAncestor && !CommonAncestor->Encloses(CurContext);
-       CommonAncestor = CommonAncestor->getLookupParent()) {
-    if (CommonAncestor->isTransparentContext() ||
-        CommonAncestor->isFunctionOrMethod())
-      continue;
-    
-    TargetParents.push_back(CommonAncestor);
-  }
-
-  NestedNameSpecifier *Result = nullptr;
-  while (!TargetParents.empty()) {
-    const DeclContext *Parent = TargetParents.pop_back_val();
-
-    if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent)) {
-      if (!Namespace->getIdentifier())
-        continue;
-
-      Result = NestedNameSpecifier::Create(Context, Result, Namespace);
-    }
-    else if (const TagDecl *TD = dyn_cast<TagDecl>(Parent))
-      Result = NestedNameSpecifier::Create(Context, Result,
-                                           false,
-                                     Context.getTypeDeclType(TD).getTypePtr());
-  }  
-  return Result;
-}
-
 /// Determine whether \p Id is a name reserved for the implementation (C99
 /// 7.1.3, C++ [lib.global.names]).
 static bool isReservedName(const IdentifierInfo *Id,
@@ -590,9 +543,8 @@
   R.QualifierIsInformative = false;
   
   if (!R.Qualifier)
-    R.Qualifier = getRequiredQualification(SemaRef.Context, 
-                                           CurContext, 
-                                           R.Declaration->getDeclContext());
+    R.Qualifier = NestedNameSpecifier::getRequiredQualification(
+        SemaRef.Context, CurContext, R.Declaration->getDeclContext());
   return false;
 }
 
@@ -3366,9 +3318,8 @@
         
     // If we need a nested-name-specifier, add one now.
     if (!InContext) {
-      NestedNameSpecifier *NNS
-        = getRequiredQualification(S.Context, CurContext,
-                                   Overridden->getDeclContext());
+      NestedNameSpecifier *NNS = NestedNameSpecifier::getRequiredQualification(
+          S.Context, CurContext, Overridden->getDeclContext());
       if (NNS) {
         std::string Str;
         llvm::raw_string_ostream OS(Str);
@@ -4230,7 +4181,8 @@
     // If there are no prior enumerators in C++, check whether we have to 
     // qualify the names of the enumerators that we suggest, because they
     // may not be visible in this scope.
-    Qualifier = getRequiredQualification(Context, CurContext, Enum);
+    Qualifier = NestedNameSpecifier::getRequiredQualification(Context,
+                                                              CurContext, Enum);
   }
   
   // Add any enumerators that have not yet been mentioned.
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 692a77e..bf8238c 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2416,6 +2416,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(),
@@ -2433,6 +2437,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());
@@ -11802,10 +11808,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 &&
@@ -11820,7 +11824,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 {
@@ -11829,6 +11833,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);
@@ -12594,7 +12608,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())
@@ -13925,6 +13941,12 @@
     Invalid = true;
   }
 
+  if (!Invalid && TUK == TUK_Definition && DC->getDeclKind() == Decl::Enum) {
+    Diag(New->getLocation(), diag::err_type_defined_in_enum)
+      << Context.getTagDeclType(New);
+    Invalid = true;
+  }
+
   // Maybe add qualifier info.
   if (SS.isNotEmpty()) {
     if (SS.isSet()) {
@@ -15248,6 +15270,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Record, Attr);
+  ProcessAPINotes(Record);
 }
 
 /// \brief Determine whether the given integral value is representable within
@@ -15548,6 +15571,8 @@
   if (Attr) ProcessDeclAttributeList(S, New, Attr);
   AddPragmaAttributes(S, New);
 
+  ProcessAPINotes(New);
+
   // Register this decl in the current scope stack.
   New->setAccess(TheEnumDecl->getAccess());
   PushOnScopeChains(New, S);
@@ -15771,6 +15796,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Enum, Attr);
+  ProcessAPINotes(Enum);
 
   if (Enum->isDependentType()) {
     for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 2a310bf..8249715 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -1517,6 +1517,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),
@@ -2441,6 +2461,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,
@@ -4029,6 +4058,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(),
@@ -4856,6 +4906,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(),
@@ -5045,6 +5129,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.
 //===----------------------------------------------------------------------===//
@@ -6120,6 +6619,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;
@@ -6186,6 +6688,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;
@@ -6245,6 +6750,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;
@@ -6517,6 +7025,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);
@@ -6759,6 +7286,9 @@
 
   // Apply additional attributes specified by '#pragma clang attribute'.
   AddPragmaAttributes(S, D);
+
+  // Look for API notes that map to attributes.
+  ProcessAPINotes(D);
 }
 
 /// Is the given declaration allowed to use a forbidden type?
@@ -7003,6 +7533,49 @@
   return dyn_cast<NamedDecl>(OrigCtx);
 }
 
+namespace {
+
+struct AttributeInsertion {
+  StringRef Prefix;
+  SourceLocation Loc;
+  StringRef Suffix;
+
+  static AttributeInsertion createInsertionAfter(const NamedDecl *D) {
+    return {" ", D->getLocEnd(), ""};
+  }
+  static AttributeInsertion createInsertionAfter(SourceLocation Loc) {
+    return {" ", Loc, ""};
+  }
+  static AttributeInsertion createInsertionBefore(const NamedDecl *D) {
+    return {"", D->getLocStart(), "\n"};
+  }
+};
+
+} // end anonymous namespace
+
+/// Returns a source location in which it's appropriate to insert a new
+/// attribute for the given declaration \D.
+static Optional<AttributeInsertion>
+createAttributeInsertion(const NamedDecl *D, const SourceManager &SM,
+                         const LangOptions &LangOpts) {
+  if (isa<ObjCPropertyDecl>(D))
+    return AttributeInsertion::createInsertionAfter(D);
+  if (const auto *MD = dyn_cast<ObjCMethodDecl>(D)) {
+    if (MD->hasBody())
+      return None;
+    return AttributeInsertion::createInsertionAfter(D);
+  }
+  if (const auto *TD = dyn_cast<TagDecl>(D)) {
+    SourceLocation Loc =
+        Lexer::getLocForEndOfToken(TD->getInnerLocStart(), 0, SM, LangOpts);
+    if (Loc.isInvalid())
+      return None;
+    // Insert after the 'struct'/whatever keyword.
+    return AttributeInsertion::createInsertionAfter(Loc);
+  }
+  return AttributeInsertion::createInsertionBefore(D);
+}
+
 /// Actually emit an availability diagnostic for a reference to an unavailable
 /// decl.
 ///
@@ -7192,8 +7765,29 @@
               << /*Anonymous*/1 << TD->getKindName();
           return;
         }
-      S.Diag(Enclosing->getLocation(), diag::note_partial_availability_silence)
-          << /*Named*/0 << Enclosing;
+      auto FixitNoteDiag = S.Diag(Enclosing->getLocation(),
+                                  diag::note_partial_availability_silence)
+                           << /*Named*/ 0 << Enclosing;
+      // Don't offer a fixit for declarations with availability attributes.
+      if (Enclosing->hasAttr<AvailabilityAttr>())
+        return;
+      if (!S.getPreprocessor().isMacroDefined("API_AVAILABLE"))
+        return;
+      Optional<AttributeInsertion> Insertion = createAttributeInsertion(
+          Enclosing, S.getSourceManager(), S.getLangOpts());
+      if (!Insertion)
+        return;
+      std::string PlatformName =
+          AvailabilityAttr::getPlatformNameSourceSpelling(
+              S.getASTContext().getTargetInfo().getPlatformName())
+              .lower();
+      std::string Introduced =
+          OffendingDecl->getVersionIntroduced().getAsString();
+      FixitNoteDiag << FixItHint::CreateInsertion(
+          Insertion->Loc,
+          (llvm::Twine(Insertion->Prefix) + "API_AVAILABLE(" + PlatformName +
+           "(" + Introduced + "))" + Insertion->Suffix)
+              .str());
     }
 }
 
@@ -7581,8 +8175,7 @@
     // If we're using the '*' case here or if this check is redundant, then we
     // use the enclosing version to check both branches.
     if (CondVersion.empty() || CondVersion <= AvailabilityStack.back())
-      return Base::TraverseStmt(If->getThen()) &&
-             Base::TraverseStmt(If->getElse());
+      return TraverseStmt(If->getThen()) && TraverseStmt(If->getElse());
   } else {
     // This isn't an availability checking 'if', we can just continue.
     return Base::TraverseIfStmt(If);
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index c05e5f0..081864c 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -5726,53 +5726,6 @@
   }
 }
 
-/// Determine whether a type is permitted to be passed or returned in
-/// registers, per C++ [class.temporary]p3.
-static bool computeCanPassInRegisters(Sema &S, CXXRecordDecl *D) {
-  if (D->isDependentType() || D->isInvalidDecl())
-    return false;
-
-  // Per C++ [class.temporary]p3, the relevant condition is:
-  //   each copy constructor, move constructor, and destructor of X is
-  //   either trivial or deleted, and X has at least one non-deleted copy
-  //   or move constructor
-  bool HasNonDeletedCopyOrMove = false;
-
-  if (D->needsImplicitCopyConstructor() &&
-      !D->defaultedCopyConstructorIsDeleted()) {
-    if (!D->hasTrivialCopyConstructor())
-      return false;
-    HasNonDeletedCopyOrMove = true; 
-  }
-
-  if (S.getLangOpts().CPlusPlus11 && D->needsImplicitMoveConstructor() &&
-      !D->defaultedMoveConstructorIsDeleted()) {
-    if (!D->hasTrivialMoveConstructor())
-      return false;
-    HasNonDeletedCopyOrMove = true;
-  }
-
-  if (D->needsImplicitDestructor() && !D->defaultedDestructorIsDeleted() &&
-      !D->hasTrivialDestructor())
-    return false;
-
-  for (const CXXMethodDecl *MD : D->methods()) {
-    if (MD->isDeleted())
-      continue;
-
-    auto *CD = dyn_cast<CXXConstructorDecl>(MD);
-    if (CD && CD->isCopyOrMoveConstructor())
-      HasNonDeletedCopyOrMove = true;
-    else if (!isa<CXXDestructorDecl>(MD))
-      continue;
-
-    if (!MD->isTrivial())
-      return false;
-  }
-
-  return HasNonDeletedCopyOrMove;
-}
-
 /// \brief Perform semantic checks on a class definition that has been
 /// completing, introducing implicitly-declared members, checking for
 /// abstract types, etc.
@@ -5917,8 +5870,6 @@
   }
 
   checkClassLevelDLLAttribute(Record);
-
-  Record->setCanPassInRegisters(computeCanPassInRegisters(*this, Record));
 }
 
 /// Look up the special member function that would be called by a special
@@ -7545,7 +7496,8 @@
               reinterpret_cast<Decl**>(FieldCollector->getCurFields()),
               FieldCollector->getCurNumFields()), LBrac, RBrac, AttrList);
 
-  CheckCompletedCXXClass(dyn_cast_or_null<CXXRecordDecl>(TagDecl));
+  CheckCompletedCXXClass(
+                        dyn_cast_or_null<CXXRecordDecl>(TagDecl));
 }
 
 /// AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared
@@ -8514,6 +8466,7 @@
   
   ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
   AddPragmaAttributes(DeclRegionScope, Namespc);
+  ProcessAPINotes(Namespc);
 
   // FIXME: Should we be merging attributes?
   if (const VisibilityAttr *Attr = Namespc->getAttr<VisibilityAttr>())
@@ -8903,6 +8856,7 @@
 
   if (UDir)
     ProcessDeclAttributeList(S, UDir, AttrList);
+  ProcessAPINotes(UDir);
 
   return UDir;
 }
@@ -10001,6 +9955,7 @@
 
   ProcessDeclAttributeList(S, NewTD, AttrList);
   AddPragmaAttributes(S, NewTD);
+  ProcessAPINotes(NewTD);
 
   CheckTypedefForVariablyModifiedType(S, NewTD);
   Invalid |= NewTD->isInvalidDecl();
@@ -11977,10 +11932,8 @@
   Scope *S = getScopeForContext(ClassDecl);
   CheckImplicitSpecialMemberDeclaration(S, CopyConstructor);
 
-  if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor)) {
-    ClassDecl->setImplicitCopyConstructorIsDeleted();
+  if (ShouldDeleteSpecialMember(CopyConstructor, CXXCopyConstructor))
     SetDeclDeleted(CopyConstructor, ClassLoc);
-  }
 
   if (S)
     PushOnScopeChains(CopyConstructor, S, false);
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 9675730..b132381 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -20,6 +20,7 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/Basic/SourceManager.h"
+#include "clang/Edit/RefactoringFixits.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
@@ -1004,6 +1005,10 @@
   ObjCInterfaceDecl *IDecl
     = ObjCInterfaceDecl::Create(Context, CurContext, AtInterfaceLoc, ClassName,
                                 typeParamList, PrevIDecl, ClassLoc);
+  if (AttrList)
+    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+  ProcessAPINotes(IDecl);
+
   if (PrevIDecl) {
     // Class already seen. Was it a definition?
     if (ObjCInterfaceDecl *Def = PrevIDecl->getDefinition()) {
@@ -1014,8 +1019,6 @@
     }
   }
   
-  if (AttrList)
-    ProcessDeclAttributeList(TUScope, IDecl, AttrList);
   AddPragmaAttributes(TUScope, IDecl);
   PushOnScopeChains(IDecl, TUScope);
 
@@ -1116,7 +1119,8 @@
 
   // Everything checked out, instantiate a new alias declaration AST.
   ObjCCompatibleAliasDecl *AliasDecl =
-    ObjCCompatibleAliasDecl::Create(Context, CurContext, AtLoc, AliasName, CDecl);
+      ObjCCompatibleAliasDecl::Create(Context, CurContext, AliasLocation,
+                                      AliasName, CDecl, ClassLocation, AtLoc);
 
   if (!CheckObjCDeclScope(AliasDecl))
     PushOnScopeChains(AliasDecl, TUScope);
@@ -1201,6 +1205,7 @@
   if (AttrList)
     ProcessDeclAttributeList(TUScope, PDecl, AttrList);
   AddPragmaAttributes(TUScope, PDecl);
+  ProcessAPINotes(PDecl);
 
   // Merge attributes from previous declarations.
   if (PrevDecl)
@@ -1725,13 +1730,15 @@
       = ObjCProtocolDecl::Create(Context, CurContext, Ident, 
                                  IdentPair.second, AtProtocolLoc,
                                  PrevDecl);
-        
+    ProcessAPINotes(PDecl);
+
     PushOnScopeChains(PDecl, TUScope);
     CheckObjCDeclScope(PDecl);
     
     if (attrList)
       ProcessDeclAttributeList(TUScope, PDecl, attrList);
     AddPragmaAttributes(TUScope, PDecl);
+    ProcessAPINotes(PDecl);
 
     if (PrevDecl)
       mergeDeclAttributes(PDecl, PrevDecl);
@@ -2142,23 +2149,28 @@
     Diag(IVI->getLocation(), diag::err_inconsistent_ivar_count);
 }
 
-static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc,
-                                ObjCMethodDecl *method,
-                                bool &IncompleteImpl,
-                                unsigned DiagID,
-                                NamedDecl *NeededFor = nullptr) {
+static bool shouldWarnUndefinedMethod(const ObjCMethodDecl *M) {
   // No point warning no definition of method which is 'unavailable'.
-  switch (method->getAvailability()) {
+  switch (M->getAvailability()) {
   case AR_Available:
   case AR_Deprecated:
-    break;
+    return true;
 
-      // Don't warn about unavailable or not-yet-introduced methods.
+  // Don't warn about unavailable or not-yet-introduced methods.
   case AR_NotYetIntroduced:
   case AR_Unavailable:
-    return;
+    return false;
   }
-  
+  llvm_unreachable("Invalid availability");
+}
+
+static void WarnUndefinedMethod(Sema &S, SourceLocation ImpLoc,
+                                ObjCMethodDecl *method, bool &IncompleteImpl,
+                                unsigned DiagID,
+                                NamedDecl *NeededFor = nullptr) {
+  if (!shouldWarnUndefinedMethod(method))
+    return;
+
   // FIXME: For now ignore 'IncompleteImpl'.
   // Previously we grouped all unimplemented methods under a single
   // warning, but some users strongly voiced that they would prefer
@@ -2619,14 +2631,12 @@
 
 /// CheckProtocolMethodDefs - This routine checks unimplemented methods
 /// Declared in protocol, and those referenced by it.
-static void CheckProtocolMethodDefs(Sema &S,
-                                    SourceLocation ImpLoc,
-                                    ObjCProtocolDecl *PDecl,
-                                    bool& IncompleteImpl,
-                                    const Sema::SelectorSet &InsMap,
-                                    const Sema::SelectorSet &ClsMap,
-                                    ObjCContainerDecl *CDecl,
-                                    LazyProtocolNameSet &ProtocolsExplictImpl) {
+static void CheckProtocolMethodDefs(
+    Sema &S, SourceLocation ImpLoc, ObjCProtocolDecl *PDecl,
+    bool &IncompleteImpl, const Sema::SelectorSet &InsMap,
+    const Sema::SelectorSet &ClsMap, ObjCContainerDecl *CDecl,
+    LazyProtocolNameSet &ProtocolsExplictImpl,
+    llvm::SmallPtrSetImpl<ObjCProtocolDecl *> *MissingRequirements) {
   ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl);
   ObjCInterfaceDecl *IDecl = C ? C->getClassInterface() 
                                : dyn_cast<ObjCInterfaceDecl>(CDecl);
@@ -2686,6 +2696,7 @@
   // protocol. This lookup is slow, but occurs rarely in correct code
   // and otherwise would terminate in a warning.
 
+  bool HasMissingRequirements = false;
   // check unimplemented instance methods.
   if (!NSIDecl)
     for (auto *method : PDecl->instance_methods()) {
@@ -2715,8 +2726,13 @@
                 continue;
             unsigned DIAG = diag::warn_unimplemented_protocol_method;
             if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
-              WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG,
-                                  PDecl);
+              if (MissingRequirements) {
+                if (!HasMissingRequirements)
+                  HasMissingRequirements = shouldWarnUndefinedMethod(method);
+              } else {
+                WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG,
+                                    PDecl);
+              }
             }
           }
     }
@@ -2738,14 +2754,23 @@
 
       unsigned DIAG = diag::warn_unimplemented_protocol_method;
       if (!S.Diags.isIgnored(DIAG, ImpLoc)) {
-        WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl);
+        if (MissingRequirements) {
+          if (!HasMissingRequirements)
+            HasMissingRequirements = shouldWarnUndefinedMethod(method);
+        } else {
+          WarnUndefinedMethod(S, ImpLoc, method, IncompleteImpl, DIAG, PDecl);
+        }
       }
     }
   }
+  if (HasMissingRequirements) {
+    assert(MissingRequirements != nullptr && "No missing requirements!");
+    MissingRequirements->insert(PDecl);
+  }
   // Check on this protocols's referenced protocols, recursively.
   for (auto *PI : PDecl->protocols())
     CheckProtocolMethodDefs(S, ImpLoc, PI, IncompleteImpl, InsMap, ClsMap,
-                            CDecl, ProtocolsExplictImpl);
+                            CDecl, ProtocolsExplictImpl, MissingRequirements);
 }
 
 /// MatchAllMethodDeclarations - Check methods declared in interface
@@ -2957,23 +2982,49 @@
 
   LazyProtocolNameSet ExplicitImplProtocols;
 
+  bool UseEditorDiagnostics = !getDiagnostics()
+                                   .getDiagnosticOptions()
+                                   .DiagnosticSerializationFile.empty() ||
+                              getLangOpts().AllowEditorPlaceholders;
+  llvm::SmallPtrSet<ObjCProtocolDecl *, 4> MissingRequirements;
   if (ObjCInterfaceDecl *I = dyn_cast<ObjCInterfaceDecl> (CDecl)) {
     for (auto *PI : I->all_referenced_protocols())
       CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), PI, IncompleteImpl,
-                              InsMap, ClsMap, I, ExplicitImplProtocols);
+                              InsMap, ClsMap, I, ExplicitImplProtocols,
+                              UseEditorDiagnostics ? &MissingRequirements
+                                                   : nullptr);
   } else if (ObjCCategoryDecl *C = dyn_cast<ObjCCategoryDecl>(CDecl)) {
     // For extended class, unimplemented methods in its protocols will
     // be reported in the primary class.
     if (!C->IsClassExtension()) {
       for (auto *P : C->protocols())
-        CheckProtocolMethodDefs(*this, IMPDecl->getLocation(), P,
-                                IncompleteImpl, InsMap, ClsMap, CDecl,
-                                ExplicitImplProtocols);
+        CheckProtocolMethodDefs(
+            *this, IMPDecl->getLocation(), P, IncompleteImpl, InsMap, ClsMap,
+            CDecl, ExplicitImplProtocols,
+            UseEditorDiagnostics ? &MissingRequirements : nullptr);
       DiagnoseUnimplementedProperties(S, IMPDecl, CDecl,
                                       /*SynthesizeProperties=*/false);
     } 
   } else
     llvm_unreachable("invalid ObjCContainerDecl type.");
+  if (!MissingRequirements.empty()) {
+    {
+      auto DB = Diag(IMPDecl->getLocation(),
+                     diag::warn_class_does_not_conform_protocol)
+                << (isa<ObjCCategoryDecl>(CDecl) ? /*category=*/1 : /*class=*/0)
+                << CDecl << (unsigned)MissingRequirements.size();
+      unsigned NumProtocols = 0;
+      for (const auto *PD : MissingRequirements) {
+        DB << PD;
+        if (++NumProtocols > 3)
+          break;
+      }
+    }
+    auto DB =
+        Diag(IMPDecl->getLocation(), diag::note_add_missing_protocol_stubs);
+    edit::fillInMissingProtocolStubs::addMissingProtocolStubs(
+        Context, IMPDecl, [&](const FixItHint &Hint) { DB << Hint; });
+  }
 }
 
 Sema::DeclGroupPtrTy
@@ -3063,6 +3114,7 @@
                                   ClassName, TypeParams, PrevIDecl,
                                   IdentLocs[i]);
     IDecl->setAtEndRange(IdentLocs[i]);
+    ProcessAPINotes(IDecl);
 
     PushOnScopeChains(IDecl, TUScope);
     CheckObjCDeclScope(IDecl);
@@ -3863,7 +3915,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)
@@ -3958,12 +4010,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 
@@ -4463,6 +4513,7 @@
     // Apply the attributes to the parameter.
     ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
     AddPragmaAttributes(TUScope, Param);
+    ProcessAPINotes(Param);
 
     if (Param->hasAttr<BlocksAttr>()) {
       Diag(Param->getLocation(), diag::err_block_on_nonlocal);
@@ -4494,6 +4545,7 @@
   if (AttrList)
     ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
   AddPragmaAttributes(TUScope, ObjCMethod);
+  ProcessAPINotes(ObjCMethod);
 
   // Add the method now.
   const ObjCMethodDecl *PrevMethod = nullptr;
@@ -4549,7 +4601,7 @@
   }
 
   ResultTypeCompatibilityKind RTC
-    = CheckRelatedResultTypeCompatibility(*this, ObjCMethod, CurrentClass);
+    = checkRelatedResultTypeCompatibility(ObjCMethod, CurrentClass);
 
   CheckObjCMethodOverrides(ObjCMethod, CurrentClass, RTC);
 
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index d3d7d8b..9e09a2f 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -7396,6 +7396,14 @@
   return CheckAssignmentConstraints(LHSType, RHSPtr, K, /*ConvertRHS=*/false);
 }
 
+/// This helper function returns true if QT is a vector type that has element
+/// type ElementType.
+static bool isVector(QualType QT, QualType ElementType) {
+  if (const VectorType *VT = QT->getAs<VectorType>())
+    return VT->getElementType() == ElementType;
+  return false;
+}
+
 /// CheckAssignmentConstraints (C99 6.5.16) - This routine currently
 /// has code to accommodate several GCC extensions when type checking
 /// pointers. Here are some objectionable examples that GCC considers warnings:
@@ -8018,6 +8026,25 @@
   return false;
 }
 
+/// Convert vector E to a vector with the same number of elements but different
+/// element type.
+static ExprResult convertVector(Expr *E, QualType ElementType, Sema &S) {
+  const auto *VecTy = E->getType()->getAs<VectorType>();
+  assert(VecTy && "Expression E must be a vector");
+  QualType NewVecTy = S.Context.getVectorType(ElementType,
+                                              VecTy->getNumElements(),
+                                              VecTy->getVectorKind());
+
+  // Look through the implicit cast. Return the subexpression if its type is
+  // NewVecTy.
+  if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
+    if (ICE->getSubExpr()->getType() == NewVecTy)
+      return ICE->getSubExpr();
+
+  auto Cast = ElementType->isIntegerType() ? CK_IntegralCast : CK_FloatingCast;
+  return S.ImpCastExprToType(E, NewVecTy, Cast);
+}
+
 /// Test if a (constant) integer Int can be casted to another integer type
 /// IntTy without losing precision.
 static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
@@ -11233,6 +11260,69 @@
   return nullptr;
 }
 
+// This helper function promotes a binary operator's operands (which are of a
+// half vector type) to a vector of floats and then truncates the result to
+// a vector of either half or short.
+static ExprResult convertHalfVecBinOp(Sema &S, ExprResult LHS, ExprResult RHS,
+                                      BinaryOperatorKind Opc, QualType ResultTy,
+                                      ExprValueKind VK, ExprObjectKind OK,
+                                      bool IsCompAssign, SourceLocation OpLoc,
+                                      FPOptions FPFeatures) {
+  auto &Context = S.getASTContext();
+  assert((isVector(ResultTy, Context.HalfTy) ||
+          isVector(ResultTy, Context.ShortTy)) &&
+         "Result must be a vector of half or short");
+  assert(isVector(LHS.get()->getType(), Context.HalfTy) &&
+         isVector(RHS.get()->getType(), Context.HalfTy) &&
+         "both operands expected to be a half vector");
+
+  RHS = convertVector(RHS.get(), Context.FloatTy, S);
+  QualType BinOpResTy = RHS.get()->getType();
+
+  // If Opc is a comparison, ResultType is a vector of shorts. In that case,
+  // change BinOpResTy to a vector of ints.
+  if (isVector(ResultTy, Context.ShortTy))
+    BinOpResTy = S.GetSignedVectorType(BinOpResTy);
+
+  if (IsCompAssign)
+    return new (Context) CompoundAssignOperator(
+        LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, BinOpResTy, BinOpResTy,
+        OpLoc, FPFeatures);
+
+  LHS = convertVector(LHS.get(), Context.FloatTy, S);
+  auto *BO = new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, BinOpResTy,
+                                          VK, OK, OpLoc, FPFeatures);
+  return convertVector(BO, ResultTy->getAs<VectorType>()->getElementType(), S);
+}
+
+static std::pair<ExprResult, ExprResult>
+CorrectDelayedTyposInBinOp(Sema &S, BinaryOperatorKind Opc, Expr *LHSExpr,
+                           Expr *RHSExpr) {
+  ExprResult LHS = LHSExpr, RHS = RHSExpr;
+  if (!S.getLangOpts().CPlusPlus) {
+    // C cannot handle TypoExpr nodes on either side of a binop because it
+    // doesn't handle dependent types properly, so make sure any TypoExprs have
+    // been dealt with before checking the operands.
+    LHS = S.CorrectDelayedTyposInExpr(LHS);
+    RHS = S.CorrectDelayedTyposInExpr(RHS, [Opc, LHS](Expr *E) {
+      if (Opc != BO_Assign)
+        return ExprResult(E);
+      // Avoid correcting the RHS to the same Expr as the LHS.
+      Decl *D = getDeclFromExpr(E);
+      return (D && D == getDeclFromExpr(LHS.get())) ? ExprError() : E;
+    });
+  }
+  return std::make_pair(LHS, RHS);
+}
+
+/// Returns true if conversion between vectors of halfs and vectors of floats
+/// is needed.
+static bool needsConversionOfHalfVec(bool OpRequiresConversion, ASTContext &Ctx,
+                                     QualType SrcType) {
+  return OpRequiresConversion && !Ctx.getLangOpts().NativeHalfType &&
+         Ctx.getLangOpts().HalfArgsAndReturns && isVector(SrcType, Ctx.HalfTy);
+}
+
 /// CreateBuiltinBinOp - Creates a new built-in binary operation with
 /// operator @p Opc at location @c TokLoc. This routine only supports
 /// built-in operations; ActOnBinOp handles overloaded operators.
@@ -11264,22 +11354,11 @@
   QualType CompResultTy; // Type of computation result
   ExprValueKind VK = VK_RValue;
   ExprObjectKind OK = OK_Ordinary;
+  bool ConvertHalfVec = false;
 
-  if (!getLangOpts().CPlusPlus) {
-    // C cannot handle TypoExpr nodes on either side of a binop because it
-    // doesn't handle dependent types properly, so make sure any TypoExprs have
-    // been dealt with before checking the operands.
-    LHS = CorrectDelayedTyposInExpr(LHSExpr);
-    RHS = CorrectDelayedTyposInExpr(RHSExpr, [Opc, LHS](Expr *E) {
-      if (Opc != BO_Assign)
-        return ExprResult(E);
-      // Avoid correcting the RHS to the same Expr as the LHS.
-      Decl *D = getDeclFromExpr(E);
-      return (D && D == getDeclFromExpr(LHS.get())) ? ExprError() : E;
-    });
-    if (!LHS.isUsable() || !RHS.isUsable())
-      return ExprError();
-  }
+  std::tie(LHS, RHS) = CorrectDelayedTyposInBinOp(*this, Opc, LHSExpr, RHSExpr);
+  if (!LHS.isUsable() || !RHS.isUsable())
+    return ExprError();
 
   if (getLangOpts().OpenCL) {
     QualType LHSTy = LHSExpr->getType();
@@ -11327,6 +11406,7 @@
     break;
   case BO_Mul:
   case BO_Div:
+    ConvertHalfVec = true;
     ResultTy = CheckMultiplyDivideOperands(LHS, RHS, OpLoc, false,
                                            Opc == BO_Div);
     break;
@@ -11334,9 +11414,11 @@
     ResultTy = CheckRemainderOperands(LHS, RHS, OpLoc);
     break;
   case BO_Add:
+    ConvertHalfVec = true;
     ResultTy = CheckAdditionOperands(LHS, RHS, OpLoc, Opc);
     break;
   case BO_Sub:
+    ConvertHalfVec = true;
     ResultTy = CheckSubtractionOperands(LHS, RHS, OpLoc);
     break;
   case BO_Shl:
@@ -11347,10 +11429,12 @@
   case BO_LT:
   case BO_GE:
   case BO_GT:
+    ConvertHalfVec = true;
     ResultTy = CheckCompareOperands(LHS, RHS, OpLoc, Opc, true);
     break;
   case BO_EQ:
   case BO_NE:
+    ConvertHalfVec = true;
     ResultTy = CheckCompareOperands(LHS, RHS, OpLoc, Opc, false);
     break;
   case BO_And:
@@ -11362,10 +11446,12 @@
     break;
   case BO_LAnd:
   case BO_LOr:
+    ConvertHalfVec = true;
     ResultTy = CheckLogicalOperands(LHS, RHS, OpLoc, Opc);
     break;
   case BO_MulAssign:
   case BO_DivAssign:
+    ConvertHalfVec = true;
     CompResultTy = CheckMultiplyDivideOperands(LHS, RHS, OpLoc, true,
                                                Opc == BO_DivAssign);
     CompLHSTy = CompResultTy;
@@ -11379,11 +11465,13 @@
       ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, CompResultTy);
     break;
   case BO_AddAssign:
+    ConvertHalfVec = true;
     CompResultTy = CheckAdditionOperands(LHS, RHS, OpLoc, Opc, &CompLHSTy);
     if (!CompResultTy.isNull() && !LHS.isInvalid() && !RHS.isInvalid())
       ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, CompResultTy);
     break;
   case BO_SubAssign:
+    ConvertHalfVec = true;
     CompResultTy = CheckSubtractionOperands(LHS, RHS, OpLoc, &CompLHSTy);
     if (!CompResultTy.isNull() && !LHS.isInvalid() && !RHS.isInvalid())
       ResultTy = CheckAssignmentOperands(LHS.get(), RHS, OpLoc, CompResultTy);
@@ -11416,6 +11504,16 @@
   if (ResultTy.isNull() || LHS.isInvalid() || RHS.isInvalid())
     return ExprError();
 
+  // Some of the binary operations require promoting operands of half vector to
+  // float vectors and truncating the result back to half vector. For now, we do
+  // this only when HalfArgsAndReturn is set (that is, when the target is arm or
+  // arm64).
+  assert(isVector(RHS.get()->getType(), Context.HalfTy) ==
+         isVector(LHS.get()->getType(), Context.HalfTy) &&
+         "both sides are half vectors or neither sides are");
+  ConvertHalfVec = needsConversionOfHalfVec(ConvertHalfVec, Context,
+                                            LHS.get()->getType());
+
   // Check for array bounds violations for both sides of the BinaryOperator
   CheckArrayAccess(LHS.get());
   CheckArrayAccess(RHS.get());
@@ -11438,14 +11536,26 @@
            dyn_cast<ObjCIvarRefExpr>(LHS.get()->IgnoreParenCasts()))
     DiagnoseDirectIsaAccess(*this, OIRE, OpLoc, RHS.get());
   
-  if (CompResultTy.isNull())
+  // Opc is not a compound assignment if CompResultTy is null.
+  if (CompResultTy.isNull()) {
+    if (ConvertHalfVec)
+      return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, false,
+                                 OpLoc, FPFeatures);
     return new (Context) BinaryOperator(LHS.get(), RHS.get(), Opc, ResultTy, VK,
                                         OK, OpLoc, FPFeatures);
+  }
+
+  // Handle compound assignments.
   if (getLangOpts().CPlusPlus && LHS.get()->getObjectKind() !=
       OK_ObjCProperty) {
     VK = VK_LValue;
     OK = LHS.get()->getObjectKind();
   }
+
+  if (ConvertHalfVec)
+    return convertHalfVecBinOp(*this, LHS, RHS, Opc, ResultTy, VK, OK, true,
+                               OpLoc, FPFeatures);
+
   return new (Context) CompoundAssignOperator(
       LHS.get(), RHS.get(), Opc, ResultTy, VK, OK, CompLHSTy, CompResultTy,
       OpLoc, FPFeatures);
@@ -11693,6 +11803,13 @@
 ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
                             BinaryOperatorKind Opc,
                             Expr *LHSExpr, Expr *RHSExpr) {
+  ExprResult LHS, RHS;
+  std::tie(LHS, RHS) = CorrectDelayedTyposInBinOp(*this, Opc, LHSExpr, RHSExpr);
+  if (!LHS.isUsable() || !RHS.isUsable())
+    return ExprError();
+  LHSExpr = LHS.get();
+  RHSExpr = RHS.get();
+
   // We want to end up calling one of checkPseudoObjectAssignment
   // (if the LHS is a pseudo-object), BuildOverloadedBinOp (if
   // both expressions are overloadable or either is type-dependent),
@@ -11796,6 +11913,7 @@
   ExprValueKind VK = VK_RValue;
   ExprObjectKind OK = OK_Ordinary;
   QualType resultType;
+  bool ConvertHalfVec = false;
   if (getLangOpts().OpenCL) {
     QualType Ty = InputExpr->getType();
     // The only legal unary operation for atomics is '&'.
@@ -11835,6 +11953,16 @@
   case UO_Minus:
     Input = UsualUnaryConversions(Input.get());
     if (Input.isInvalid()) return ExprError();
+    // Unary plus and minus require promoting an operand of half vector to a
+    // float vector and truncating the result back to a half vector. For now, we
+    // do this only when HalfArgsAndReturns is set (that is, when the target is
+    // arm or arm64).
+    ConvertHalfVec =
+        needsConversionOfHalfVec(true, Context, Input.get()->getType());
+
+    // If the operand is a half vector, promote it to a float vector.
+    if (ConvertHalfVec)
+      Input = convertVector(Input.get(), Context.FloatTy, *this);
     resultType = Input.get()->getType();
     if (resultType->isDependentType())
       break;
@@ -11972,8 +12100,12 @@
   if (Opc != UO_AddrOf && Opc != UO_Deref)
     CheckArrayAccess(Input.get());
 
-  return new (Context)
+  auto *UO = new (Context)
       UnaryOperator(Input.get(), Opc, resultType, VK, OK, OpLoc);
+  // Convert the result back to a half vector.
+  if (ConvertHalfVec)
+    return convertVector(UO, Context.HalfTy, *this);
+  return UO;
 }
 
 /// \brief Determine whether the given expression is a qualified member
@@ -13997,6 +14129,8 @@
     Field->setImplicit(true);
     Field->setAccess(AS_private);
     RD->addDecl(Field);
+    if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP)
+      S.setOpenMPCaptureKind(Field, Var, RSI->OpenMPLevel);
  
     CopyExpr = new (S.Context) DeclRefExpr(Var, RefersToCapturedVariable,
                                             DeclRefType, VK_LValue, Loc);
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index a9cf3ec..9c0bd6f 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -24,6 +24,7 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/Basic/AlignedAllocation.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Lex/Preprocessor.h"
@@ -1660,9 +1661,13 @@
 
   bool IsAligned = false;
   if (FD.isReplaceableGlobalAllocationFunction(&IsAligned) && IsAligned) {
+    const llvm::Triple &T = S.getASTContext().getTargetInfo().getTriple();
+    StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling(
+        S.getASTContext().getTargetInfo().getPlatformName());
+
     S.Diag(Loc, diag::warn_aligned_allocation_unavailable)
-         << IsDelete << FD.getType().getAsString()
-         << S.getASTContext().getTargetInfo().getTriple().str();
+         << IsDelete << FD.getType().getAsString() << OSName
+         << alignedAllocMinVersion(T.getOS()).getAsString();
     S.Diag(Loc, diag::note_silence_unligned_allocation_unavailable);
   }
 }
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index 28581ba..43ac6f1 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -4319,7 +4319,7 @@
   // problems here.  To catch them all, we'd need to rebuild arbitrary
   // value-propagating subexpressions --- we can't reliably rebuild
   // in-place because of expression sharing.
-  if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
+  if (auto *ice = dyn_cast<ImplicitCastExpr>(e->IgnoreParens()))
     if (ice->getCastKind() == CK_ARCReclaimReturnedObject)
       return ice->getSubExpr();
 
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index bfb0071..7192987 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -644,8 +644,6 @@
     PDecl->setInvalidDecl();
   }
 
-  ProcessDeclAttributes(S, PDecl, FD.D);
-
   // Regardless of setter/getter attribute, we save the default getter/setter
   // selector names in anticipation of declaration of setter/getter methods.
   PDecl->setGetterName(GetterSel, GetterNameLoc);
@@ -653,6 +651,8 @@
   PDecl->setPropertyAttributesAsWritten(
                           makePropertyAttributesAsWritten(AttributesAsWritten));
 
+  ProcessDeclAttributes(S, PDecl, FD.D);
+
   if (Attributes & ObjCDeclSpec::DQ_PR_readonly)
     PDecl->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_readonly);
 
@@ -1895,7 +1895,7 @@
                             /* property = */ Prop->getIdentifier(),
                             /* ivar = */ Prop->getDefaultSynthIvarName(Context),
                             Prop->getLocation(), Prop->getQueryKind()));
-    if (PIDecl) {
+    if (PIDecl && !Prop->isUnavailable()) {
       Diag(Prop->getLocation(), diag::warn_missing_explicit_synthesis);
       Diag(IMPDecl->getLocation(), diag::note_while_in_implementation);
     }
@@ -2394,6 +2394,8 @@
           SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section,
                                       SA->getName(), Loc));
 
+    ProcessAPINotes(GetterMethod);
+
     if (getLangOpts().ObjCAutoRefCount)
       CheckARCMethodDecl(GetterMethod);
   } else
@@ -2459,6 +2461,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/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 01f574b..30b1086 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -1139,6 +1139,39 @@
       D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level);
 }
 
+void Sema::setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level) {
+  assert(LangOpts.OpenMP && "OpenMP is not allowed");
+  D = getCanonicalDecl(D);
+  OpenMPClauseKind OMPC = OMPC_unknown;
+  for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
+    const unsigned NewLevel = I - 1;
+    if (DSAStack->hasExplicitDSA(D,
+                                 [&OMPC](const OpenMPClauseKind K) {
+                                   if (isOpenMPPrivate(K)) {
+                                     OMPC = K;
+                                     return true;
+                                   }
+                                   return false;
+                                 },
+                                 NewLevel))
+      break;
+    if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
+            D, NewLevel,
+            [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
+               OpenMPClauseKind) { return true; })) {
+      OMPC = OMPC_map;
+      break;
+    }
+    if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
+                                       NewLevel)) {
+      OMPC = OMPC_firstprivate;
+      break;
+    }
+  }
+  if (OMPC != OMPC_unknown)
+    FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
+}
+
 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) {
   assert(LangOpts.OpenMP && "OpenMP is not allowed");
   // Return true if the current level is no longer enclosed in a target region.
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 2a38a1f..e89b26c 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -11,11 +11,10 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Sema/SemaInternal.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/ASTDiagnostic.h"
-#include "clang/AST/CharUnits.h"
 #include "clang/AST/CXXInheritance.h"
+#include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/ExprCXX.h"
@@ -26,11 +25,13 @@
 #include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeOrdering.h"
 #include "clang/Basic/TargetInfo.h"
+#include "clang/Edit/RefactoringFixits.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Scope.h"
 #include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/SemaInternal.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/STLExtras.h"
@@ -1160,14 +1161,22 @@
 
       // Produce a nice diagnostic if multiple values aren't handled.
       if (!UnhandledNames.empty()) {
-        DiagnosticBuilder DB = Diag(CondExpr->getExprLoc(),
-                                    TheDefaultStmt ? diag::warn_def_missing_case
-                                                   : diag::warn_missing_case)
-                               << (int)UnhandledNames.size();
+        {
+          DiagnosticBuilder DB =
+              Diag(CondExpr->getExprLoc(), TheDefaultStmt
+                                               ? diag::warn_def_missing_case
+                                               : diag::warn_missing_case)
+              << (int)UnhandledNames.size();
 
-        for (size_t I = 0, E = std::min(UnhandledNames.size(), (size_t)3);
-             I != E; ++I)
-          DB << UnhandledNames[I];
+          for (size_t I = 0, E = std::min(UnhandledNames.size(), (size_t)3);
+               I != E; ++I)
+            DB << UnhandledNames[I];
+        }
+        auto DB =
+            Diag(CondExpr->getExprLoc(), diag::note_fill_in_missing_cases);
+        edit::fillInMissingSwitchEnumCases(
+            Context, SS, ED, CurContext,
+            [&](const FixItHint &Hint) { DB << Hint; });
       }
 
       if (!hasCasesNotInSwitch)
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index e9b3855..9b99f6a 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1449,6 +1449,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, NewClass, Attr);
+  ProcessAPINotes(NewClass);
 
   if (PrevClassTemplate)
     mergeDeclAttributes(NewClass, PrevClassTemplate->getTemplatedDecl());
@@ -7575,6 +7576,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.
@@ -8627,6 +8629,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
@@ -9055,6 +9058,7 @@
         // Merge attributes.
         if (AttributeList *Attr = D.getDeclSpec().getAttributes().getList())
           ProcessDeclAttributeList(S, Prev, Attr);
+        ProcessAPINotes(Prev);
       }
       if (TSK == TSK_ExplicitInstantiationDefinition)
         InstantiateVariableDefinition(D.getIdentifierLoc(), Prev);
@@ -9220,6 +9224,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 f4f0c80..643e018 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2030,12 +2030,11 @@
   bool MergeWithParentScope = !Instantiation->isDefinedOutsideFunctionOrMethod();
   LocalInstantiationScope Scope(*this, MergeWithParentScope);
 
-  // All dllexported classes created during instantiation should be fully
-  // emitted after instantiation completes. We may not be ready to emit any
-  // delayed classes already on the stack, so save them away and put them back
-  // later.
-  decltype(DelayedDllExportClasses) ExportedClasses;
-  std::swap(ExportedClasses, DelayedDllExportClasses);
+  // Some class state isn't processed immediately but delayed till class
+  // instantiation completes. We may not be ready to handle any delayed state
+  // already on the stack as it might correspond to a different class, so save
+  // it now and put it back later.
+  SavePendingParsedClassStateRAII SavedPendingParsedClassState(*this);
 
   // Pull attributes from the pattern onto the instantiation.
   InstantiateAttrs(TemplateArgs, Pattern, Instantiation);
@@ -2122,9 +2121,6 @@
   // default arg exprs for default constructors if necessary now.
   ActOnFinishCXXNonNestedClass(Instantiation);
 
-  // Put back the delayed exported classes that we moved out of the way.
-  std::swap(ExportedClasses, DelayedDllExportClasses);
-
   // Instantiate late parsed attributes, and attach them to their decls.
   // See Sema::InstantiateAttrs
   for (LateInstantiatedAttrVec::iterator I = LateAttrs.begin(),
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 598a113..62cdb6c 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -1157,20 +1157,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.
@@ -3381,25 +3367,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;
@@ -3423,6 +3393,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
@@ -6053,12 +6043,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;
@@ -6067,6 +6079,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);
@@ -6074,11 +6089,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();
@@ -6089,7 +6109,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);
@@ -6114,15 +6134,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();
@@ -6151,13 +6172,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() 
@@ -6926,7 +6940,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 91da9f8..a8b4c7a 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -6585,8 +6585,7 @@
 
   // Rebuild the switch statement.
   StmtResult Switch
-    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(),
-                                          S->getInit(), Cond);
+    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Init.get(), Cond);
   if (Switch.isInvalid())
     return StmtError();
 
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 50be74f..a1c3272 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -4908,6 +4908,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++];
@@ -4955,6 +4956,7 @@
       CurrentModule->IsFromModuleFile = true;
       CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
       CurrentModule->IsExternC = IsExternC;
+      CurrentModule->IsSwiftInferImportAsMember = IsSwiftInferImportAsMember;
       CurrentModule->InferSubmodules = InferSubmodules;
       CurrentModule->InferExplicitSubmodules = InferExplicitSubmodules;
       CurrentModule->InferExportWildcard = InferExportWildcard;
@@ -5109,7 +5111,7 @@
       break;
     }
 
-    case SUBMODULE_INITIALIZERS:
+    case SUBMODULE_INITIALIZERS: {
       if (!ContextObj)
         break;
       SmallVector<uint32_t, 16> Inits;
@@ -5118,6 +5120,11 @@
       ContextObj->addLazyModuleInitializers(CurrentModule, Inits);
       break;
     }
+
+    case SUBMODULE_EXPORT_AS:
+      CurrentModule->ExportAsModule = Blob.str();
+      break;
+    }
   }
 }
 
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 0853415..93b5e20 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -1157,6 +1157,8 @@
 void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
   VisitNamedDecl(CAD);
   CAD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>());
+  CAD->setClassInterfaceLoc(ReadSourceLocation());
+  CAD->setAtLoc(ReadSourceLocation());
 }
 
 void ASTDeclReader::VisitObjCPropertyDecl(ObjCPropertyDecl *D) {
@@ -1559,11 +1561,9 @@
   Data.HasUninitializedFields = Record.readInt();
   Data.HasInheritedConstructor = Record.readInt();
   Data.HasInheritedAssignment = Record.readInt();
-  Data.NeedOverloadResolutionForCopyConstructor = Record.readInt();
   Data.NeedOverloadResolutionForMoveConstructor = Record.readInt();
   Data.NeedOverloadResolutionForMoveAssignment = Record.readInt();
   Data.NeedOverloadResolutionForDestructor = Record.readInt();
-  Data.DefaultedCopyConstructorIsDeleted = Record.readInt();
   Data.DefaultedMoveConstructorIsDeleted = Record.readInt();
   Data.DefaultedMoveAssignmentIsDeleted = Record.readInt();
   Data.DefaultedDestructorIsDeleted = Record.readInt();
@@ -1572,7 +1572,6 @@
   Data.HasIrrelevantDestructor = Record.readInt();
   Data.HasConstexprNonCopyMoveConstructor = Record.readInt();
   Data.HasDefaultedDefaultConstructor = Record.readInt();
-  Data.CanPassInRegisters = Record.readInt();
   Data.DefaultedDefaultConstructorIsConstexpr = Record.readInt();
   Data.HasConstexprDefaultConstructor = Record.readInt();
   Data.HasNonLiteralTypeFieldsOrBases = Record.readInt();
@@ -1700,11 +1699,9 @@
   MATCH_FIELD(HasUninitializedFields)
   MATCH_FIELD(HasInheritedConstructor)
   MATCH_FIELD(HasInheritedAssignment)
-  MATCH_FIELD(NeedOverloadResolutionForCopyConstructor)
   MATCH_FIELD(NeedOverloadResolutionForMoveConstructor)
   MATCH_FIELD(NeedOverloadResolutionForMoveAssignment)
   MATCH_FIELD(NeedOverloadResolutionForDestructor)
-  MATCH_FIELD(DefaultedCopyConstructorIsDeleted)
   MATCH_FIELD(DefaultedMoveConstructorIsDeleted)
   MATCH_FIELD(DefaultedMoveAssignmentIsDeleted)
   MATCH_FIELD(DefaultedDestructorIsDeleted)
@@ -1713,7 +1710,6 @@
   MATCH_FIELD(HasIrrelevantDestructor)
   OR_FIELD(HasConstexprNonCopyMoveConstructor)
   OR_FIELD(HasDefaultedDefaultConstructor)
-  MATCH_FIELD(CanPassInRegisters)
   MATCH_FIELD(DefaultedDefaultConstructorIsConstexpr)
   OR_FIELD(HasConstexprDefaultConstructor)
   MATCH_FIELD(HasNonLiteralTypeFieldsOrBases)
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 128e53b..07ad0db 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -1130,6 +1130,7 @@
   RECORD(SUBMODULE_TEXTUAL_HEADER);
   RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER);
   RECORD(SUBMODULE_INITIALIZERS);
+  RECORD(SUBMODULE_EXPORT_AS);
 
   // Comments Block.
   BLOCK(COMMENTS_BLOCK);
@@ -2719,6 +2720,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...
@@ -2789,6 +2791,11 @@
   Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));    // Message
   unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
 
+  Abbrev = std::make_shared<BitCodeAbbrev>();
+  Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_EXPORT_AS));
+  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));    // Macro name
+  unsigned ExportAsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
+
   // Write the submodule metadata block.
   RecordData::value_type Record[] = {
       getNumberOfModules(WritingModule),
@@ -2819,6 +2826,7 @@
                                          Mod->IsExplicit,
                                          Mod->IsSystem,
                                          Mod->IsExternC,
+                                         Mod->IsSwiftInferImportAsMember,
                                          Mod->InferSubmodules,
                                          Mod->InferExplicitSubmodules,
                                          Mod->InferExportWildcard,
@@ -2923,6 +2931,12 @@
     if (!Inits.empty())
       Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits);
 
+    // Emit the name of the re-exported module, if any.
+    if (!Mod->ExportAsModule.empty()) {
+      RecordData::value_type Record[] = {SUBMODULE_EXPORT_AS};
+      Stream.EmitRecordWithBlob(ExportAsAbbrev, Record, Mod->ExportAsModule);
+    }
+    
     // Queue up the submodules of this module.
     for (auto *M : Mod->submodules())
       Q.push(M);
@@ -5874,11 +5888,9 @@
   Record->push_back(Data.HasUninitializedFields);
   Record->push_back(Data.HasInheritedConstructor);
   Record->push_back(Data.HasInheritedAssignment);
-  Record->push_back(Data.NeedOverloadResolutionForCopyConstructor);
   Record->push_back(Data.NeedOverloadResolutionForMoveConstructor);
   Record->push_back(Data.NeedOverloadResolutionForMoveAssignment);
   Record->push_back(Data.NeedOverloadResolutionForDestructor);
-  Record->push_back(Data.DefaultedCopyConstructorIsDeleted);
   Record->push_back(Data.DefaultedMoveConstructorIsDeleted);
   Record->push_back(Data.DefaultedMoveAssignmentIsDeleted);
   Record->push_back(Data.DefaultedDestructorIsDeleted);
@@ -5887,7 +5899,6 @@
   Record->push_back(Data.HasIrrelevantDestructor);
   Record->push_back(Data.HasConstexprNonCopyMoveConstructor);
   Record->push_back(Data.HasDefaultedDefaultConstructor);
-  Record->push_back(Data.CanPassInRegisters);
   Record->push_back(Data.DefaultedDefaultConstructorIsConstexpr);
   Record->push_back(Data.HasConstexprDefaultConstructor);
   Record->push_back(Data.HasNonLiteralTypeFieldsOrBases);
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index ec21ca2..65aed14 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -784,6 +784,8 @@
 void ASTDeclWriter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) {
   VisitNamedDecl(D);
   Record.AddDeclRef(D->getClassInterface());
+  Record.AddSourceLocation(D->getClassInterfaceLoc());
+  Record.AddSourceLocation(D->getAtLoc());
   Code = serialization::DECL_OBJC_COMPATIBLE_ALIAS;
 }
 
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/Tooling/CMakeLists.txt b/lib/Tooling/CMakeLists.txt
index 7b0c58e..3321450 100644
--- a/lib/Tooling/CMakeLists.txt
+++ b/lib/Tooling/CMakeLists.txt
@@ -4,6 +4,7 @@
   )
 
 add_subdirectory(Core)
+add_subdirectory(Refactor)
 add_subdirectory(Refactoring)
 
 add_clang_library(clangTooling
@@ -30,4 +31,6 @@
   clangLex
   clangRewrite
   clangToolingCore
+  clangToolingRefactor
+  clangToolingRefactoring
   )
diff --git a/lib/Tooling/Refactor/ASTSlice.cpp b/lib/Tooling/Refactor/ASTSlice.cpp
new file mode 100644
index 0000000..5447571
--- /dev/null
+++ b/lib/Tooling/Refactor/ASTSlice.cpp
@@ -0,0 +1,625 @@
+//===--- ASTSlice.cpp - Represents a portion of the AST -------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ASTSlice.h"
+#include "SourceLocationUtilities.h"
+#include "StmtUtils.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/SourceManager.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/SaveAndRestore.h"
+#include <algorithm>
+
+using namespace clang;
+using namespace clang::tooling;
+
+namespace {
+
+/// Searches for AST nodes around the given source location and range that can
+/// be used to initiate a refactoring operation.
+class ASTSliceFinder : public clang::RecursiveASTVisitor<ASTSliceFinder> {
+public:
+  explicit ASTSliceFinder(SourceLocation Location, SourceRange SelectionRange,
+                          const ASTContext &Context)
+      : Location(Location), SelectionRange(SelectionRange), Context(Context) {}
+
+  bool TraverseDecl(Decl *D) {
+    if (!D)
+      return true;
+    if (isa<DeclContext>(D) && !D->isImplicit())
+      collectDeclIfInRange(D);
+    // TODO: Handle Lambda/Blocks.
+    if (!isa<FunctionDecl>(D) && !isa<ObjCMethodDecl>(D)) {
+      RecursiveASTVisitor::TraverseDecl(D);
+      return true;
+    }
+    const Decl *PreviousDecl = CurrentDecl;
+    CurrentDecl = D;
+    RecursiveASTVisitor::TraverseDecl(D);
+    CurrentDecl = PreviousDecl;
+    return true;
+  }
+
+  bool TraverseStmt(Stmt *S) {
+    if (!S)
+      return true;
+    // PseudoObjectExpressions don't have to be parents.
+    if (isa<PseudoObjectExpr>(S))
+      return RecursiveASTVisitor::TraverseStmt(S);
+    llvm::SaveAndRestore<const Stmt *> Parent(ParentStmt, CurrentStmt);
+    llvm::SaveAndRestore<const Stmt *> Current(CurrentStmt, S);
+    RecursiveASTVisitor::TraverseStmt(S);
+    return true;
+  }
+
+  bool TraversePseudoObjectExpr(PseudoObjectExpr *E) {
+    // Avoid traversing the getter/setter message sends for property
+    // expressions.
+    TraverseStmt(E->getSyntacticForm());
+    return true;
+  }
+
+  bool TraverseObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+    RecursiveASTVisitor::TraverseObjCPropertyRefExpr(E);
+    // Visit the opaque base manually as it won't be traversed by the
+    // PseudoObjectExpr.
+    if (E->isObjectReceiver()) {
+      if (const auto *Opaque = dyn_cast<OpaqueValueExpr>(E->getBase()))
+        TraverseStmt(Opaque->getSourceExpr());
+    }
+    return true;
+  }
+
+  // Statement visitors:
+
+  bool VisitStmt(Stmt *S) {
+    collectStmtIfInRange(S, S->getSourceRange());
+    return true;
+  }
+
+  // Ignore some implicit expressions.
+
+  bool WalkUpFromMaterializeTemporaryExpr(MaterializeTemporaryExpr *E) {
+    return true;
+  }
+
+  bool WalkUpFromCXXThisExpr(CXXThisExpr *E) {
+    if (E->isImplicit())
+      return true;
+    return RecursiveASTVisitor::WalkUpFromCXXThisExpr(E);
+  }
+
+  /// Checks if the given statement and its source range has the location
+  /// of interest or overlaps with the selection range, and adds this node to
+  /// the set of statements for the slice that's being constructed.
+  void collectStmtIfInRange(const Stmt *S, SourceRange Range) {
+    SourceLocation Start = Range.getBegin();
+    const auto &SM = Context.getSourceManager();
+    bool IsStartMacroArg = false;
+    if (Start.isMacroID()) {
+      if (SM.isMacroArgExpansion(Start)) {
+        Start = SM.getSpellingLoc(Start);
+        IsStartMacroArg = true;
+      } else {
+        Start = SM.getExpansionLoc(Start);
+      }
+    }
+    SourceLocation End = Range.getEnd();
+    if (End.isMacroID() && SM.isMacroArgExpansion(End)) {
+      // Ignore the node that's span across normal code and a macro argument.
+      if (IsStartMacroArg)
+        End = SM.getSpellingLoc(End);
+    }
+    End = getPreciseTokenLocEnd(End, SM, Context.getLangOpts());
+    if (!isPairOfFileLocations(Start, End))
+      return;
+    if (SelectionRange.isValid()) {
+      if (!areRangesOverlapping(SelectionRange, SourceRange(Start, End),
+                                Context.getSourceManager()))
+        return;
+    } else if (!isPointWithin(Location, Start, End, Context.getSourceManager()))
+      return;
+    Matches.emplace_back(S, ParentStmt, CurrentDecl, SourceRange(Start, End));
+  }
+
+  void collectDeclIfInRange(const Decl *D) {
+    SourceLocation Start = D->getSourceRange().getBegin();
+    SourceLocation End = getPreciseTokenLocEnd(
+        getLexicalEndLocForDecl(D, Context.getSourceManager(),
+                                Context.getLangOpts()),
+        Context.getSourceManager(), Context.getLangOpts());
+    if (!isPairOfFileLocations(Start, End))
+      return;
+    if (SelectionRange.isValid()) {
+      if (!areRangesOverlapping(SelectionRange, SourceRange(Start, End),
+                                Context.getSourceManager()))
+        return;
+    } else if (!isPointWithin(Location, Start, End, Context.getSourceManager()))
+      return;
+    Matches.emplace_back(D, CurrentDecl, SourceRange(Start, End));
+  }
+
+  SmallVector<ASTSlice::Node, 16> Matches;
+  /// The point of interest.
+  ///
+  /// Represents a location at which refactoring should be initiated.
+  const SourceLocation Location;
+  const SourceRange SelectionRange;
+  const ASTContext &Context;
+  const Decl *CurrentDecl = nullptr;
+  const Stmt *ParentStmt = nullptr, *CurrentStmt = nullptr;
+};
+
+} // end anonymous namespace
+
+ASTSlice::SelectedStmt::SelectedStmt(ASTSlice &Slice, const Stmt *S,
+                                     unsigned Index)
+    : Slice(Slice), S(S), Index(Index) {
+  assert(S && "No statement given!");
+}
+
+ASTSlice::SelectedDecl::SelectedDecl(const Decl *D) : D(D) {
+  assert(D && "No decl given!");
+}
+
+const Decl *ASTSlice::SelectedStmt::getParentDecl() {
+  return Slice.parentDeclForIndex(Index);
+}
+
+ASTSlice::ASTSlice(SourceLocation Location, SourceRange SelectionRange,
+                   ASTContext &Context)
+    : Context(Context), SelectionLocation(Location),
+      SelectionRange(SelectionRange) {
+  FileID SearchFile = Context.getSourceManager().getFileID(Location);
+  ASTSliceFinder Visitor(Location, SelectionRange, Context);
+  SourceLocation EndLoc;
+  for (auto *CurrDecl : Context.getTranslationUnitDecl()->decls()) {
+    if (EndLoc.isValid() &&
+        !Context.getSourceManager().isBeforeInTranslationUnit(
+            CurrDecl->getLocStart(), EndLoc))
+      break;
+    const SourceLocation FileLoc =
+        Context.getSourceManager().getSpellingLoc(CurrDecl->getLocStart());
+    if (Context.getSourceManager().getFileID(FileLoc) == SearchFile)
+      Visitor.TraverseDecl(CurrDecl);
+    // We are only interested in looking at a single top level declaration
+    // even if our selection range spans across multiple top level declarations.
+    if (!Visitor.Matches.empty()) {
+      // Objective-C @implementation declarations might have trailing functions
+      // that are declared outside of the @implementation, so continue looking
+      // through them.
+      if (isa<ObjCImplDecl>(CurrDecl)) {
+        EndLoc = CurrDecl->getLocEnd();
+        continue;
+      }
+      break;
+    }
+  }
+
+  for (auto I = Visitor.Matches.rbegin(), E = Visitor.Matches.rend(); I != E;
+       ++I)
+    NodeTree.push_back(*I);
+}
+
+bool ASTSlice::isSourceRangeSelected(CharSourceRange Range) const {
+  SourceRange R = Range.getAsRange();
+  if (Range.isTokenRange())
+    R.setEnd(getPreciseTokenLocEnd(R.getEnd(), Context.getSourceManager(),
+                                   Context.getLangOpts()));
+  if (SelectionRange.isInvalid())
+    return isPointWithin(SelectionLocation, R.getBegin(), R.getEnd(),
+                         Context.getSourceManager());
+  return areRangesOverlapping(SelectionRange, R, Context.getSourceManager());
+}
+
+/// Find the 'if' statement that acts as the start of the
+/// 'if'/'else if'/'else' construct.
+static std::pair<const IfStmt *, unsigned>
+findIfStmtStart(const IfStmt *If, unsigned Index,
+                ArrayRef<ASTSlice::Node> NodeTree) {
+  if (Index >= NodeTree.size())
+    return {If, Index}; // We've reached the top of the tree, return.
+  const auto *ParentIf =
+      dyn_cast_or_null<IfStmt>(NodeTree[Index + 1].getStmtOrNull());
+  // The current 'if' is actually an 'else if' when the next 'if' has an else
+  // statement that points to the current 'if'.
+  if (!ParentIf || ParentIf->getElse() != If)
+    return {If, Index};
+  return findIfStmtStart(ParentIf, Index + 1, NodeTree);
+}
+
+/// Find an expression that best represents the given selected expression.
+static std::pair<const Stmt *, unsigned>
+canonicalizeSelectedExpr(const Stmt *S, unsigned Index,
+                         ArrayRef<ASTSlice::Node> NodeTree) {
+  const auto Same = std::make_pair(S, Index);
+  if (Index + 1 >= NodeTree.size())
+    return Same;
+  const Stmt *Parent = NodeTree[Index + 1].getStmtOrNull();
+  if (!Parent)
+    return Same;
+
+  const auto Next = std::make_pair(Parent, Index + 1);
+  // The entire pseudo expression is selected when just its syntactic
+  // form is selected.
+  if (isa<Expr>(S)) {
+    if (const auto *POE = dyn_cast_or_null<PseudoObjectExpr>(Parent)) {
+      if (POE->getSyntacticForm() == S)
+        return Next;
+    }
+  }
+  // The entire ObjC string literal is selected when just its string
+  // literal is selected.
+  if (isa<StringLiteral>(S) && isa<ObjCStringLiteral>(Parent))
+    return Next;
+  // The entire call should be selected when just the member expression
+  // that refers to the method is selected.
+  // FIXME: Check if this can be one of the call arguments.
+  if (isa<MemberExpr>(S) && isa<CXXMemberCallExpr>(Parent))
+    return Next;
+  // The entire call should be selected when just the callee is selected.
+  if (const auto *DRE = dyn_cast<DeclRefExpr>(S)) {
+    if (const auto *Call = dyn_cast<CallExpr>(Parent)) {
+      if (Call->getCalleeDecl() == DRE->getDecl())
+        return Next;
+    }
+  }
+  return Same;
+}
+
+Optional<ASTSlice::SelectedStmt> ASTSlice::nearestSelectedStmt(
+    llvm::function_ref<bool(const Stmt *)> Predicate) {
+  for (const auto &Node : llvm::enumerate(NodeTree)) {
+    const Stmt *S = Node.value().getStmtOrNull();
+    if (!S || !Predicate(S))
+      continue;
+
+    // Found the match. Perform any additional adjustments.
+    if (isa<Expr>(S)) {
+      auto CanonicalExpr = canonicalizeSelectedExpr(S, Node.index(), NodeTree);
+      return SelectedStmt(*this, CanonicalExpr.first, CanonicalExpr.second);
+    }
+    switch (S->getStmtClass()) {
+    case Stmt::IfStmtClass: {
+      // TODO: Fix findIfStmtStart bug with Index where it will return the
+      // index of the last statement.
+      auto If = findIfStmtStart(cast<IfStmt>(S), Node.index(), NodeTree);
+      return SelectedStmt(*this, If.first, If.second);
+    }
+    default:
+      break;
+    }
+
+    return SelectedStmt(*this, S, Node.index());
+  }
+  return None;
+}
+
+Optional<ASTSlice::SelectedStmt>
+ASTSlice::nearestSelectedStmt(Stmt::StmtClass Class) {
+  return nearestSelectedStmt(
+      [Class](const Stmt *S) -> bool { return S->getStmtClass() == Class; });
+}
+
+const Stmt *ASTSlice::nearestStmt(Stmt::StmtClass Class) {
+  auto Result = nearestSelectedStmt(Class);
+  return Result ? Result->getStmt() : nullptr;
+}
+
+Optional<ASTSlice::SelectedDecl> ASTSlice::innermostSelectedDecl(
+    llvm::function_ref<bool(const Decl *)> Predicate, unsigned Options) {
+  if (SelectionRange.isValid()) {
+    if (Options & ASTSlice::InnermostDeclOnly) {
+      auto Result = getInnermostCompletelySelectedDecl();
+      if (!Result)
+        return None;
+      if (Predicate(Result->getDecl()))
+        return Result;
+      return None;
+    }
+    // Traverse down through all of the selected node checking the predicate.
+    // TODO: Cache the SelectionRangeOverlap kinds properly instead of relying
+    // on getInnermostCompletelySelectedDecl.
+    getInnermostCompletelySelectedDecl();
+    for (const auto &N : NodeTree) {
+      const Decl *D = N.getDeclOrNull();
+      if (!D)
+        continue;
+      if (N.SelectionRangeOverlap != Node::ContainsSelectionRange)
+        continue;
+      if (Predicate(D))
+        return SelectedDecl(D);
+    }
+    return None;
+  }
+  for (const auto &Node : llvm::enumerate(NodeTree)) {
+    const Decl *D = Node.value().getDeclOrNull();
+    if (!D)
+      continue;
+    if (Predicate(D))
+      return SelectedDecl(D);
+    if (Options & ASTSlice::InnermostDeclOnly)
+      return None;
+  }
+  return None;
+}
+
+Optional<ASTSlice::SelectedDecl>
+ASTSlice::innermostSelectedDecl(ArrayRef<Decl::Kind> Classes,
+                                unsigned Options) {
+  assert(!Classes.empty() && "Expected at least one decl kind");
+  return innermostSelectedDecl(
+      [&](const Decl *D) {
+        for (Decl::Kind Class : Classes) {
+          if (D->getKind() == Class)
+            return true;
+        }
+        return false;
+      },
+      Options);
+}
+
+/// Compute the SelectionRangeOverlap kinds for matched AST nodes.
+///
+/// The overlap kinds are computed only upto the first node that contains the
+/// entire selection range.
+static void
+computeSelectionRangeOverlapKinds(MutableArrayRef<ASTSlice::Node> NodeTree,
+                                  SourceRange SelectionRange,
+                                  const SourceManager &SM) {
+  for (ASTSlice::Node &Node : NodeTree) {
+    bool HasStart =
+        isPointWithin(SelectionRange.getBegin(), Node.Range.getBegin(),
+                      Node.Range.getEnd(), SM);
+    bool HasEnd = isPointWithin(SelectionRange.getEnd(), Node.Range.getBegin(),
+                                Node.Range.getEnd(), SM);
+    if (HasStart && HasEnd)
+      Node.SelectionRangeOverlap = ASTSlice::Node::ContainsSelectionRange;
+    else if (HasStart)
+      Node.SelectionRangeOverlap = ASTSlice::Node::ContainsSelectionRangeStart;
+    else if (HasEnd)
+      Node.SelectionRangeOverlap = ASTSlice::Node::ContainsSelectionRangeEnd;
+  }
+}
+
+const Stmt *findFirstStatementAfter(const CompoundStmt *CS, SourceLocation Loc,
+                                    const SourceManager &SM) {
+  for (const Stmt *S : CS->body()) {
+    if (!SM.isBeforeInTranslationUnit(S->getLocStart(), Loc))
+      return S;
+  }
+  return nullptr;
+}
+
+const Stmt *findLastStatementBefore(const CompoundStmt *CS, SourceLocation Loc,
+                                    const Stmt *StartAt,
+                                    const SourceManager &SM) {
+  auto It = std::find(CS->body_begin(), CS->body_end(), StartAt);
+  assert(It != CS->body_end());
+  const Stmt *Last = StartAt;
+  for (auto E = CS->body_end(); It != E; ++It) {
+    const Stmt *S = *It;
+    if (!SM.isBeforeInTranslationUnit(S->getLocStart(), Loc))
+      return Last;
+    Last = S;
+  }
+  return Last;
+}
+
+/// Return the source construct that contains the given compound statement.
+///
+/// This is useful to find the source construct to which the given compound
+/// statement belongs to lexically. For example, if we've selected just the
+/// body of an if statement, we ideally want to select the entire if statement.
+static std::pair<const Stmt *, unsigned>
+findCompoundStatementSourceConstruct(const CompoundStmt *CS,
+                                     ArrayRef<ASTSlice::Node> NodeTree) {
+  for (const auto &Node : llvm::enumerate(NodeTree)) {
+    const Stmt *S = Node.value().getStmtOrNull();
+    if (!S)
+      continue;
+    for (const Stmt *Child : S->children()) {
+      if (Child == CS) {
+        if (isa<CompoundStmt>(S))
+          return {CS, 0};
+        if (const auto *If = dyn_cast<IfStmt>(S))
+          return findIfStmtStart(If, Node.index(), NodeTree);
+        return {S, Node.index()};
+      }
+    }
+  }
+  // This is the outer compound statement.
+  return {CS, 0};
+}
+
+/// Return the source construct that contains the given switch case.
+static std::pair<const Stmt *, unsigned>
+findSwitchSourceConstruct(const SwitchCase *Case,
+                          ArrayRef<ASTSlice::Node> NodeTree) {
+  for (const auto &Node : llvm::enumerate(NodeTree)) {
+    const Stmt *S = Node.value().getStmtOrNull();
+    if (!S)
+      continue;
+    if (isa<SwitchStmt>(S))
+      return {S, Node.index()};
+  }
+  return {Case, 0};
+}
+
+SelectedStmtSet SelectedStmtSet::createFromEntirelySelected(const Stmt *S,
+                                                            unsigned Index) {
+  SelectedStmtSet Result;
+  Result.containsSelectionRange = S;
+  Result.containsSelectionRangeIndex = Index;
+  return Result;
+}
+
+Optional<ASTSlice::SelectedDecl>
+ASTSlice::getInnermostCompletelySelectedDecl() {
+  assert(SelectionRange.isValid() && "No selection range!");
+  if (CachedSelectedInnermostDecl)
+    return *CachedSelectedInnermostDecl;
+  computeSelectionRangeOverlapKinds(NodeTree, SelectionRange,
+                                    Context.getSourceManager());
+  Optional<SelectedDecl> Result;
+  for (const auto &N : llvm::enumerate(NodeTree)) {
+    const Decl *D = N.value().getDeclOrNull();
+    if (!D)
+      continue;
+    if (N.value().SelectionRangeOverlap != Node::ContainsSelectionRange)
+      continue;
+    Result = SelectedDecl(D);
+    break;
+  }
+  CachedSelectedInnermostDecl = Result;
+  return Result;
+}
+
+static bool isCaseSelected(const SwitchStmt *S, SourceRange SelectionRange,
+                           const SourceManager &SM) {
+  for (const SwitchCase *Case = S->getSwitchCaseList(); Case;
+       Case = Case->getNextSwitchCase()) {
+    SourceRange Range(Case->getLocStart(), Case->getColonLoc());
+    if (areRangesOverlapping(Range, SelectionRange, SM))
+      return true;
+  }
+  return false;
+}
+
+Optional<SelectedStmtSet> ASTSlice::computeSelectedStmtSet() {
+  if (SelectionRange.isInvalid())
+    return None;
+  computeSelectionRangeOverlapKinds(NodeTree, SelectionRange,
+                                    Context.getSourceManager());
+
+  SelectedStmtSet Result;
+  for (const auto &N : llvm::enumerate(NodeTree)) {
+    const auto *S = N.value().getStmtOrNull();
+    if (!S)
+      continue;
+    switch (N.value().SelectionRangeOverlap) {
+    case Node::ContainsSelectionRange: {
+      Result.containsSelectionRange = S;
+      Result.containsSelectionRangeIndex = N.index();
+
+      const auto *CS = dyn_cast<CompoundStmt>(Result.containsSelectionRange);
+      if (!CS) {
+        // The entire if should be selected when just the 'else if' overlaps
+        // with the selection range.
+        if (const auto *If = dyn_cast<IfStmt>(Result.containsSelectionRange)) {
+          auto IfConstruct = findIfStmtStart(If, N.index(), NodeTree);
+          return SelectedStmtSet::createFromEntirelySelected(
+              IfConstruct.first, IfConstruct.second);
+        }
+        // The entire switch should be selected when just a 'case' overlaps
+        // with the selection range.
+        if (const auto *Case =
+                dyn_cast<SwitchCase>(Result.containsSelectionRange)) {
+          auto Switch = findSwitchSourceConstruct(
+              Case, makeArrayRef(NodeTree).drop_front(N.index() + 1));
+          return SelectedStmtSet::createFromEntirelySelected(
+              Switch.first, N.index() + Switch.second);
+        }
+
+        auto CanonicalExpr = canonicalizeSelectedExpr(S, N.index(), NodeTree);
+        Result.containsSelectionRange = CanonicalExpr.first;
+        Result.containsSelectionRangeIndex = CanonicalExpr.second;
+        return Result;
+      }
+
+      bool IsLBraceSelected =
+          !Context.getSourceManager().isBeforeInTranslationUnit(
+              CS->getLBracLoc(), SelectionRange.getBegin());
+      bool IsRBraceSelected =
+          Context.getSourceManager().isBeforeInTranslationUnit(
+              CS->getRBracLoc(), SelectionRange.getEnd());
+
+      // Return the entire source construct that has the compound statement
+      // when one of the braces is selected, or when an actual `case` of the
+      // switch is selected.
+      auto Construct = findCompoundStatementSourceConstruct(
+          CS, makeArrayRef(NodeTree).drop_front(N.index() + 1));
+      if (Construct.first != CS &&
+          ((IsLBraceSelected || IsRBraceSelected) ||
+           (isa<SwitchStmt>(Construct.first) &&
+            isCaseSelected(cast<SwitchStmt>(Construct.first), SelectionRange,
+                           Context.getSourceManager()))))
+        return SelectedStmtSet::createFromEntirelySelected(
+            Construct.first, N.index() + Construct.second);
+
+      // When both braces are selected the entire compound statement is
+      // considered to be selected.
+      if (IsLBraceSelected && IsRBraceSelected)
+        return Result;
+      if (IsLBraceSelected)
+        Result.containsSelectionRangeStart = CS->body_front();
+      else if (IsRBraceSelected)
+        Result.containsSelectionRangeEnd = CS->body_back();
+
+      if (!Result.containsSelectionRangeStart)
+        Result.containsSelectionRangeStart = findFirstStatementAfter(
+            CS, SelectionRange.getBegin(), Context.getSourceManager());
+
+      // Return an empty set when the compound statements os empty or the
+      // selection range starts after the last statement or the selection range
+      // doesn't overlap with any actual statements.
+      if (!Result.containsSelectionRangeStart ||
+          !Context.getSourceManager().isBeforeInTranslationUnit(
+              Result.containsSelectionRangeStart->getLocStart(),
+              SelectionRange.getEnd()))
+        return None;
+
+      if (!Result.containsSelectionRangeEnd)
+        Result.containsSelectionRangeEnd = findLastStatementBefore(
+            CS, SelectionRange.getEnd(), Result.containsSelectionRangeStart,
+            Context.getSourceManager());
+
+      return Result;
+    }
+    case Node::ContainsSelectionRangeStart:
+      Result.containsSelectionRangeStart = S;
+      break;
+    case Node::ContainsSelectionRangeEnd:
+      Result.containsSelectionRangeEnd = S;
+      break;
+    case Node::UnknownOverlap:
+      break;
+    }
+  }
+  return Result;
+}
+
+Optional<SelectedStmtSet> ASTSlice::getSelectedStmtSet() {
+  if (CachedSelectedStmtSet)
+    return *CachedSelectedStmtSet;
+  CachedSelectedStmtSet = computeSelectedStmtSet();
+  return *CachedSelectedStmtSet;
+}
+
+bool ASTSlice::isContainedInCompoundStmt(unsigned Index) {
+  assert(Index < NodeTree.size() && "Invalid node index");
+  for (unsigned I = Index + 1, E = NodeTree.size(); I != E; ++I) {
+    const Stmt *S = NodeTree[I].getStmtOrNull();
+    if (!S)
+      continue;
+    if (isa<CompoundStmt>(S))
+      return true;
+  }
+  return false;
+}
+
+const Decl *ASTSlice::parentDeclForIndex(unsigned Index) {
+  return NodeTree[Index].ParentDecl;
+}
+
+const Stmt *ASTSlice::parentStmtForIndex(unsigned Index) {
+  return NodeTree[Index].ParentStmt;
+}
diff --git a/lib/Tooling/Refactor/ASTSlice.h b/lib/Tooling/Refactor/ASTSlice.h
new file mode 100644
index 0000000..f5cb9c6
--- /dev/null
+++ b/lib/Tooling/Refactor/ASTSlice.h
@@ -0,0 +1,182 @@
+//===--- ASTSlice.h - Represents a portion of the AST ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_TOOLING_REFACTOR_ASTSLICE_H
+#define LLVM_CLANG_LIB_TOOLING_REFACTOR_ASTSLICE_H
+
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class NamedDecl;
+
+namespace tooling {
+
+/// Represents a set of statements that overlap with the selection range.
+struct SelectedStmtSet {
+  /// The outermost statement that contains the start of the selection range.
+  const Stmt *containsSelectionRangeStart = nullptr;
+
+  /// The outermost statement that contains the end of the selection range.
+  const Stmt *containsSelectionRangeEnd = nullptr;
+
+  /// The innermost statement that contains the entire selection range.
+  const Stmt *containsSelectionRange = nullptr;
+
+  /// The index of the innermost statement that contains the entire selection
+  /// range. The index points into the NodeTree stored in the \c ASTSlice.
+  Optional<unsigned> containsSelectionRangeIndex;
+
+  static SelectedStmtSet createFromEntirelySelected(const Stmt *S,
+                                                    unsigned Index);
+
+  /// Returns true if the compound statement is not fully selected.
+  bool isCompoundStatementPartiallySelected() const {
+    assert(containsSelectionRange && "No statement selected");
+    return isa<CompoundStmt>(containsSelectionRange) &&
+           (containsSelectionRangeStart || containsSelectionRangeEnd);
+  }
+};
+
+/// A portion of the AST that is located around the location and/or source
+/// range of interest.
+class ASTSlice {
+public:
+  struct Node {
+    enum SelectionRangeOverlapKind {
+      UnknownOverlap,
+      ContainsSelectionRangeStart,
+      ContainsSelectionRangeEnd,
+      ContainsSelectionRange
+    };
+    llvm::PointerUnion<const Stmt *, const Decl *> StmtOrDecl;
+    const Stmt *ParentStmt;
+    const Decl *ParentDecl;
+    SourceRange Range;
+    SelectionRangeOverlapKind SelectionRangeOverlap = UnknownOverlap;
+
+    const Stmt *getStmtOrNull() const {
+      return StmtOrDecl.dyn_cast<const Stmt *>();
+    }
+
+    const Decl *getDeclOrNull() const {
+      return StmtOrDecl.dyn_cast<const Decl *>();
+    }
+
+    Node(const Stmt *S, const Stmt *ParentStmt, const Decl *ParentDecl,
+         SourceRange Range)
+        : StmtOrDecl(S), ParentStmt(ParentStmt), ParentDecl(ParentDecl),
+          Range(Range) {}
+    Node(const Decl *D, const Decl *ParentDecl, SourceRange Range)
+        : StmtOrDecl(D), ParentStmt(nullptr), ParentDecl(ParentDecl),
+          Range(Range) {}
+  };
+
+  /// Represents a statement that overlaps with the selection range/point.
+  class SelectedStmt {
+    ASTSlice &Slice;
+    const Stmt *S;
+    unsigned Index;
+
+    friend class ASTSlice;
+
+    SelectedStmt(ASTSlice &Slice, const Stmt *S, unsigned Index);
+
+  public:
+    const Stmt *getStmt() { return S; }
+    const Decl *getParentDecl();
+  };
+
+  /// Represents a declaration that overlaps with the selection range/point.
+  class SelectedDecl {
+    const Decl *D;
+
+    friend class ASTSlice;
+
+    SelectedDecl(const Decl *D);
+
+  public:
+    const Decl *getDecl() { return D; }
+  };
+
+  ASTSlice(SourceLocation Location, SourceRange SelectionRange,
+           ASTContext &Context);
+
+  /// Returns true if the given source range overlaps with the selection.
+  bool isSourceRangeSelected(CharSourceRange Range) const;
+
+  enum SelectionSearchOptions {
+    /// Search with-in the innermost declaration only, including the declaration
+    /// itself without inspecting any other outer declarations.
+    InnermostDeclOnly = 1
+  };
+
+  /// Returns the statement that results in true when passed into \p Predicate
+  /// that's nearest to the location of interest, or \c None if such statement
+  /// isn't found.
+  Optional<SelectedStmt>
+  nearestSelectedStmt(llvm::function_ref<bool(const Stmt *)> Predicate);
+
+  /// Returns the statement of the given class that's nearest to the location
+  /// of interest, or \c None if such statement isn't found.
+  Optional<SelectedStmt> nearestSelectedStmt(Stmt::StmtClass Class);
+
+  /// TODO: Remove in favour of nearestStmt that returns \c SelectedStmt
+  const Stmt *nearestStmt(Stmt::StmtClass Class);
+
+  /// Returns the declaration that overlaps with the selection range, is
+  /// nearest to the location of interest and that results in true when passed
+  /// into \p Predicate, or \c None if such declaration isn't found.
+  Optional<SelectedDecl>
+  innermostSelectedDecl(llvm::function_ref<bool(const Decl *)> Predicate,
+                        unsigned Options = 0);
+
+  /// Returns the declaration closest to the location of interest whose decl
+  /// kind is in \p Classes, or \c None if no such decl can't be found.
+  Optional<SelectedDecl> innermostSelectedDecl(ArrayRef<Decl::Kind> Classes,
+                                               unsigned Options = 0);
+
+  /// Returns the set of statements that overlap with the selection range.
+  Optional<SelectedStmtSet> getSelectedStmtSet();
+
+  /// Returns true if the statement with the given index is contained in a
+  /// compound statement that overlaps with the selection range.
+  bool isContainedInCompoundStmt(unsigned Index);
+
+  /// Returns the declaration that contains the statement at the given index.
+  const Decl *parentDeclForIndex(unsigned Index);
+
+  /// Returns the statement that contains the statement at the given index.
+  const Stmt *parentStmtForIndex(unsigned Index);
+
+private:
+  Optional<SelectedStmtSet> computeSelectedStmtSet();
+
+  /// Returns the innermost declaration that contains both the start and the
+  /// end of the selection range.
+  Optional<SelectedDecl> getInnermostCompletelySelectedDecl();
+
+  /// The lowest element is the top of the hierarchy
+  SmallVector<Node, 16> NodeTree;
+  ASTContext &Context;
+  SourceLocation SelectionLocation;
+  SourceRange SelectionRange;
+  Optional<Optional<SelectedStmtSet>> CachedSelectedStmtSet;
+  Optional<Optional<SelectedDecl>> CachedSelectedInnermostDecl;
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_TOOLING_REFACTOR_ASTSLICE_H
diff --git a/lib/Tooling/Refactor/ASTStateSerialization.cpp b/lib/Tooling/Refactor/ASTStateSerialization.cpp
new file mode 100644
index 0000000..2d10fbc
--- /dev/null
+++ b/lib/Tooling/Refactor/ASTStateSerialization.cpp
@@ -0,0 +1,70 @@
+//===-- ASTStateSerialization.cpp - Persists TU-specific state across TUs -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RefactoringContinuations.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace clang::tooling::detail;
+
+namespace {
+
+class USRToDeclConverter
+    : public clang::RecursiveASTVisitor<USRToDeclConverter> {
+  llvm::StringMap<const Decl *> &USRs;
+  unsigned NumFound = 0;
+
+public:
+  USRToDeclConverter(llvm::StringMap<const Decl *> &USRs) : USRs(USRs) {}
+
+  bool isDone() const { return NumFound == USRs.size(); }
+
+  bool VisitNamedDecl(const NamedDecl *D) {
+    std::string USR = rename::getUSRForDecl(D);
+    auto It = USRs.find(USR);
+    if (It == USRs.end() || It->second)
+      return true;
+    It->second = D;
+    ++NumFound;
+    return NumFound != USRs.size();
+  }
+};
+
+} // end anonymous namespace
+
+const Decl *PersistentToASTSpecificStateConverter::lookupDecl(StringRef USR) {
+  if (USR.empty())
+    return nullptr;
+  auto It = ConvertedDeclRefs.find(USR);
+  if (It != ConvertedDeclRefs.end())
+    return It->second;
+  // FIXME: If we ever need to convert a PersistentDeclRef through the ASTQuery,
+  // we have to support conversion without coalesced conversion.
+  assert(false && "Persistent decl refs should be converted all at once");
+  return nullptr;
+}
+
+void PersistentToASTSpecificStateConverter::runCoalescedConversions() {
+  USRToDeclConverter Converter(ConvertedDeclRefs);
+  for (Decl *D : Context.getTranslationUnitDecl()->decls()) {
+    Converter.TraverseDecl(D);
+    if (Converter.isDone())
+      break;
+  }
+}
+
+FileID
+PersistentToASTSpecificStateConverter::convert(const PersistentFileID &Ref) {
+  FileManager &FM = Context.getSourceManager().getFileManager();
+  const FileEntry *Entry = FM.getFile(Ref.Filename);
+  if (!Entry)
+    return FileID();
+  return Context.getSourceManager().translateFile(Entry);
+}
diff --git a/lib/Tooling/Refactor/CMakeLists.txt b/lib/Tooling/Refactor/CMakeLists.txt
new file mode 100644
index 0000000..9828c1a
--- /dev/null
+++ b/lib/Tooling/Refactor/CMakeLists.txt
@@ -0,0 +1,44 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangToolingRefactor
+  ASTSlice.cpp
+  ASTStateSerialization.cpp
+  Extract.cpp
+  ExtractRepeatedExpressionIntoVariable.cpp
+  ExtractionUtils.cpp
+  FillInEnumSwitchCases.cpp
+  FillInMissingMethodStubsFromAbstractClasses.cpp
+  FillInMissingProtocolStubs.cpp
+  IfSwitchConversion.cpp
+  ImplementDeclaredMethods.cpp
+  IndexerQueries.cpp
+  LocalizeObjCStringLiteral.cpp
+  RefactoringActions.cpp
+  RefactoringActionFinder.cpp
+  RefactoringOperation.cpp
+  RefactoringOptions.cpp
+  RenamingOperation.cpp
+  RenameIndexedFile.cpp
+  RenamedSymbol.cpp
+  SourceLocationUtilities.cpp
+  StmtUtils.cpp
+  SymbolOperation.cpp
+  SymbolOccurrenceFinder.cpp
+  SymbolName.cpp
+  SymbolUSRFinder.cpp
+  TypeUtils.cpp
+  USRFinder.cpp
+
+  DEPENDS
+  ClangDriverOptions
+
+  LINK_LIBS
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangEdit
+  clangIndex
+  clangLex
+  clangToolingCore
+  clangRewrite
+  )
diff --git a/lib/Tooling/Refactor/Extract.cpp b/lib/Tooling/Refactor/Extract.cpp
new file mode 100644
index 0000000..0dbc304
--- /dev/null
+++ b/lib/Tooling/Refactor/Extract.cpp
@@ -0,0 +1,1999 @@
+//===--- Extract.cpp -  ---------------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the "extract" refactoring operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ExtractionUtils.h"
+#include "RefactoringOperations.h"
+#include "SourceLocationUtilities.h"
+#include "StmtUtils.h"
+#include "TypeUtils.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/MacroInfo.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactor/RefactoringOptions.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Path.h"
+#include <algorithm>
+
+using namespace clang;
+using namespace clang::tooling;
+
+namespace {
+
+struct CompoundStatementRange {
+  CompoundStmt::const_body_iterator First, Last;
+
+  const Stmt *getFirst() const {
+    // We must have selected just the child of the case, since a selection that
+    // includes the case is treated like a selection of the entire switch.
+    if (const auto *Case = dyn_cast<SwitchCase>(*First)) {
+      if (const Stmt *S = Case->getSubStmt())
+        return S;
+    }
+    return *First;
+  }
+
+  const Stmt *getLast() const { return *Last; }
+
+  // TODO: We might not want to iterate over the switch case if we've just
+  // selected its child. We should switch over to an array of nodes instead of
+  // an iterator pair instead.
+  CompoundStmt::const_body_iterator begin() const { return First; }
+  CompoundStmt::const_body_iterator end() const { return Last + 1; }
+};
+
+enum class ExtractionKind { Function, Method, Expression };
+
+class ExtractOperation : public RefactoringOperation {
+public:
+  struct CandidateInfo {
+    CandidateInfo(SourceRange Range, StringRef PreInsertedText = "",
+                  const Stmt *AnalyzedStatement = nullptr)
+        : Range(Range), PreInsertedText(PreInsertedText),
+          AnalyzedStatement(AnalyzedStatement) {}
+
+    /// The candidate token range, i.e. the end location is the starting
+    /// location of the last token.
+    SourceRange Range;
+    /// The text that should be inserted before the call to the extracted
+    /// function.
+    StringRef PreInsertedText;
+    /// The expression that should be analyzed for captured variables and the
+    /// return value.
+    const Stmt *AnalyzedStatement;
+  };
+
+  ExtractOperation(const Stmt *S, const Stmt *ParentStmt,
+                   const Decl *FunctionLikeParentDecl,
+                   std::vector<std::string> Candidates,
+                   Optional<CompoundStatementRange> ExtractedStmtRange,
+                   Optional<CandidateInfo> FirstCandidateInfo,
+                   ExtractionKind Kind)
+      : S(S), ParentStmt(ParentStmt),
+        FunctionLikeParentDecl(FunctionLikeParentDecl),
+        Candidates(std::move(Candidates)),
+        ExtractedStmtRange(ExtractedStmtRange), Kind(Kind) {
+    if (FirstCandidateInfo)
+      CandidateExtractionInfo.push_back(*FirstCandidateInfo);
+  }
+
+  const Stmt *getTransformedStmt() const override {
+    if (ExtractedStmtRange)
+      return ExtractedStmtRange->getFirst();
+    return S;
+  }
+
+  const Stmt *getLastTransformedStmt() const override {
+    if (ExtractedStmtRange)
+      return ExtractedStmtRange->getLast();
+    return nullptr;
+  }
+
+  std::vector<std::string> getRefactoringCandidates() override {
+    return Candidates;
+  }
+
+  std::vector<RefactoringActionType> getAvailableSubActions() override {
+    std::vector<RefactoringActionType> SubActions;
+    if (isa<CXXMethodDecl>(FunctionLikeParentDecl) ||
+        isa<ObjCMethodDecl>(FunctionLikeParentDecl))
+      SubActions.push_back(RefactoringActionType::Extract_Method);
+    if (isLexicalExpression(S, ParentStmt))
+      SubActions.push_back(RefactoringActionType::Extract_Expression);
+    return SubActions;
+  }
+
+  bool isMethodExtraction() const { return Kind == ExtractionKind::Method; }
+
+  bool isExpressionExtraction() const {
+    return Kind == ExtractionKind::Expression;
+  }
+
+  llvm::Expected<RefactoringResult> perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex) override;
+
+  llvm::Expected<RefactoringResult>
+  performExpressionExtraction(ASTContext &Context, PrintingPolicy &PP);
+
+  const Stmt *S, *ParentStmt;
+  const Decl *FunctionLikeParentDecl;
+  std::vector<std::string> Candidates;
+  /// A set of extraction candidates that correspond to the extracted code.
+  SmallVector<CandidateInfo, 2> CandidateExtractionInfo;
+  Optional<CompoundStatementRange> ExtractedStmtRange;
+  ExtractionKind Kind;
+};
+
+} // end anonymous namespace
+
+bool isSimpleExpression(const Expr *E) {
+  switch (E->IgnoreParenCasts()->getStmtClass()) {
+  case Stmt::DeclRefExprClass:
+  case Stmt::PredefinedExprClass:
+  case Stmt::IntegerLiteralClass:
+  case Stmt::FloatingLiteralClass:
+  case Stmt::ImaginaryLiteralClass:
+  case Stmt::CharacterLiteralClass:
+  case Stmt::StringLiteralClass:
+    return true;
+  default:
+    return false;
+  }
+}
+
+static bool isMultipleCandidateBinOp(BinaryOperatorKind Op) {
+  return Op == BO_Add || Op == BO_Sub;
+}
+
+/// Searches for the selected statement in the given CompoundStatement, looking
+/// through things like PseudoObjectExpressions.
+static CompoundStmt::const_body_iterator
+findSelectedStmt(CompoundStmt::body_const_range Statements,
+                 const Stmt *Target) {
+  return llvm::find_if(Statements, [=](const Stmt *S) {
+    if (S == Target)
+      return true;
+    if (const auto *POE = dyn_cast<PseudoObjectExpr>(S)) {
+      if (POE->getSyntacticForm() == Target)
+        return true;
+    }
+    return false;
+  });
+}
+
+/// Returns the first and the last statements that should be extracted from a
+/// compound statement.
+Optional<CompoundStatementRange> getExtractedStatements(const CompoundStmt *CS,
+                                                        const Stmt *Begin,
+                                                        const Stmt *End) {
+  if (CS->body_empty())
+    return None;
+  assert(Begin && End);
+  CompoundStatementRange Result;
+  Result.First = findSelectedStmt(CS->body(), Begin);
+  assert(Result.First != CS->body_end());
+  Result.Last = findSelectedStmt(
+      CompoundStmt::body_const_range(Result.First, CS->body_end()), End);
+  assert(Result.Last != CS->body_end());
+  return Result;
+}
+
+static RefactoringOperationResult
+initiateAnyExtractOperation(ASTSlice &Slice, ASTContext &Context,
+                            SourceLocation Location, SourceRange SelectionRange,
+                            bool CreateOperation,
+                            ExtractionKind Kind = ExtractionKind::Function) {
+  auto SelectedStmtsOpt = Slice.getSelectedStmtSet();
+  if (!SelectedStmtsOpt)
+    return None;
+  SelectedStmtSet Stmts = *SelectedStmtsOpt;
+  // The selection range is contained entirely within this statement (without
+  // taking leading/trailing comments and whitespace into account).
+  const Stmt *Selected = Stmts.containsSelectionRange;
+
+  // We only want to perform the extraction if the selection range is entirely
+  // within a body of a function or method.
+  if (!Selected)
+    return None;
+  const Decl *ParentDecl =
+      Slice.parentDeclForIndex(*Stmts.containsSelectionRangeIndex);
+
+  if (!ParentDecl ||
+      (!Stmts.isCompoundStatementPartiallySelected() &&
+       !Slice.isContainedInCompoundStmt(*Stmts.containsSelectionRangeIndex)))
+    return RefactoringOperationResult(
+        "the selected expression is not in a function");
+
+  if (isa<Expr>(Selected) && isSimpleExpression(cast<Expr>(Selected)))
+    return RefactoringOperationResult("the selected expression is too simple");
+  if (const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(Selected)) {
+    if (!PRE->isMessagingGetter())
+      return RefactoringOperationResult("property setter can't be extracted");
+  }
+
+  const Stmt *ParentStmt =
+      Slice.parentStmtForIndex(*Stmts.containsSelectionRangeIndex);
+  if (Kind == ExtractionKind::Expression &&
+      !isLexicalExpression(Selected, ParentStmt))
+    return None;
+
+  RefactoringOperationResult Result;
+  Result.Initiated = true;
+  if (!CreateOperation)
+    return Result;
+
+  Optional<CompoundStatementRange> ExtractedStmtRange;
+
+  // Check if there are multiple candidates that can be extracted.
+  std::vector<std::string> Candidates;
+  Optional<ExtractOperation::CandidateInfo> FirstCandidateInfo;
+  if (const auto *BinOp = dyn_cast<BinaryOperator>(Selected)) {
+    // Binary '+' and '-' operators allow multiple candidates when the
+    // selection range starts after the LHS expression but still overlaps
+    // with the RHS.
+    if (isMultipleCandidateBinOp(BinOp->getOpcode()) &&
+        (!Stmts.containsSelectionRangeStart ||
+         getPreciseTokenLocEnd(
+             BinOp->getLHS()->getLocEnd(), Context.getSourceManager(),
+             Context.getLangOpts()) == SelectionRange.getBegin()) &&
+        Stmts.containsSelectionRangeEnd) {
+      SourceRange FirstCandidateRange =
+          SourceRange(SelectionRange.getBegin(), BinOp->getLocEnd());
+      if (FirstCandidateRange.getEnd().isMacroID())
+        FirstCandidateRange.setEnd(Context.getSourceManager().getExpansionLoc(
+            FirstCandidateRange.getEnd()));
+      FirstCandidateInfo = ExtractOperation::CandidateInfo(
+          FirstCandidateRange, "+ ",
+          /*AnalyzedStatement=*/BinOp->getRHS());
+      Candidates.push_back(
+          Lexer::getSourceText(
+              CharSourceRange::getTokenRange(FirstCandidateRange),
+              Context.getSourceManager(), Context.getLangOpts())
+              .trim());
+      Candidates.push_back(Lexer::getSourceText(
+          CharSourceRange::getTokenRange(BinOp->getSourceRange()),
+          Context.getSourceManager(), Context.getLangOpts()));
+    }
+  } else if (const auto *CS = dyn_cast<CompoundStmt>(Selected)) {
+    // We want to extract some child statements from a compound statement unless
+    // we've selected the entire compound statement including the opening and
+    // closing brace.
+    if (Stmts.containsSelectionRangeStart)
+      ExtractedStmtRange =
+          getExtractedStatements(CS, Stmts.containsSelectionRangeStart,
+                                 Stmts.containsSelectionRangeEnd);
+  }
+
+  auto Operation = llvm::make_unique<ExtractOperation>(
+      Selected, ParentStmt, ParentDecl, std::move(Candidates),
+      ExtractedStmtRange, FirstCandidateInfo, Kind);
+  auto &CandidateExtractionInfo = Operation->CandidateExtractionInfo;
+  SourceRange Range;
+  if (ExtractedStmtRange)
+    Range = SourceRange(ExtractedStmtRange->getFirst()->getLocStart(),
+                        ExtractedStmtRange->getLast()->getLocEnd());
+  else
+    Range = Selected->getSourceRange();
+  bool IsBeginMacroArgument = false;
+  if (Range.getBegin().isMacroID()) {
+    if (Context.getSourceManager().isMacroArgExpansion(Range.getBegin())) {
+      Range.setBegin(
+          Context.getSourceManager().getSpellingLoc(Range.getBegin()));
+      IsBeginMacroArgument = true;
+    } else {
+      Range.setBegin(
+          Context.getSourceManager().getExpansionLoc(Range.getBegin()));
+    }
+  }
+  if (Range.getEnd().isMacroID()) {
+    if (IsBeginMacroArgument &&
+        Context.getSourceManager().isMacroArgExpansion(Range.getEnd()))
+      Range.setEnd(Context.getSourceManager().getSpellingLoc(Range.getEnd()));
+    else
+      Range.setEnd(
+          Context.getSourceManager().getExpansionRange(Range.getEnd()).second);
+  }
+  CandidateExtractionInfo.push_back(ExtractOperation::CandidateInfo(Range));
+  Result.RefactoringOp = std::move(Operation);
+  return Result;
+}
+
+RefactoringOperationResult clang::tooling::initiateExtractOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  return initiateAnyExtractOperation(Slice, Context, Location, SelectionRange,
+                                     CreateOperation);
+}
+
+RefactoringOperationResult clang::tooling::initiateExtractMethodOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  // TODO: Verify that method extraction is actually possible.
+  return initiateAnyExtractOperation(Slice, Context, Location, SelectionRange,
+                                     CreateOperation, ExtractionKind::Method);
+}
+
+RefactoringOperationResult clang::tooling::initiateExtractExpressionOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  RefactoringOperationResult R =
+      initiateAnyExtractOperation(Slice, Context, Location, SelectionRange,
+                                  CreateOperation, ExtractionKind::Expression);
+  return R;
+}
+
+using ReferencedEntity =
+    llvm::PointerUnion<const DeclRefExpr *, const FieldDecl *>;
+
+/// Iterate over the entities (variables/instance variables) that are directly
+/// referenced by the given expression \p E.
+///
+/// Note: Objective-C ivars are always captured via 'self'.
+static void findEntitiesDirectlyReferencedInExpr(
+    const Expr *E,
+    llvm::function_ref<void(const ReferencedEntity &Entity)> Handler) {
+  E = E->IgnoreParenCasts();
+  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
+    return Handler(DRE);
+
+  if (const auto *ME = dyn_cast<MemberExpr>(E)) {
+    if (isa<CXXThisExpr>(ME->getBase()->IgnoreParenCasts())) {
+      if (const auto *FD = dyn_cast_or_null<FieldDecl>(ME->getMemberDecl()))
+        Handler(FD);
+      return;
+    }
+    if (const auto *MD = ME->getMemberDecl()) {
+      if (isa<FieldDecl>(MD) || isa<IndirectFieldDecl>(MD))
+        findEntitiesDirectlyReferencedInExpr(ME->getBase(), Handler);
+    }
+    return;
+  }
+
+  if (const auto *CO = dyn_cast<ConditionalOperator>(E)) {
+    findEntitiesDirectlyReferencedInExpr(CO->getTrueExpr(), Handler);
+    findEntitiesDirectlyReferencedInExpr(CO->getFalseExpr(), Handler);
+    return;
+  }
+
+  if (const auto *BO = dyn_cast<BinaryOperator>(E)) {
+    if (BO->getOpcode() == BO_Comma)
+      return findEntitiesDirectlyReferencedInExpr(BO->getRHS(), Handler);
+  }
+}
+
+template <typename T, typename Matcher>
+static void
+findMatchingParameters(Matcher &ParameterMatcher, const Stmt *S,
+                       ASTContext &Context, StringRef Node,
+                       llvm::function_ref<void(const T *E)> Handler) {
+  using namespace clang::ast_matchers;
+  auto Matches = match(findAll(callExpr(ParameterMatcher)), *S, Context);
+  for (const auto &Match : Matches)
+    Handler(Match.template getNodeAs<T>(Node));
+  Matches = match(findAll(cxxConstructExpr(ParameterMatcher)), *S, Context);
+  for (const auto &Match : Matches)
+    Handler(Match.template getNodeAs<T>(Node));
+}
+
+static void
+findUseOfConstThis(const Stmt *S, ASTContext &Context,
+                   llvm::function_ref<void(const CXXThisExpr *E)> Handler) {
+  using namespace clang::ast_matchers;
+  // Check the receiver in method call and member operator calls.
+  auto This = cxxThisExpr().bind("this");
+  auto ThisReceiver = ignoringParenCasts(
+      anyOf(This, unaryOperator(hasOperatorName("*"),
+                                hasUnaryOperand(ignoringParenCasts(This)))));
+  auto ConstMethodCallee = callee(cxxMethodDecl(isConst()));
+  auto Matches = match(
+      findAll(expr(anyOf(cxxMemberCallExpr(ConstMethodCallee, on(ThisReceiver)),
+                         cxxOperatorCallExpr(ConstMethodCallee,
+                                             hasArgument(0, ThisReceiver))))),
+      *S, Context);
+  for (const auto &Match : Matches)
+    Handler(Match.getNodeAs<CXXThisExpr>("this"));
+  // Check parameters in calls.
+  auto ConstPointee = pointee(qualType(isConstQualified()));
+  auto RefParameter = forEachArgumentWithParam(
+      ThisReceiver,
+      parmVarDecl(hasType(qualType(referenceType(ConstPointee)))));
+  findMatchingParameters(RefParameter, S, Context, "this", Handler);
+  auto PtrParameter = forEachArgumentWithParam(
+      ignoringParenCasts(This),
+      parmVarDecl(hasType(qualType(pointerType(ConstPointee)))));
+  findMatchingParameters(PtrParameter, S, Context, "this", Handler);
+}
+
+static void findArgumentsPassedByNonConstReference(
+    const Stmt *S, ASTContext &Context,
+    llvm::function_ref<void(const Expr *E)> Handler) {
+  using namespace clang::ast_matchers;
+  // Check the receiver in method call and member operator calls.
+  auto NonPointerReceiver =
+      expr(unless(hasType(qualType(pointerType())))).bind("arg");
+  auto NonConstMethodCallee = callee(cxxMethodDecl(unless(isConst())));
+  auto Matches =
+      match(findAll(expr(anyOf(
+                cxxMemberCallExpr(NonConstMethodCallee, on(NonPointerReceiver)),
+                cxxOperatorCallExpr(NonConstMethodCallee,
+                                    hasArgument(0, NonPointerReceiver))))),
+            *S, Context);
+  for (const auto &Match : Matches)
+    Handler(Match.getNodeAs<Expr>("arg"));
+  // Check parameters in calls.
+  auto RefParameter = forEachArgumentWithParam(
+      expr().bind("arg"), parmVarDecl(hasType(qualType(referenceType(unless(
+                              pointee(qualType(isConstQualified()))))))));
+  Matches = match(findAll(callExpr(RefParameter)), *S, Context);
+  for (const auto &Match : Matches)
+    Handler(Match.getNodeAs<Expr>("arg"));
+  Matches = match(findAll(cxxConstructExpr(RefParameter)), *S, Context);
+  for (const auto &Match : Matches)
+    Handler(Match.getNodeAs<Expr>("arg"));
+}
+
+static void findAddressExpressionsPassedByConstPointer(
+    const Stmt *S, ASTContext &Context,
+    llvm::function_ref<void(const UnaryOperator *E)> Handler) {
+  using namespace clang::ast_matchers;
+  auto ConstPtrParameter = forEachArgumentWithParam(
+      ignoringParenImpCasts(unaryOperator(hasOperatorName("&")).bind("arg")),
+      parmVarDecl(hasType(
+          qualType(pointerType(pointee(qualType(isConstQualified())))))));
+  auto Matches = match(findAll(callExpr(ConstPtrParameter)), *S, Context);
+  for (const auto &Match : Matches)
+    Handler(Match.getNodeAs<UnaryOperator>("arg"));
+  Matches = match(findAll(cxxConstructExpr(ConstPtrParameter)), *S, Context);
+  for (const auto &Match : Matches)
+    Handler(Match.getNodeAs<UnaryOperator>("arg"));
+}
+
+static bool isImplicitInitializer(const VarDecl *VD) {
+  assert(VD->hasInit());
+  const auto *E = VD->getInit();
+  if (isa<ExprWithCleanups>(E))
+    return false;
+  const auto *Construct = dyn_cast<CXXConstructExpr>(E);
+  if (!Construct)
+    return E->getLocStart() == VD->getLocation();
+  return Construct->getParenOrBraceRange().isInvalid();
+}
+
+static const Expr *getInitializerExprWithLexicalRange(const Expr *E) {
+  if (const auto *EWC = dyn_cast<ExprWithCleanups>(E)) {
+    if (const auto *Construct = dyn_cast<CXXConstructExpr>(EWC->getSubExpr())) {
+      if (Construct->getNumArgs() == 1) {
+        if (const auto *ME =
+                dyn_cast<MaterializeTemporaryExpr>(Construct->getArg(0)))
+          return ME;
+      }
+    }
+  }
+  return E;
+}
+
+namespace {
+
+class ExtractedCodeVisitor : public RecursiveASTVisitor<ExtractedCodeVisitor> {
+  int DefineOrdering = 0;
+
+public:
+  struct CaptureInfo {
+    bool IsMutated = false;
+    bool IsDefined = false;
+    bool IsAddressTaken = false;
+    bool IsConstAddressTaken = false;
+    bool IsFieldCapturedWithThis = false;
+    bool IsUsed = false;
+    int DefineOrderingPriority = 0;
+
+    bool isPassedByRefOrPtr() const {
+      return IsMutated || IsAddressTaken || IsConstAddressTaken;
+    }
+    bool isRefOrPtrConst() const {
+      return IsConstAddressTaken && !IsMutated && !IsAddressTaken;
+    }
+  };
+
+  const ImplicitParamDecl *SelfDecl;
+
+  ExtractedCodeVisitor(const ImplicitParamDecl *SelfDecl)
+      : SelfDecl(SelfDecl) {}
+
+  bool HasReturnInExtracted = false;
+
+  CaptureInfo &captureVariable(const VarDecl *VD) {
+    CaptureInfo &Result = CapturedVariables[VD];
+    Result.IsUsed = true;
+    return Result;
+  }
+
+  CaptureInfo &captureField(const FieldDecl *FD) { return CapturedFields[FD]; }
+
+  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+    const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
+    if (!VD)
+      return true;
+    if (VD == SelfDecl) {
+      CaptureSelf = true;
+      SelfType = VD->getType();
+      return true;
+    }
+    if (!VD->isLocalVarDeclOrParm())
+      return true;
+    captureVariable(VD);
+    return true;
+  }
+
+  void captureThisWithoutConstConcerns(const CXXThisExpr *E) {
+    CaptureThis = true;
+    ThisRecordType = E->getType()->getPointeeType();
+  }
+
+  bool VisitCXXThisExpr(const CXXThisExpr *E) {
+    captureThisWithoutConstConcerns(E);
+    ThisUsesWithUnknownConstness.insert(E);
+    return true;
+  }
+
+  bool TraverseMemberExpr(MemberExpr *E) {
+    const auto *Base = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts());
+    if (!Base)
+      return RecursiveASTVisitor::TraverseMemberExpr(E);
+    const FieldDecl *FD = dyn_cast_or_null<FieldDecl>(E->getMemberDecl());
+    if (!FD)
+      return RecursiveASTVisitor::TraverseMemberExpr(E);
+    CaptureInfo &Info = captureField(FD);
+    // Don't capture the implicit 'this' for private fields as we don't want to
+    // capture this if we only use the private fields.
+    if (FD->getAccess() == AS_public || !Base->isImplicit()) {
+      Info.IsFieldCapturedWithThis = true;
+      // The member might have an effect on the constness of the captured 'this'
+      // but this is checked via mutation/const tracking for the field itself,
+      // so we just capture 'this' without worrying about checking if it's used
+      // in a 'const' manner here.
+      captureThisWithoutConstConcerns(Base);
+    }
+    return true;
+  }
+
+  void captureSuper(QualType T) {
+    if (CaptureSuper)
+      return;
+    SuperType = T;
+    CaptureSuper = true;
+  }
+
+  bool TraverseObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+    if (E->isSuperReceiver())
+      captureSuper(E->getSuperReceiverType());
+    // Base might be an opaque expression, so we have to visit it manually as
+    // we don't necessarily visit the setter/getter message sends if just the
+    // property was selected.
+    if (E->isObjectReceiver()) {
+      if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E->getBase()))
+        TraverseStmt(OVE->getSourceExpr());
+    }
+    return RecursiveASTVisitor::TraverseObjCPropertyRefExpr(E);
+  }
+
+  bool TraverseBinAssign(BinaryOperator *S) {
+    // RHS might be an opaque expression, if this is a property assignment. We
+    // have to visit it manually as we don't necessarily visit the setter/getter
+    // message sends if just the property was selected.
+    if (const auto *OVE = dyn_cast<OpaqueValueExpr>(S->getRHS()))
+      TraverseStmt(OVE->getSourceExpr());
+    return RecursiveASTVisitor::TraverseBinAssign(S);
+  }
+
+  void findCapturedVariableOrFieldsInExpression(
+      const Expr *E, llvm::function_ref<void(CaptureInfo &)> Handler) {
+    findEntitiesDirectlyReferencedInExpr(
+        E, [&Handler, this](const ReferencedEntity &Entity) {
+          if (const auto *DRE = Entity.dyn_cast<const DeclRefExpr *>()) {
+            const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
+            if (!VD || !VD->isLocalVarDeclOrParm() || VD->isImplicit())
+              return;
+            return Handler(captureVariable(VD));
+          }
+          return Handler(captureField(Entity.get<const FieldDecl *>()));
+        });
+  }
+
+  void
+  markDirectlyReferencedVariableOrFieldInExpressionAsMutated(const Expr *E) {
+    findCapturedVariableOrFieldsInExpression(
+        E, [](CaptureInfo &Capture) { Capture.IsMutated = true; });
+  }
+
+  bool VisitBinaryOperator(const BinaryOperator *E) {
+    if (E->isAssignmentOp())
+      markDirectlyReferencedVariableOrFieldInExpressionAsMutated(E->getLHS());
+    return true;
+  }
+
+  bool VisitUnaryPreInc(const UnaryOperator *E) {
+    markDirectlyReferencedVariableOrFieldInExpressionAsMutated(E->getSubExpr());
+    return true;
+  }
+
+  bool VisitUnaryPostInc(const UnaryOperator *E) {
+    markDirectlyReferencedVariableOrFieldInExpressionAsMutated(E->getSubExpr());
+    return true;
+  }
+
+  bool VisitUnaryPreDec(const UnaryOperator *E) {
+    markDirectlyReferencedVariableOrFieldInExpressionAsMutated(E->getSubExpr());
+    return true;
+  }
+
+  bool VisitUnaryPostDec(const UnaryOperator *E) {
+    markDirectlyReferencedVariableOrFieldInExpressionAsMutated(E->getSubExpr());
+    return true;
+  }
+
+  /// If the given expression refers to a local/instance variable or a
+  /// a member of such variable that variable is marked as captured by
+  /// reference.
+  void captureVariableOrFieldInExpressionByReference(const Expr *E) {
+    findCapturedVariableOrFieldsInExpression(
+        E, [](CaptureInfo &Capture) { Capture.IsAddressTaken = true; });
+  }
+
+  bool VisitUnaryAddrOf(const UnaryOperator *E) {
+    // Capture the entity with 'const' reference/pointer when its address is
+    // passed into a function that takes a 'const' pointer and no other
+    // mutations or non-const address/reference acquisitions occur.
+    if (AddressExpressionsPassedToConstPointerParameter.count(E))
+      findCapturedVariableOrFieldsInExpression(
+          E->getSubExpr(),
+          [](CaptureInfo &Capture) { Capture.IsConstAddressTaken = true; });
+    else
+      captureVariableOrFieldInExpressionByReference(E->getSubExpr());
+    return true;
+  }
+
+  bool VisitObjCMessageExpr(const ObjCMessageExpr *E) {
+    if (E->getSuperLoc().isValid())
+      captureSuper(E->getSuperType());
+    const ObjCMethodDecl *MD = E->getMethodDecl();
+    if (!MD)
+      return true;
+    for (const auto &Param : llvm::enumerate(MD->parameters())) {
+      QualType T = Param.value()->getType();
+      if (Param.index() >= E->getNumArgs())
+        break;
+      if (T->isReferenceType() && !T->getPointeeType().isConstQualified())
+        captureVariableOrFieldInExpressionByReference(E->getArg(Param.index()));
+      if (T->isPointerType() && T->getPointeeType().isConstQualified()) {
+        // Check if this is an '&' passed into a const pointer parameter.
+        const Expr *Arg = E->getArg(Param.index());
+        if (const auto *Op =
+                dyn_cast<UnaryOperator>(Arg->IgnoreParenImpCasts())) {
+          if (Op->getOpcode() == UO_AddrOf)
+            AddressExpressionsPassedToConstPointerParameter.insert(Op);
+        }
+      }
+    }
+    return true;
+  }
+
+  bool VisitVarDecl(const VarDecl *VD) {
+    // Don't capture using the captureVariable method as we don't want to mark
+    // the declaration as a 'use'. This allows us to avoid passing in variables
+    // that are defined in extracted code, used afterwards, but never actually
+    // used in the extracted code.
+    CaptureInfo &Capture = CapturedVariables[VD];
+    Capture.IsDefined = true;
+    Capture.DefineOrderingPriority = ++DefineOrdering;
+    // Ensure the capture is marked as 'used' when the variable declaration has
+    // an explicit initialization expression. This allows us to pass it by
+    // reference when it's defined in extracted code, used afterwards, but never
+    // actually used in the extracted code. The main reason why we want to try
+    // to keep this initialization in the extracted code is to preserve
+    // semantics as the initialization expression might have side-effects.
+    if (!Capture.IsUsed && VD->hasInit() && !isImplicitInitializer(VD))
+      Capture.IsUsed = true;
+    QualType T = VD->getType();
+    if (T->isReferenceType() && !T->getPointeeType().isConstQualified() &&
+        VD->hasInit())
+      captureVariableOrFieldInExpressionByReference(VD->getInit());
+    return true;
+  }
+
+  bool VisitReturnStmt(const ReturnStmt *S) {
+    HasReturnInExtracted = true;
+    return true;
+  }
+
+  void InspectExtractedStmt(Stmt *S, ASTContext &Context) {
+    findAddressExpressionsPassedByConstPointer(
+        S, Context, [this](const UnaryOperator *Arg) {
+          AddressExpressionsPassedToConstPointerParameter.insert(Arg);
+        });
+    TraverseStmt(S);
+    findArgumentsPassedByNonConstReference(S, Context, [this](const Expr *Arg) {
+      captureVariableOrFieldInExpressionByReference(Arg);
+    });
+    if (CaptureThis && !ThisUsesWithUnknownConstness.empty()) {
+      // Compare the definite 'const' uses of 'this' to all the seen uses
+      // (except for the known field uses).
+      findUseOfConstThis(S, Context, [this](const CXXThisExpr *Arg) {
+        ThisUsesWithUnknownConstness.erase(Arg);
+      });
+      IsThisConstForNonCapturedFieldUses = ThisUsesWithUnknownConstness.empty();
+    }
+  }
+
+  llvm::DenseMap<const VarDecl *, CaptureInfo> CapturedVariables;
+  llvm::DenseMap<const FieldDecl *, CaptureInfo> CapturedFields;
+  llvm::SmallPtrSet<const UnaryOperator *, 8>
+      AddressExpressionsPassedToConstPointerParameter;
+  llvm::SmallPtrSet<const CXXThisExpr *, 16> ThisUsesWithUnknownConstness;
+  bool CaptureThis = false;
+  bool IsThisConstForNonCapturedFieldUses = true;
+  QualType ThisRecordType;
+  bool CaptureSelf = false, CaptureSuper = false;
+  QualType SelfType, SuperType;
+};
+
+/// Traverses the extracted code and finds the uses of captured variables
+/// that are passed into the extracted function using a pointer.
+class VariableDefinedInExtractedCodeUseAfterExtractionFinder
+    : public RecursiveASTVisitor<
+          VariableDefinedInExtractedCodeUseAfterExtractionFinder> {
+  bool IsAfterExtracted = false;
+
+public:
+  const Stmt *LastExtractedStmt;
+  const llvm::SmallPtrSetImpl<const VarDecl *> &VariablesDefinedInExtractedCode;
+  llvm::SmallPtrSet<const VarDecl *, 4> VariablesUsedAfterExtraction;
+
+  VariableDefinedInExtractedCodeUseAfterExtractionFinder(
+      const Stmt *LastExtractedStmt,
+      const llvm::SmallPtrSetImpl<const VarDecl *>
+          &VariablesDefinedInExtractedCode)
+      : LastExtractedStmt(LastExtractedStmt),
+        VariablesDefinedInExtractedCode(VariablesDefinedInExtractedCode) {}
+
+  bool TraverseStmt(Stmt *S) {
+    RecursiveASTVisitor::TraverseStmt(S);
+    if (S == LastExtractedStmt)
+      IsAfterExtracted = true;
+    return true;
+  }
+
+  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+    if (!IsAfterExtracted)
+      return true;
+    const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
+    if (!VD)
+      return true;
+    if (VariablesDefinedInExtractedCode.count(VD))
+      VariablesUsedAfterExtraction.insert(VD);
+    return true;
+  }
+};
+
+class PossibleShadowingVariableFinder
+    : public RecursiveASTVisitor<PossibleShadowingVariableFinder> {
+  const VarDecl *TargetVD;
+
+  PossibleShadowingVariableFinder(const VarDecl *TargetVD)
+      : TargetVD(TargetVD) {}
+
+public:
+  bool VisitVarDecl(const VarDecl *VD) {
+    if (VD == TargetVD || VD->getName() != TargetVD->getName())
+      return true;
+    return false;
+  }
+
+  /// Returns true if the given statement \p S has a variable declaration whose
+  /// name is identical to the given variable declaration \p VD.
+  static bool hasShadowingVar(const VarDecl *VD, const Stmt *S) {
+    return !PossibleShadowingVariableFinder(VD).TraverseStmt(
+        const_cast<Stmt *>(S));
+  }
+};
+
+/// Traverses the extracted code and rewrites the 'return' statements to ensure
+/// that they now return some value.
+class ReturnRewriter : public RecursiveASTVisitor<ReturnRewriter> {
+  Rewriter &SourceRewriter;
+  std::string Text;
+
+public:
+  ReturnRewriter(Rewriter &SourceRewriter, StringRef Text)
+      : SourceRewriter(SourceRewriter), Text(std::string(" ") + Text.str()) {}
+
+  bool VisitReturnStmt(const ReturnStmt *S) {
+    SourceRewriter.InsertText(
+        getPreciseTokenLocEnd(S->getLocEnd(), SourceRewriter.getSourceMgr(),
+                              SourceRewriter.getLangOpts()),
+        Text);
+    return true;
+  }
+};
+
+/// Prints the given initializer expression using the original source code if
+/// possible.
+static void printInitializerExpressionUsingOriginalSyntax(
+    const VarDecl *VD, const Expr *E, bool IsDeclaration, const ASTContext &Ctx,
+    llvm::raw_ostream &OS, const PrintingPolicy &PP) {
+  E = getInitializerExprWithLexicalRange(E);
+  SourceRange Range = E->getSourceRange();
+  bool UseEquals = true;
+  bool UseTypeName = false;
+  if (const auto *Construct = dyn_cast<CXXConstructExpr>(E)) {
+    SourceRange SubRange = Construct->getParenOrBraceRange();
+    if (SubRange.isValid()) {
+      UseEquals = false;
+      UseTypeName = true;
+      Range = SubRange;
+    }
+  }
+  if (Range.getBegin().isMacroID())
+    Range.setBegin(Ctx.getSourceManager().getExpansionLoc(Range.getBegin()));
+  if (Range.getEnd().isMacroID())
+    Range.setEnd(Ctx.getSourceManager().getExpansionLoc(Range.getEnd()));
+  bool IsInvalid = false;
+  StringRef Text = Lexer::getSourceText(CharSourceRange::getTokenRange(Range),
+                                        Ctx.getSourceManager(),
+                                        Ctx.getLangOpts(), &IsInvalid);
+  if (IsDeclaration && UseEquals)
+    OS << " = ";
+  else if (!IsDeclaration && UseTypeName)
+    VD->getType().print(OS, PP);
+  if (IsInvalid)
+    E->printPretty(OS, nullptr, PP);
+  else
+    OS << Text;
+};
+
+/// Traverses the extracted code and rewrites the declaration statements that
+/// declare variables that are used after the extracted code.
+class DefinedInExtractedCodeDeclStmtRewriter
+    : public RecursiveASTVisitor<DefinedInExtractedCodeDeclStmtRewriter> {
+public:
+  Rewriter &SourceRewriter;
+  const llvm::SmallPtrSetImpl<const VarDecl *> &VariablesUsedAfterExtraction;
+  const PrintingPolicy &PP;
+
+  DefinedInExtractedCodeDeclStmtRewriter(
+      Rewriter &SourceRewriter, const llvm::SmallPtrSetImpl<const VarDecl *>
+                                    &VariablesUsedAfterExtraction,
+      const PrintingPolicy &PP)
+      : SourceRewriter(SourceRewriter),
+        VariablesUsedAfterExtraction(VariablesUsedAfterExtraction), PP(PP) {}
+
+  /// When a declaration statement declares variables that are all used
+  /// after extraction, we can rewrite it completely into a set of assignments
+  /// while still preserving the original initializer expressions when we
+  /// can.
+  void rewriteAllVariableDeclarationsToAssignments(const DeclStmt *S) {
+    SourceLocation StartLoc = S->getLocStart();
+    for (const Decl *D : S->decls()) {
+      const auto *VD = dyn_cast<VarDecl>(D);
+      if (!VD || !VariablesUsedAfterExtraction.count(VD))
+        continue;
+      if (!VD->hasInit() || isImplicitInitializer(VD)) {
+        // Remove the variable declarations without explicit initializers.
+        // This can affect the semantics of the program if the implicit
+        // initialization expression has side effects.
+        SourceRange Range = SourceRange(
+            StartLoc, S->isSingleDecl() ? S->getLocEnd() : VD->getLocation());
+        SourceRewriter.RemoveText(Range);
+        continue;
+      }
+      std::string Str;
+      llvm::raw_string_ostream OS(Str);
+      if (StartLoc != S->getLocStart())
+        OS << "; ";
+      const ASTContext &Ctx = D->getASTContext();
+      // Dereference the variable unless the source uses C++.
+      if (!Ctx.getLangOpts().CPlusPlus)
+        OS << '*';
+      OS << VD->getName() << " = ";
+      const Expr *Init = getInitializerExprWithLexicalRange(VD->getInit());
+      SourceLocation End = Init->getLocStart();
+      if (const auto *Construct = dyn_cast<CXXConstructExpr>(Init)) {
+        SourceRange SubRange = Construct->getParenOrBraceRange();
+        if (SubRange.isValid()) {
+          End = SubRange.getBegin();
+          VD->getType().print(OS, PP);
+        }
+      }
+      if (End.isMacroID())
+        End = Ctx.getSourceManager().getExpansionLoc(End);
+      auto Range = CharSourceRange::getCharRange(StartLoc, End);
+      SourceRewriter.ReplaceText(StartLoc, SourceRewriter.getRangeSize(Range),
+                                 OS.str());
+      StartLoc = getPreciseTokenLocEnd(D->getLocEnd(), Ctx.getSourceManager(),
+                                       Ctx.getLangOpts());
+    }
+  }
+
+  /// When a declaration statement has variables that are both used after
+  /// extraction and not used after extraction, we create new declaration
+  /// statements that declare the unused variables, while creating assignment
+  /// statements that "initialize" the variables that are used after the
+  /// extraction. This way we can preserve the order of
+  /// initialization/assignment from the original declaration statement.
+  void rewriteMixedDeclarations(const DeclStmt *S) {
+    // Completely rewrite the declaration statement.
+    std::string Str;
+    llvm::raw_string_ostream OS(Str);
+    for (const Decl *D : S->decls()) {
+      const ASTContext &Ctx = D->getASTContext();
+      const VarDecl *VD = dyn_cast<VarDecl>(D);
+      bool IsLast = D == S->decl_end()[-1];
+      if (!VD) {
+        OS << "<<unsupported declaration>>;";
+        continue;
+      }
+
+      auto PrintInit = [&](bool IsDeclaration) {
+        printInitializerExpressionUsingOriginalSyntax(
+            VD, VD->getInit(), IsDeclaration, Ctx, OS, PP);
+      };
+      if (!VariablesUsedAfterExtraction.count(VD)) {
+        VD->getType().print(OS, PP);
+        OS << " " << VD->getName();
+        if (VD->hasInit() && !isImplicitInitializer(VD))
+          PrintInit(/*IsDeclaration=*/true);
+        OS << ";";
+        if (!IsLast)
+          OS << ' ';
+        continue;
+      }
+      if (VD->hasInit() && !isImplicitInitializer(VD)) {
+        // Dereference the variable unless the source uses C++.
+        if (!Ctx.getLangOpts().CPlusPlus)
+          OS << '*';
+        OS << VD->getName() << " = ";
+        PrintInit(/*IsDeclaration=*/false);
+        OS << ";";
+        if (!IsLast)
+          OS << ' ';
+      }
+    }
+    SourceRewriter.ReplaceText(S->getSourceRange(), OS.str());
+  }
+
+  bool VisitDeclStmt(const DeclStmt *S) {
+    bool AreAllUsed = true;
+    bool AreNoneUsed = true;
+    for (const Decl *D : S->decls()) {
+      const auto *VD = dyn_cast<VarDecl>(D);
+      if (!VD || !VariablesUsedAfterExtraction.count(VD)) {
+        AreAllUsed = false;
+        continue;
+      }
+      AreNoneUsed = false;
+      // Exit early when both flags were set in the loop.
+      if (!AreAllUsed)
+        break;
+    }
+    if (AreNoneUsed)
+      return true;
+
+    if (AreAllUsed)
+      rewriteAllVariableDeclarationsToAssignments(S);
+    else
+      rewriteMixedDeclarations(S);
+    return true;
+  }
+};
+
+/// Takes care of pseudo object expressions and Objective-C properties to avoid
+/// duplicate rewrites and missing rewrites.
+template <typename T>
+class PseudoObjectRewriter : public RecursiveASTVisitor<T> {
+  typedef RecursiveASTVisitor<T> Base;
+
+public:
+  bool TraversePseudoObjectExpr(PseudoObjectExpr *E) {
+    return Base::TraverseStmt(E->getSyntacticForm());
+  }
+
+  bool TraverseObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+    // Base might be an opaque expression, so we have to visit it manually as
+    // we don't necessarily visit the setter/getter message sends if just the
+    // property was selected.
+    if (E->isObjectReceiver()) {
+      if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E->getBase()))
+        Base::TraverseStmt(OVE->getSourceExpr());
+    }
+    return Base::TraverseObjCPropertyRefExpr(E);
+  }
+
+  bool TraverseBinAssign(BinaryOperator *S) {
+    // RHS might be an opaque expression, if this is a property assignment. We
+    // have to visit it manually as we don't necessarily visit the setter/getter
+    // message sends if just the property was selected.
+    if (const auto *OVE = dyn_cast<OpaqueValueExpr>(S->getRHS()))
+      Base::TraverseStmt(OVE->getSourceExpr());
+    return Base::TraverseBinAssign(S);
+  }
+};
+
+/// Traverses the extracted code and rewrites the uses of captured variables
+/// that are passed into the extracted function using a pointer.
+class CapturedVariableCaptureByPointerRewriter
+    : public PseudoObjectRewriter<CapturedVariableCaptureByPointerRewriter> {
+public:
+  const VarDecl *TargetVD;
+  Rewriter &SourceRewriter;
+
+  CapturedVariableCaptureByPointerRewriter(const VarDecl *VD,
+                                           Rewriter &SourceRewriter)
+      : TargetVD(VD), SourceRewriter(SourceRewriter) {}
+
+  bool isTargetDeclRefExpr(const Expr *E) {
+    const auto *DRE = dyn_cast<DeclRefExpr>(E);
+    if (!DRE)
+      return false;
+    return dyn_cast<VarDecl>(DRE->getDecl()) == TargetVD;
+  }
+
+  void dereferenceTargetVar(const Expr *E, bool WrapInParens = false) {
+    SourceRewriter.InsertTextBefore(E->getLocStart(),
+                                    WrapInParens ? "(*" : "*");
+    if (WrapInParens)
+      SourceRewriter.InsertTextAfterToken(E->getLocEnd(), ")");
+  }
+
+  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+    const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
+    if (VD != TargetVD)
+      return true;
+    dereferenceTargetVar(E);
+    return true;
+  }
+
+  bool TraverseUnaryAddrOf(UnaryOperator *E) {
+    if (const auto *DRE =
+            dyn_cast<DeclRefExpr>(E->getSubExpr()->IgnoreParenCasts())) {
+      const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
+      if (VD == TargetVD) {
+        // Remove the '&' as the variable is now a pointer.
+        SourceRewriter.RemoveText(
+            CharSourceRange::getTokenRange(E->getLocStart(), E->getLocStart()));
+        return true;
+      }
+    }
+    return RecursiveASTVisitor::TraverseUnaryAddrOf(E);
+  }
+
+  bool TraverseMemberExpr(MemberExpr *E) {
+    if (!E->isArrow()) {
+      if (const auto *DRE =
+              dyn_cast<DeclRefExpr>(E->getBase()->IgnoreParenCasts())) {
+        const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
+        if (VD == TargetVD) {
+          // Replace '.' with '->'.
+          SourceRewriter.ReplaceText(E->getOperatorLoc(), 1, "->");
+          return true;
+        }
+      }
+    } else if (isTargetDeclRefExpr(E->getBase()->IgnoreImpCasts())) {
+      // Ensure the variable is wrapped in parenthesis when it's the base of
+      // '->' operator.
+      dereferenceTargetVar(E->getBase(), /*WrapInParens=*/true);
+      return true;
+    }
+    return RecursiveASTVisitor::TraverseMemberExpr(E);
+  }
+};
+
+/// Traverses the extracted code and rewrites the uses of 'this' that can be
+/// rewritten as references.
+class CapturedThisReferenceRewriter
+    : public PseudoObjectRewriter<CapturedThisReferenceRewriter> {
+public:
+  Rewriter &SourceRewriter;
+  llvm::SmallPtrSet<const CXXThisExpr *, 8> RewrittenExpressions;
+
+  CapturedThisReferenceRewriter(Rewriter &SourceRewriter)
+      : SourceRewriter(SourceRewriter) {}
+
+  void rewriteThis(const CXXThisExpr *E) {
+    RewrittenExpressions.insert(E);
+    if (!E->isImplicit())
+      SourceRewriter.ReplaceText(E->getLocStart(), 4, "object");
+    else
+      SourceRewriter.InsertText(E->getLocStart(), "object");
+  }
+
+  bool VisitMemberExpr(const MemberExpr *E) {
+    const auto *This =
+        dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts());
+    if (This) {
+      rewriteThis(This);
+      if (!This->isImplicit() && E->isArrow())
+        SourceRewriter.ReplaceText(E->getOperatorLoc(), 2, ".");
+      else
+        SourceRewriter.InsertText(E->getBase()->getLocEnd(), ".");
+    }
+    return true;
+  }
+};
+
+/// Traverses the extracted code and rewrites the uses of 'this' into '&object'.
+class CapturedThisPointerRewriter
+    : public PseudoObjectRewriter<CapturedThisPointerRewriter> {
+public:
+  Rewriter &SourceRewriter;
+  const llvm::SmallPtrSetImpl<const CXXThisExpr *> &RewrittenExpressions;
+
+  CapturedThisPointerRewriter(
+      Rewriter &SourceRewriter,
+      const llvm::SmallPtrSetImpl<const CXXThisExpr *> &RewrittenExpressions)
+      : SourceRewriter(SourceRewriter),
+        RewrittenExpressions(RewrittenExpressions) {}
+
+  void replace(const CXXThisExpr *E, StringRef Text) {
+    SourceRewriter.ReplaceText(E->getLocStart(), 4, Text);
+  }
+
+  bool VisitCXXThisExpr(const CXXThisExpr *E) {
+    if (RewrittenExpressions.count(E))
+      return true;
+    if (!E->isImplicit())
+      replace(E, "&object");
+    return true;
+  }
+
+  bool TraverseUnaryDeref(UnaryOperator *E) {
+    if (const auto *This =
+            dyn_cast<CXXThisExpr>(E->getSubExpr()->IgnoreParenImpCasts())) {
+      if (!This->isImplicit()) {
+        // Remove the '*' as the variable is now a reference.
+        SourceRewriter.RemoveText(
+            CharSourceRange::getTokenRange(E->getLocStart(), E->getLocStart()));
+        replace(This, "object");
+        return true;
+      }
+    }
+    return RecursiveASTVisitor::TraverseUnaryAddrOf(E);
+  }
+};
+
+/// Traverses the extracted code and rewrites the uses of 'self' into 'object'.
+class CapturedSelfRewriter : public PseudoObjectRewriter<CapturedSelfRewriter> {
+public:
+  Rewriter &SourceRewriter;
+  const ImplicitParamDecl *SelfDecl;
+
+  CapturedSelfRewriter(Rewriter &SourceRewriter,
+                       const ImplicitParamDecl *SelfDecl)
+      : SourceRewriter(SourceRewriter), SelfDecl(SelfDecl) {
+    assert(SelfDecl);
+  }
+
+  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+    const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
+    if (!VD || VD != SelfDecl)
+      return true;
+    if (E->getLocStart().isInvalid())
+      return true;
+    SourceRewriter.ReplaceText(E->getLocStart(), 4, "object");
+    return true;
+  }
+
+  void insertObjectForImplicitSelf(const Expr *E, SourceLocation Loc,
+                                   StringRef Text) {
+    const auto *DRE = dyn_cast<DeclRefExpr>(E);
+    if (!DRE)
+      return;
+    const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl());
+    if (!VD || VD != SelfDecl || DRE->getLocStart().isValid())
+      return;
+    SourceRewriter.InsertText(Loc, Text);
+  }
+
+  bool VisitObjCIvarRefExpr(const ObjCIvarRefExpr *E) {
+    insertObjectForImplicitSelf(E->getBase()->IgnoreImpCasts(),
+                                E->getLocStart(), "object->");
+    return true;
+  }
+};
+
+/// Traverses the extracted code and rewrites the uses of 'self' into the name
+/// of the class.
+class CapturedClassSelfRewriter
+    : public PseudoObjectRewriter<CapturedClassSelfRewriter> {
+public:
+  Rewriter &SourceRewriter;
+  StringRef ClassName;
+  const ImplicitParamDecl *SelfDecl;
+
+  CapturedClassSelfRewriter(Rewriter &SourceRewriter, StringRef ClassName,
+                            const ImplicitParamDecl *SelfDecl)
+      : SourceRewriter(SourceRewriter), ClassName(ClassName),
+        SelfDecl(SelfDecl) {
+
+    assert(SelfDecl);
+  }
+
+  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+    const VarDecl *VD = dyn_cast<VarDecl>(E->getDecl());
+    if (!VD || VD != SelfDecl || E->getLocStart().isInvalid())
+      return true;
+    SourceRewriter.ReplaceText(E->getLocStart(), 4, ClassName);
+    return true;
+  }
+};
+
+/// Traverses the extracted code and rewrites the uses of 'super' into
+/// 'superObject' or the name of the super class.
+class CapturedSuperRewriter
+    : public PseudoObjectRewriter<CapturedSuperRewriter> {
+public:
+  Rewriter &SourceRewriter;
+  StringRef ReplacementString;
+
+  CapturedSuperRewriter(Rewriter &SourceRewriter, StringRef ReplacementString)
+      : SourceRewriter(SourceRewriter), ReplacementString(ReplacementString) {}
+
+  void rewriteSuper(SourceLocation Loc) {
+    SourceRewriter.ReplaceText(Loc, strlen("super"), ReplacementString);
+  }
+
+  bool VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *E) {
+    if (E->isSuperReceiver())
+      rewriteSuper(E->getReceiverLocation());
+    return true;
+  }
+
+  bool VisitObjCMessageExpr(const ObjCMessageExpr *E) {
+    if (E->getSuperLoc().isValid())
+      rewriteSuper(E->getSuperLoc());
+    return true;
+  }
+};
+
+struct ExtractionSemicolonPolicy {
+  bool IsNeededInExtractedFunction;
+  bool IsNeededInOriginalFunction;
+
+  static ExtractionSemicolonPolicy neededInExtractedFunction() {
+    return {true, false};
+  }
+  static ExtractionSemicolonPolicy neededInOriginalFunction() {
+    return {false, true};
+  }
+  static ExtractionSemicolonPolicy neededInBoth() { return {true, true}; }
+};
+
+} // end anonymous namespace
+
+ExtractionSemicolonPolicy
+computeSemicolonExtractionPolicy(const Stmt *S, SourceRange &ExtractedRange,
+                                 const SourceManager &SM,
+                                 const LangOptions &LangOpts) {
+  if (isa<Expr>(S))
+    return ExtractionSemicolonPolicy::neededInExtractedFunction();
+  bool NeedsSemi = isSemicolonRequiredAfter(S);
+  if (!NeedsSemi)
+    return ExtractionSemicolonPolicy::neededInOriginalFunction();
+  SourceLocation End = ExtractedRange.getEnd();
+  if (isSemicolonAtLocation(End, SM, LangOpts))
+    return ExtractionSemicolonPolicy::neededInOriginalFunction();
+  SourceLocation NextTokenLoc =
+      Lexer::findNextTokenLocationAfterTokenAt(End, SM, LangOpts);
+  if (NextTokenLoc.isValid() &&
+      isSemicolonAtLocation(NextTokenLoc, SM, LangOpts) &&
+      areOnSameLine(NextTokenLoc, End, SM)) {
+    ExtractedRange.setEnd(NextTokenLoc);
+    return ExtractionSemicolonPolicy::neededInOriginalFunction();
+  }
+  return ExtractionSemicolonPolicy::neededInBoth();
+}
+
+PrintingPolicy getPrintingPolicy(const ASTContext &Context,
+                                 const Preprocessor &PP) {
+  PrintingPolicy Policy = Context.getPrintingPolicy();
+  // Our printing policy is copied over the ASTContext printing policy whenever
+  // a diagnostic is emitted, so recompute it.
+  Policy.Bool = Context.getLangOpts().Bool;
+  // FIXME: This is duplicated with Sema.cpp. When upstreaming this should be
+  // cleaned up.
+  if (!Policy.Bool) {
+    if (const MacroInfo *BoolMacro = PP.getMacroInfo(Context.getBoolName())) {
+      Policy.Bool = BoolMacro->isObjectLike() &&
+                    BoolMacro->getNumTokens() == 1 &&
+                    BoolMacro->getReplacementToken(0).is(tok::kw__Bool);
+    }
+  }
+  return Policy;
+}
+
+static QualType getFunctionLikeParentDeclReturnType(const Decl *D) {
+  // FIXME: might need to handle ObjC blocks in the future.
+  if (const auto *M = dyn_cast<ObjCMethodDecl>(D))
+    return M->getReturnType();
+  return cast<FunctionDecl>(D)->getReturnType();
+}
+
+static const Stmt *getEnclosingDeclBody(const Decl *D) {
+  // FIXME: might need to handle ObjC blocks in the future.
+  if (const auto *M = dyn_cast<ObjCMethodDecl>(D))
+    return M->getBody();
+  return cast<FunctionDecl>(D)->getBody();
+}
+
+static bool isEnclosingMethodConst(const Decl *D) {
+  if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
+    return MD->isConst();
+  return false;
+}
+
+static bool isEnclosingMethodStatic(const Decl *D) {
+  if (const auto *MD = dyn_cast<CXXMethodDecl>(D))
+    return MD->isStatic();
+  return false;
+}
+
+static bool isEnclosingMethodOutOfLine(const Decl *D) {
+  const auto *MD = dyn_cast<CXXMethodDecl>(D);
+  if (!MD)
+    return false;
+  return MD->isOutOfLine();
+}
+
+static void printEnclosingMethodScope(const Decl *D, llvm::raw_ostream &OS,
+                                      const PrintingPolicy &PP) {
+  const auto *MD = dyn_cast<CXXMethodDecl>(D);
+  if (!MD)
+    return;
+  if (!MD->isOutOfLine() || !MD->getQualifier())
+    return;
+  MD->getQualifier()->print(OS, PP);
+}
+
+static SourceLocation
+computeFunctionExtractionLocation(const Decl *D, bool IsMethodExtraction) {
+  if (!IsMethodExtraction && isa<CXXMethodDecl>(D)) {
+    // Code from methods that defined in class bodies should be extracted to a
+    // function defined just before the class.
+    while (const auto *RD = dyn_cast<CXXRecordDecl>(D->getLexicalDeclContext()))
+      D = RD;
+  }
+  return D->getLocStart();
+}
+
+namespace {
+enum class MethodDeclarationPlacement { After, Before };
+
+/// \brief Represents an entity captured from the original function that's
+/// passed into the new function/method.
+struct CapturedVariable {
+  const VarDecl *VD;
+  const FieldDecl *FD;
+  QualType ThisType;
+  bool PassByRefOrPtr;
+  bool IsRefOrPtrConst;
+  bool IsThisSelf = false;
+  bool IsThisSuper = false;
+  bool TakeAddress = false;
+  QualType ParameterType;
+
+  CapturedVariable(const VarDecl *VD, bool PassByRefOrPtr, bool IsRefOrPtrConst)
+      : VD(VD), FD(nullptr), PassByRefOrPtr(PassByRefOrPtr),
+        IsRefOrPtrConst(IsRefOrPtrConst) {}
+  CapturedVariable(const FieldDecl *FD, bool PassByRefOrPtr,
+                   bool IsRefOrPtrConst)
+      : VD(nullptr), FD(FD), PassByRefOrPtr(PassByRefOrPtr),
+        IsRefOrPtrConst(IsRefOrPtrConst) {}
+  CapturedVariable(QualType ThisType, bool PassByRefOrPtr, bool IsConst)
+      : VD(nullptr), FD(nullptr), ThisType(ThisType),
+        PassByRefOrPtr(PassByRefOrPtr), IsRefOrPtrConst(IsConst) {}
+
+  static CapturedVariable getThis(QualType T, bool IsConst) {
+    return CapturedVariable(T, /*PassByRefOrPtr=*/true, /*IsConst*/ IsConst);
+  }
+
+  static CapturedVariable getSelf(QualType T) {
+    auto Result =
+        CapturedVariable(T, /*PassByRefOrPtr=*/false, /*IsConst*/ false);
+    Result.IsThisSelf = true;
+    return Result;
+  }
+
+  static CapturedVariable getSuper(QualType T) {
+    auto Result =
+        CapturedVariable(T, /*PassByRefOrPtr=*/false, /*IsConst*/ false);
+    Result.IsThisSuper = true;
+    return Result;
+  }
+
+  StringRef getName() const {
+    return VD ? VD->getName()
+              : FD ? FD->getName() : IsThisSuper ? "superObject" : "object";
+  }
+  StringRef getExpr() const {
+    return ThisType.isNull()
+               ? getName()
+               : IsThisSelf ? "self" : IsThisSuper ? "super.self" : "*this";
+  }
+  QualType getType() const {
+    return VD ? VD->getType() : FD ? FD->getType() : ThisType;
+  }
+};
+} // end anonymous namespace
+
+static std::pair<SourceLocation, MethodDeclarationPlacement>
+computeAppropriateExtractionLocationForMethodDeclaration(
+    const CXXMethodDecl *D) {
+  const CXXRecordDecl *RD = D->getParent();
+  // Try to put the new declaration after the last method, or just before the
+  // end of the class.
+  SourceLocation Loc;
+  for (const CXXMethodDecl *M : RD->methods()) {
+    if (M->isImplicit())
+      continue;
+    Loc = M->getLocEnd();
+  }
+  return Loc.isValid() ? std::make_pair(Loc, MethodDeclarationPlacement::After)
+                       : std::make_pair(RD->getLocEnd(),
+                                        MethodDeclarationPlacement::Before);
+}
+
+static bool isInHeader(SourceLocation Loc, const SourceManager &SM) {
+  // Base the header decision on the filename.
+  StringRef Extension = llvm::sys::path::extension(SM.getFilename(Loc));
+  if (Extension.empty())
+    return false;
+  return llvm::StringSwitch<bool>(Extension.drop_front())
+      .Case("h", true)
+      .Case("hpp", true)
+      .Case("hh", true)
+      .Case("h++", true)
+      .Case("hxx", true)
+      .Case("inl", true)
+      .Case("def", true)
+      .Default(false);
+}
+
+llvm::Expected<RefactoringResult>
+ExtractOperation::performExpressionExtraction(ASTContext &Context,
+                                              PrintingPolicy &PP) {
+  assert(isExpressionExtraction() && "Not an expression extraction");
+  std::vector<RefactoringReplacement> Replacements;
+  const Expr *E = cast<Expr>(S);
+  QualType VarType = findExpressionLexicalType(FunctionLikeParentDecl, E,
+                                               E->getType(), PP, Context);
+  StringRef VarName = "extractedExpr";
+  auto CreatedSymbol =
+      llvm::make_unique<RefactoringResultAssociatedSymbol>(SymbolName(VarName));
+
+  SourceRange ExtractedTokenRange = CandidateExtractionInfo[0].Range;
+  SourceRange ExtractedCharRange = SourceRange(
+      ExtractedTokenRange.getBegin(),
+      getPreciseTokenLocEnd(ExtractedTokenRange.getEnd(),
+                            Context.getSourceManager(), Context.getLangOpts()));
+
+  // Create the variable that will hold the value of the duplicate expression.
+  std::string VariableDeclarationString;
+  llvm::raw_string_ostream OS(VariableDeclarationString);
+  VarType.print(OS, PP, /*PlaceHolder*/ VarName);
+  // FIXME: We should hook into the TypePrinter when moving over to llvm.org
+  // instead and get the offset from it.
+  unsigned NameOffset = StringRef(OS.str()).find(VarName);
+  OS << " = ";
+  OS << Lexer::getSourceText(CharSourceRange::getCharRange(ExtractedCharRange),
+                             Context.getSourceManager(), Context.getLangOpts());
+  OS << ";\n";
+
+  // Variable declaration.
+  SourceLocation InsertionLoc =
+      extract::locationForExtractedVariableDeclaration(
+          E, FunctionLikeParentDecl, Context.getSourceManager());
+  Replacements.push_back(RefactoringReplacement(
+      SourceRange(InsertionLoc, InsertionLoc), OS.str(), CreatedSymbol.get(),
+      RefactoringReplacement::AssociatedSymbolLocation(
+          llvm::makeArrayRef(NameOffset), /*IsDeclaration=*/true)));
+  // Replace the expression with the variable.
+  Replacements.push_back(
+      RefactoringReplacement(ExtractedCharRange, VarName, CreatedSymbol.get(),
+                             /*NameOffset=*/llvm::makeArrayRef(unsigned(0))));
+
+  RefactoringResult Result(std::move(Replacements));
+  Result.AssociatedSymbols.push_back(std::move(CreatedSymbol));
+  return std::move(Result);
+}
+
+llvm::Expected<RefactoringResult> ExtractOperation::perform(
+    ASTContext &Context, const Preprocessor &ThePreprocessor,
+    const RefactoringOptionSet &Options, unsigned SelectedCandidateIndex) {
+  std::vector<RefactoringReplacement> Replacements;
+  SourceManager &SM = Context.getSourceManager();
+  const LangOptions &LangOpts = Context.getLangOpts();
+  Rewriter SourceRewriter(SM, LangOpts);
+  PrintingPolicy PP = getPrintingPolicy(Context, ThePreprocessor);
+  PP.UseStdFunctionForLambda = true;
+  PP.SuppressStrongLifetime = true;
+  PP.SuppressLifetimeQualifiers = true;
+  PP.SuppressUnwrittenScope = true;
+
+  if (isExpressionExtraction())
+    return performExpressionExtraction(Context, PP);
+
+  const Stmt *S =
+      CandidateExtractionInfo[SelectedCandidateIndex].AnalyzedStatement
+          ? CandidateExtractionInfo[SelectedCandidateIndex].AnalyzedStatement
+          : this->S;
+
+  const auto *EnclosingObjCMethod =
+      dyn_cast<ObjCMethodDecl>(FunctionLikeParentDecl);
+
+  // Find the variables that are captured by the extracted code.
+  ExtractedCodeVisitor Visitor(/*SelfDecl=*/EnclosingObjCMethod
+                                   ? EnclosingObjCMethod->getSelfDecl()
+                                   : nullptr);
+  if (ExtractedStmtRange) {
+    for (const Stmt *S : *ExtractedStmtRange)
+      Visitor.InspectExtractedStmt(const_cast<Stmt *>(S), Context);
+  } else
+    Visitor.InspectExtractedStmt(const_cast<Stmt *>(S), Context);
+  // Compute the return type.
+  bool IsExpr = isLexicalExpression(S, ParentStmt);
+  QualType ReturnType;
+  if (IsExpr || Visitor.HasReturnInExtracted) {
+    if (const auto *E = dyn_cast<Expr>(S)) {
+      assert(!ExtractedStmtRange);
+      ReturnType = findExpressionLexicalType(FunctionLikeParentDecl, E,
+                                             E->getType(), PP, Context);
+    } else
+      ReturnType = getFunctionLikeParentDeclReturnType(FunctionLikeParentDecl);
+  } else
+    ReturnType = Context.VoidTy;
+  // Sort the captured variables.
+  std::vector<CapturedVariable> CapturedVariables;
+  llvm::SmallPtrSet<const VarDecl *, 4> VariablesDefinedInExtractedCode;
+  CapturedVariables.reserve(Visitor.CapturedVariables.size() +
+                            Visitor.CapturedFields.size());
+  for (const auto &I : Visitor.CapturedVariables) {
+    if (I.getSecond().IsDefined) {
+      VariablesDefinedInExtractedCode.insert(I.getFirst());
+      continue;
+    }
+    CapturedVariables.push_back(
+        CapturedVariable(I.getFirst(), I.getSecond().isPassedByRefOrPtr(),
+                         I.getSecond().isRefOrPtrConst()));
+  }
+  // Take a look at the variables that are defined in the extracted code.
+  VariableDefinedInExtractedCodeUseAfterExtractionFinder
+      UsedAfterExtractionFinder(ExtractedStmtRange ? *ExtractedStmtRange->Last
+                                                   : S,
+                                VariablesDefinedInExtractedCode);
+  UsedAfterExtractionFinder.TraverseStmt(
+      const_cast<Stmt *>(getEnclosingDeclBody(FunctionLikeParentDecl)));
+  struct RedeclaredVariable {
+    const VarDecl *VD;
+    int OrderingPriority;
+  };
+  llvm::SmallVector<RedeclaredVariable, 4> RedeclaredVariables;
+  bool CanUseReturnForVariablesUsedAfterwards =
+      !isa<Expr>(S) && ReturnType->isVoidType() &&
+      UsedAfterExtractionFinder.VariablesUsedAfterExtraction.size() == 1;
+  if (CanUseReturnForVariablesUsedAfterwards) {
+    // Avoid using the return value for the variable that's used afterwards as
+    // another variable might shadow it at the point of a 'return' that we
+    // have to rewrite to 'return var'.
+    const VarDecl *VD =
+        *UsedAfterExtractionFinder.VariablesUsedAfterExtraction.begin();
+    if (ExtractedStmtRange) {
+      for (const Stmt *S : *ExtractedStmtRange) {
+        if (PossibleShadowingVariableFinder::hasShadowingVar(VD, S)) {
+          CanUseReturnForVariablesUsedAfterwards = false;
+          break;
+        }
+      }
+    } else
+      CanUseReturnForVariablesUsedAfterwards =
+          !PossibleShadowingVariableFinder::hasShadowingVar(VD, S);
+  }
+  if (CanUseReturnForVariablesUsedAfterwards) {
+    for (const auto &I : Visitor.CapturedVariables) {
+      if (!I.getSecond().IsDefined ||
+          !UsedAfterExtractionFinder.VariablesUsedAfterExtraction.count(
+              I.getFirst()))
+        continue;
+      RedeclaredVariables.push_back(
+          {I.getFirst(), I.getSecond().DefineOrderingPriority});
+      ReturnType = I.getFirst()->getType();
+      // Const qualifier can be dropped as we don't want to declare the return
+      // type as 'const'.
+      if (ReturnType.isConstQualified())
+        ReturnType.removeLocalConst();
+      break;
+    }
+    if (Visitor.HasReturnInExtracted) {
+      ReturnRewriter ReturnsRewriter(SourceRewriter,
+                                     RedeclaredVariables.front().VD->getName());
+      if (ExtractedStmtRange) {
+        for (const Stmt *S : *ExtractedStmtRange)
+          ReturnsRewriter.TraverseStmt(const_cast<Stmt *>(S));
+      } else
+        ReturnsRewriter.TraverseStmt(const_cast<Stmt *>(S));
+    }
+  } else {
+    for (const auto &I : Visitor.CapturedVariables) {
+      if (!I.getSecond().IsDefined ||
+          !UsedAfterExtractionFinder.VariablesUsedAfterExtraction.count(
+              I.getFirst()))
+        continue;
+      RedeclaredVariables.push_back(
+          {I.getFirst(), I.getSecond().DefineOrderingPriority});
+      if (!I.getSecond().IsUsed)
+        continue;
+      // Pass the variable that's defined in the extracted code but used
+      // afterwards as a parameter only when it's actually used in the extracted
+      // code.
+      CapturedVariables.push_back(CapturedVariable(I.getFirst(),
+                                                   /*PassByRefOrPtr=*/true,
+                                                   /*IsRefOrPtrConst=*/false));
+    }
+    std::sort(RedeclaredVariables.begin(), RedeclaredVariables.end(),
+              [](const RedeclaredVariable &X, const RedeclaredVariable &Y) {
+                return X.OrderingPriority < Y.OrderingPriority;
+              });
+    DefinedInExtractedCodeDeclStmtRewriter DeclRewriter(
+        SourceRewriter, UsedAfterExtractionFinder.VariablesUsedAfterExtraction,
+        PP);
+    if (ExtractedStmtRange) {
+      for (const Stmt *S : *ExtractedStmtRange)
+        DeclRewriter.TraverseStmt(const_cast<Stmt *>(S));
+    } else
+      DeclRewriter.TraverseStmt(const_cast<Stmt *>(S));
+  }
+  // Capture any fields if necessary.
+  bool IsThisConstInCapturedFieldUses = true;
+  if (!isMethodExtraction()) {
+    for (const auto &I : Visitor.CapturedFields) {
+      if (I.getSecond().isPassedByRefOrPtr() &&
+          !I.getSecond().isRefOrPtrConst())
+        IsThisConstInCapturedFieldUses = false;
+      // Private fields that use explicit 'this' should be captured using 'this'
+      // even if they might end up being inaccessible in the extracted function.
+      if (I.getSecond().IsFieldCapturedWithThis)
+        continue;
+      CapturedVariables.push_back(
+          CapturedVariable(I.getFirst(), I.getSecond().isPassedByRefOrPtr(),
+                           I.getSecond().isRefOrPtrConst()));
+    }
+  }
+  std::sort(CapturedVariables.begin(), CapturedVariables.end(),
+            [](const CapturedVariable &X, const CapturedVariable &Y) {
+              return X.getName() < Y.getName();
+            });
+  // 'This'/'self' should be passed-in first.
+  if (!isMethodExtraction() && Visitor.CaptureThis) {
+    CapturedVariables.insert(
+        CapturedVariables.begin(),
+        CapturedVariable::getThis(
+            Visitor.ThisRecordType,
+            IsThisConstInCapturedFieldUses &&
+                Visitor.IsThisConstForNonCapturedFieldUses));
+    CapturedThisReferenceRewriter ThisRewriter(SourceRewriter);
+    if (ExtractedStmtRange) {
+      for (const Stmt *S : *ExtractedStmtRange)
+        ThisRewriter.TraverseStmt(const_cast<Stmt *>(S));
+    } else
+      ThisRewriter.TraverseStmt(const_cast<Stmt *>(S));
+    CapturedThisPointerRewriter PtrThisRewriter(
+        SourceRewriter, ThisRewriter.RewrittenExpressions);
+    if (ExtractedStmtRange) {
+      for (const Stmt *S : *ExtractedStmtRange)
+        PtrThisRewriter.TraverseStmt(const_cast<Stmt *>(S));
+    } else
+      PtrThisRewriter.TraverseStmt(const_cast<Stmt *>(S));
+  } else if (!isMethodExtraction() && Visitor.CaptureSelf &&
+             EnclosingObjCMethod) {
+    if (EnclosingObjCMethod->isInstanceMethod()) {
+      // Instance methods rewrite 'self' into an 'object' parameter.
+      CapturedVariables.insert(CapturedVariables.begin(),
+                               CapturedVariable::getSelf(Visitor.SelfType));
+      CapturedSelfRewriter SelfRewriter(SourceRewriter,
+                                        EnclosingObjCMethod->getSelfDecl());
+      if (ExtractedStmtRange) {
+        for (const Stmt *S : *ExtractedStmtRange)
+          SelfRewriter.TraverseStmt(const_cast<Stmt *>(S));
+      } else
+        SelfRewriter.TraverseStmt(const_cast<Stmt *>(S));
+    } else {
+      // Class methods rewrite 'self' into the class name and don't pass 'self'
+      // as a parameter.
+      CapturedClassSelfRewriter SelfRewriter(
+          SourceRewriter, EnclosingObjCMethod->getClassInterface()->getName(),
+          EnclosingObjCMethod->getSelfDecl());
+      if (ExtractedStmtRange) {
+        for (const Stmt *S : *ExtractedStmtRange)
+          SelfRewriter.TraverseStmt(const_cast<Stmt *>(S));
+      } else
+        SelfRewriter.TraverseStmt(const_cast<Stmt *>(S));
+    }
+  }
+  if (!isMethodExtraction() && Visitor.CaptureSuper && EnclosingObjCMethod) {
+    if (EnclosingObjCMethod->isInstanceMethod())
+      // Instance methods rewrite 'super' into an 'superObject' parameter.
+      CapturedVariables.insert(Visitor.CaptureSelf
+                                   ? CapturedVariables.begin() + 1
+                                   : CapturedVariables.begin(),
+                               CapturedVariable::getSuper(Visitor.SuperType));
+    CapturedSuperRewriter SuperRewriter(
+        SourceRewriter, EnclosingObjCMethod->isInstanceMethod()
+                            ? "superObject"
+                            : EnclosingObjCMethod->getClassInterface()
+                                  ->getSuperClass()
+                                  ->getName());
+    if (ExtractedStmtRange) {
+      for (const Stmt *S : *ExtractedStmtRange)
+        SuperRewriter.TraverseStmt(const_cast<Stmt *>(S));
+    } else
+      SuperRewriter.TraverseStmt(const_cast<Stmt *>(S));
+  }
+
+  // Compute the parameter types.
+  for (auto &Var : CapturedVariables) {
+    QualType T = Var.getType();
+
+    // Array types are passed into the extracted function using a pointer.
+    if (const auto *AT = Context.getAsArrayType(T))
+      T = Context.getPointerType(AT->getElementType());
+
+    // Captured records and other mutated variables are passed into the
+    // extracted function either using a reference (C++) or a pointer.
+    if ((T->isRecordType() || Var.PassByRefOrPtr) && !T->isReferenceType()) {
+      // Add a 'const' qualifier to the record when it's not mutated in the
+      // extracted code or when we are taking the address of the captured
+      // variable for just a 'const' use.
+      if (!Var.PassByRefOrPtr || Var.IsRefOrPtrConst)
+        T.addConst();
+
+      if (LangOpts.CPlusPlus)
+        T = Context.getLValueReferenceType(T);
+      else {
+        T = Context.getPointerType(T);
+        CapturedVariableCaptureByPointerRewriter UseRewriter(Var.VD,
+                                                             SourceRewriter);
+        if (ExtractedStmtRange) {
+          for (const Stmt *S : *ExtractedStmtRange)
+            UseRewriter.TraverseStmt(const_cast<Stmt *>(S));
+        } else
+          UseRewriter.TraverseStmt(const_cast<Stmt *>(S));
+        Var.TakeAddress = true;
+      }
+    }
+    // Const qualifier can be dropped as we don't want to declare the parameter
+    // as 'const'.
+    else if (T.isLocalConstQualified())
+      T.removeLocalConst();
+
+    Var.ParameterType = T;
+  }
+
+  // TODO: Choose a better name if there are collisions.
+  StringRef ExtractedName = "extracted";
+  llvm::SmallVector<StringRef, 4> ExtractedNamePieces;
+  ExtractedNamePieces.push_back(ExtractedName);
+  if (isMethodExtraction() && EnclosingObjCMethod &&
+      !CapturedVariables.empty()) {
+    for (const auto &Var : llvm::makeArrayRef(CapturedVariables).drop_front())
+      ExtractedNamePieces.push_back(Var.getName());
+  }
+  std::unique_ptr<RefactoringResultAssociatedSymbol> CreatedSymbol =
+      llvm::make_unique<RefactoringResultAssociatedSymbol>(
+          SymbolName(ExtractedNamePieces));
+
+  SourceLocation FunctionExtractionLoc = computeFunctionExtractionLocation(
+      FunctionLikeParentDecl, isMethodExtraction());
+  FunctionExtractionLoc =
+      getLocationOfPrecedingComment(FunctionExtractionLoc, SM, LangOpts);
+
+  // Create the replacement that contains the new function.
+  auto PrintFunctionHeader =
+      [&](llvm::raw_string_ostream &OS,
+          bool IsDefinition =
+              true) -> RefactoringReplacement::AssociatedSymbolLocation {
+    if (isMethodExtraction() && EnclosingObjCMethod) {
+      OS << (EnclosingObjCMethod->isClassMethod() ? '+' : '-') << " (";
+      ReturnType.print(OS, PP);
+      OS << ')';
+      llvm::SmallVector<unsigned, 4> NameOffsets;
+      NameOffsets.push_back(OS.str().size());
+      OS << ExtractedName;
+      bool IsFirst = true;
+      for (const auto &Var : CapturedVariables) {
+        if (!IsFirst) {
+          OS << ' ';
+          NameOffsets.push_back(OS.str().size());
+          OS << Var.getName();
+        }
+        IsFirst = false;
+        OS << ":(";
+        Var.ParameterType.print(OS, PP);
+        OS << ')' << Var.getName();
+      }
+      return RefactoringReplacement::AssociatedSymbolLocation(
+          NameOffsets, /*IsDeclaration=*/true);
+    }
+    auto *FD = dyn_cast<FunctionDecl>(FunctionLikeParentDecl);
+    if (isMethodExtraction() && IsDefinition &&
+        !FD->getDescribedFunctionTemplate()) {
+      // Print the class template parameter lists for an out-of-line method.
+      for (unsigned I = 0,
+                    NumTemplateParams = FD->getNumTemplateParameterLists();
+           I < NumTemplateParams; ++I) {
+        FD->getTemplateParameterList(I)->print(OS, PP, Context);
+        OS << "\n";
+      }
+    }
+    if (isMethodExtraction() && isEnclosingMethodStatic(FunctionLikeParentDecl))
+      OS << "static ";
+    else if (!isMethodExtraction())
+      OS << (isInHeader(FunctionExtractionLoc, SM) ? "inline " : "static ");
+    ReturnType.print(OS, PP);
+    OS << ' ';
+    if (isMethodExtraction() && IsDefinition)
+      printEnclosingMethodScope(FunctionLikeParentDecl, OS, PP);
+    unsigned NameOffset = OS.str().size();
+    OS << ExtractedName << '(';
+    bool IsFirst = true;
+    for (const auto &Var : CapturedVariables) {
+      if (!IsFirst)
+        OS << ", ";
+      IsFirst = false;
+      Var.ParameterType.print(OS, PP, /*PlaceHolder=*/Var.getName());
+    }
+    OS << ')';
+    if (isMethodExtraction() && isEnclosingMethodConst(FunctionLikeParentDecl))
+      OS << " const";
+    return RefactoringReplacement::AssociatedSymbolLocation(
+        NameOffset, /*IsDeclaration=*/true);
+    ;
+  };
+
+  if (isMethodExtraction() &&
+      isEnclosingMethodOutOfLine(FunctionLikeParentDecl)) {
+    // The location of the declaration should be either before the original
+    // declararation, or, if this method has not declaration, somewhere
+    // appropriate in the class.
+    MethodDeclarationPlacement Placement;
+    SourceLocation DeclarationLoc;
+    if (FunctionLikeParentDecl->getCanonicalDecl() != FunctionLikeParentDecl) {
+      DeclarationLoc = computeFunctionExtractionLocation(
+          FunctionLikeParentDecl->getCanonicalDecl(), isMethodExtraction());
+      Placement = MethodDeclarationPlacement::Before;
+    } else {
+      auto LocAndPlacement =
+          computeAppropriateExtractionLocationForMethodDeclaration(
+              cast<CXXMethodDecl>(FunctionLikeParentDecl));
+      DeclarationLoc = LocAndPlacement.first;
+      Placement = LocAndPlacement.second;
+    }
+    if (Placement == MethodDeclarationPlacement::Before)
+      DeclarationLoc =
+          getLocationOfPrecedingComment(DeclarationLoc, SM, LangOpts);
+    else
+      DeclarationLoc = getLastLineLocationUnlessItHasOtherTokens(
+          getPreciseTokenLocEnd(DeclarationLoc, SM, LangOpts), SM, LangOpts);
+    // Add a replacement for the method declaration if necessary.
+    std::string DeclarationString;
+    llvm::raw_string_ostream OS(DeclarationString);
+    if (Placement == MethodDeclarationPlacement::After)
+      OS << "\n\n";
+    RefactoringReplacement::AssociatedSymbolLocation SymbolLoc =
+        PrintFunctionHeader(OS, /*IsDefinition=*/false);
+    OS << ";\n";
+    if (Placement == MethodDeclarationPlacement::Before)
+      OS << "\n";
+    Replacements.push_back(RefactoringReplacement(
+        SourceRange(DeclarationLoc, DeclarationLoc), std::move(OS.str()),
+        CreatedSymbol.get(), SymbolLoc));
+  }
+  std::string ExtractedCode;
+  llvm::raw_string_ostream ExtractedOS(ExtractedCode);
+  RefactoringReplacement::AssociatedSymbolLocation SymbolLoc =
+      PrintFunctionHeader(ExtractedOS);
+  ExtractedOS << " {\n";
+  if (IsExpr && !ReturnType->isVoidType())
+    ExtractedOS << "return ";
+  SourceRange ExtractedTokenRange =
+      CandidateExtractionInfo[SelectedCandidateIndex].Range;
+  auto Semicolons = computeSemicolonExtractionPolicy(
+      ExtractedStmtRange ? *(ExtractedStmtRange->Last) : S, ExtractedTokenRange,
+      SM, LangOpts);
+  ExtractedOS << SourceRewriter.getRewrittenText(ExtractedTokenRange);
+  if (Semicolons.IsNeededInExtractedFunction)
+    ExtractedOS << ';';
+  if (CanUseReturnForVariablesUsedAfterwards)
+    ExtractedOS << "\nreturn " << RedeclaredVariables.front().VD->getName()
+                << ";";
+  ExtractedOS << "\n}\n\n";
+  Replacements.push_back(RefactoringReplacement(
+      SourceRange(FunctionExtractionLoc, FunctionExtractionLoc),
+      std::move(ExtractedOS.str()), CreatedSymbol.get(), SymbolLoc));
+
+  // Create a replacements that removes the extracted code in favor of the
+  // function call.
+  std::string InsertedCode;
+  llvm::raw_string_ostream InsertedOS(InsertedCode);
+  // We might have to declare variables that were declared in the extracted code
+  // but still used afterwards.
+  if (CanUseReturnForVariablesUsedAfterwards) {
+    const auto &Var = RedeclaredVariables.front();
+    Var.VD->getType().print(InsertedOS, PP);
+    InsertedOS << ' ' << Var.VD->getName() << " = ";
+  } else {
+    for (const auto &Var : RedeclaredVariables) {
+      Var.VD->getType().print(InsertedOS, PP);
+      InsertedOS << ' ' << Var.VD->getName() << ";\n";
+    }
+  }
+  InsertedOS << CandidateExtractionInfo[SelectedCandidateIndex].PreInsertedText;
+  llvm::SmallVector<unsigned, 4> NameOffsets;
+  if (isMethodExtraction() && EnclosingObjCMethod) {
+    InsertedOS << "[self ";
+    NameOffsets.push_back(InsertedOS.str().size());
+    InsertedOS << ExtractedName;
+    bool IsFirst = true;
+    for (const auto &Var : CapturedVariables) {
+      if (!IsFirst) {
+        InsertedOS << ' ';
+        NameOffsets.push_back(InsertedOS.str().size());
+        InsertedOS << Var.getName();
+      }
+      IsFirst = false;
+      InsertedOS << ':';
+      if (Var.TakeAddress)
+        InsertedOS << '&';
+      InsertedOS << Var.getExpr();
+    }
+    InsertedOS << ']';
+  } else {
+    NameOffsets.push_back(InsertedOS.str().size());
+    InsertedOS << ExtractedName << '(';
+    bool IsFirst = true;
+    for (const auto &Var : CapturedVariables) {
+      if (!IsFirst)
+        InsertedOS << ", ";
+      IsFirst = false;
+      if (Var.TakeAddress)
+        InsertedOS << '&';
+      InsertedOS << Var.getExpr();
+    }
+    InsertedOS << ')';
+  }
+  if (Semicolons.IsNeededInOriginalFunction)
+    InsertedOS << ';';
+  SourceRange ExtractedCharRange = SourceRange(
+      ExtractedTokenRange.getBegin(),
+      getPreciseTokenLocEnd(ExtractedTokenRange.getEnd(), SM, LangOpts));
+  Replacements.push_back(RefactoringReplacement(
+      ExtractedCharRange, std::move(InsertedOS.str()), CreatedSymbol.get(),
+      llvm::makeArrayRef(NameOffsets)));
+
+  RefactoringResult Result(std::move(Replacements));
+  Result.AssociatedSymbols.push_back(std::move(CreatedSymbol));
+  return std::move(Result);
+}
diff --git a/lib/Tooling/Refactor/ExtractRepeatedExpressionIntoVariable.cpp b/lib/Tooling/Refactor/ExtractRepeatedExpressionIntoVariable.cpp
new file mode 100644
index 0000000..dc90d9e
--- /dev/null
+++ b/lib/Tooling/Refactor/ExtractRepeatedExpressionIntoVariable.cpp
@@ -0,0 +1,282 @@
+//===--- ExtractRepeatedExpressionIntoVariable.cpp -  ---------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the "Extract repeated expression into variable" refactoring
+// operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ExtractionUtils.h"
+#include "RefactoringOperations.h"
+#include "SourceLocationUtilities.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+using namespace clang::tooling;
+
+namespace {
+
+class ExtractRepeatedExpressionIntoVariableOperation
+    : public RefactoringOperation {
+public:
+  ExtractRepeatedExpressionIntoVariableOperation(
+      const Expr *E, ArrayRef<const Expr *> Duplicates, const Decl *ParentDecl)
+      : E(E), DuplicateExpressions(Duplicates.begin(), Duplicates.end()),
+        ParentDecl(ParentDecl) {}
+
+  const Stmt *getTransformedStmt() const override { return E; }
+
+  llvm::Expected<RefactoringResult> perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex) override;
+
+  const Expr *E;
+  SmallVector<const Expr *, 4> DuplicateExpressions;
+  const Decl *ParentDecl;
+};
+
+using UseOfDeclaration = std::pair<const Decl *, unsigned>;
+
+bool shouldIgnoreParens(const ParenExpr *E) {
+  if (!E)
+    return false;
+  const Expr *Child = E->getSubExpr();
+  // Ignore the parens unless they are around an expression that
+  // really needs them.
+  if (isa<UnaryOperator>(Child) || isa<BinaryOperator>(Child) ||
+      isa<AbstractConditionalOperator>(Child) ||
+      isa<CXXOperatorCallExpr>(Child))
+    return false;
+  return true;
+}
+
+/// Builds up a list of declarations that are used in an expression.
+class DuplicateExprSemanticProfiler
+    : public RecursiveASTVisitor<DuplicateExprSemanticProfiler> {
+  unsigned Index = 0;
+  llvm::SmallVectorImpl<UseOfDeclaration> &DeclRefs;
+
+public:
+  DuplicateExprSemanticProfiler(
+      llvm::SmallVectorImpl<UseOfDeclaration> &DeclRefs)
+      : DeclRefs(DeclRefs) {
+    DeclRefs.clear();
+  }
+
+  bool VisitStmt(const Stmt *S) {
+    if (!shouldIgnoreParens(dyn_cast<ParenExpr>(S)))
+      ++Index;
+    return true;
+  }
+
+  bool VisitDeclRefExpr(const DeclRefExpr *E) {
+    if (E->getDecl())
+      DeclRefs.emplace_back(E->getDecl(), Index);
+    return true;
+  }
+};
+
+class DuplicateExprFinder : public RecursiveASTVisitor<DuplicateExprFinder>,
+                            PrinterHelper {
+  const Expr *Target;
+  const ASTContext &Context;
+  const PrintingPolicy &PP;
+  Stmt::StmtClass ExprKind;
+  QualType T;
+  std::string ExprString, OSString;
+  llvm::SmallVector<UseOfDeclaration, 8> ExprDecls, DeclUses;
+
+  void printExpr(std::string &Str, const Expr *E) {
+    llvm::raw_string_ostream OS(Str);
+    E->printPretty(OS, /*Helper=*/this, PP);
+  }
+
+public:
+  SmallVector<const Expr *, 4> DuplicateExpressions;
+
+  DuplicateExprFinder(const Expr *E, const ASTContext &Context,
+                      const PrintingPolicy &PP)
+      : Target(E), Context(Context), PP(PP), ExprKind(E->getStmtClass()),
+        T(E->getType()) {
+    printExpr(ExprString, E);
+    DuplicateExprSemanticProfiler(ExprDecls).TraverseStmt(
+        const_cast<Expr *>(E));
+  }
+
+  bool handledStmt(Stmt *E, raw_ostream &OS) final override {
+    if (const auto *Paren = dyn_cast<ParenExpr>(E)) {
+      if (!shouldIgnoreParens(Paren))
+        return false;
+      Paren->getSubExpr()->printPretty(OS, /*Helper=*/this, PP);
+      return true;
+    }
+    return false;
+  }
+
+  bool VisitStmt(const Stmt *S) {
+    if (S->getStmtClass() != ExprKind)
+      return true;
+    const auto *E = cast<Expr>(S);
+    if (E == Target) {
+      DuplicateExpressions.push_back(E);
+      return true;
+    }
+    // The expression should not be in a macro.
+    SourceRange R = E->getSourceRange();
+    if (R.getBegin().isMacroID()) {
+      if (!Context.getSourceManager().isMacroArgExpansion(R.getBegin()))
+        return true;
+    }
+    if (R.getEnd().isMacroID()) {
+      if (!Context.getSourceManager().isMacroArgExpansion(R.getEnd()))
+        return true;
+    }
+    // The expression types should match.
+    if (E->getType() != T)
+      return true;
+    // Check if the expression is a duplicate by comparing their lexical
+    // representations.
+    OSString.clear();
+    printExpr(OSString, E);
+    if (OSString == ExprString) {
+      DuplicateExprSemanticProfiler(DeclUses).TraverseStmt(
+          const_cast<Expr *>(E));
+      // Check if they're semantically equivalent.
+      if (ExprDecls.size() == DeclUses.size() &&
+          std::equal(ExprDecls.begin(), ExprDecls.end(), DeclUses.begin()))
+        DuplicateExpressions.push_back(E);
+    }
+    return true;
+  }
+};
+
+} // end anonymous namespace
+
+static QualType returnTypeOfCall(const Expr *E) {
+  if (const auto *Call = dyn_cast<CallExpr>(E)) {
+    if (const auto *Fn = Call->getDirectCallee())
+      return Fn->getReturnType();
+  } else if (const auto *Msg = dyn_cast<ObjCMessageExpr>(E)) {
+    if (const auto *M = Msg->getMethodDecl())
+      return M->getReturnType();
+  } else if (const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    if (PRE->isImplicitProperty()) {
+      if (const auto *M = PRE->getImplicitPropertyGetter())
+        return M->getReturnType();
+    } else if (const auto *Prop = PRE->getExplicitProperty())
+      return Prop->getType();
+  }
+  return QualType();
+}
+
+static bool isRepeatableExpression(const Stmt *S) {
+  if (const auto *Op = dyn_cast<CXXOperatorCallExpr>(S))
+    return Op->getOperator() == OO_Call || Op->getOperator() == OO_Subscript;
+  return isa<CallExpr>(S) || isa<ObjCMessageExpr>(S) ||
+         isa<ObjCPropertyRefExpr>(S);
+}
+
+RefactoringOperationResult
+clang::tooling::initiateExtractRepeatedExpressionIntoVariableOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  const Stmt *S;
+  const Decl *ParentDecl;
+  if (SelectionRange.isValid()) {
+    auto SelectedStmt = Slice.getSelectedStmtSet();
+    if (!SelectedStmt)
+      return None;
+    if (!SelectedStmt->containsSelectionRange)
+      return None;
+    if (!isRepeatableExpression(SelectedStmt->containsSelectionRange))
+      return None;
+    S = SelectedStmt->containsSelectionRange;
+    ParentDecl =
+        Slice.parentDeclForIndex(*SelectedStmt->containsSelectionRangeIndex);
+  } else {
+    auto SelectedStmt = Slice.nearestSelectedStmt(isRepeatableExpression);
+    if (!SelectedStmt)
+      return None;
+    S = SelectedStmt->getStmt();
+    ParentDecl = SelectedStmt->getParentDecl();
+  }
+
+  const Expr *E = cast<Expr>(S);
+  // Check if the function/method returns a reference/pointer.
+  QualType T = returnTypeOfCall(E);
+  if (!T.getTypePtrOrNull() ||
+      (!T->isAnyPointerType() && !T->isReferenceType()))
+    return None;
+
+  DuplicateExprFinder DupFinder(E, Context, Context.getPrintingPolicy());
+  DupFinder.TraverseDecl(const_cast<Decl *>(ParentDecl));
+  if (DupFinder.DuplicateExpressions.size() < 2)
+    return None;
+
+  RefactoringOperationResult Result;
+  Result.Initiated = true;
+  if (!CreateOperation)
+    return Result;
+  auto Operation =
+      llvm::make_unique<ExtractRepeatedExpressionIntoVariableOperation>(
+          E, DupFinder.DuplicateExpressions, ParentDecl);
+  Result.RefactoringOp = std::move(Operation);
+  return Result;
+}
+
+static StringRef nameForExtractedVariable(const Expr *E) {
+  auto SuggestedName = extract::nameForExtractedVariable(E);
+  if (!SuggestedName)
+    return "duplicate";
+  return *SuggestedName;
+}
+
+llvm::Expected<RefactoringResult>
+ExtractRepeatedExpressionIntoVariableOperation::perform(
+    ASTContext &Context, const Preprocessor &ThePreprocessor,
+    const RefactoringOptionSet &Options, unsigned SelectedCandidateIndex) {
+  std::vector<RefactoringReplacement> Replacements;
+
+  const SourceManager &SM = Context.getSourceManager();
+  SourceLocation InsertionLoc =
+      extract::locationForExtractedVariableDeclaration(DuplicateExpressions,
+                                                       ParentDecl, SM);
+  if (InsertionLoc.isInvalid())
+    return llvm::make_error<RefactoringOperationError>(
+        "no appropriate insertion location found");
+
+  StringRef Name = nameForExtractedVariable(E);
+
+  // Create the variable that will hold the value of the duplicate expression.
+  std::string VariableDeclarationString;
+  llvm::raw_string_ostream OS(VariableDeclarationString);
+  QualType T = returnTypeOfCall(E);
+  PrintingPolicy PP = Context.getPrintingPolicy();
+  PP.SuppressStrongLifetime = true;
+  PP.SuppressLifetimeQualifiers = true;
+  PP.SuppressUnwrittenScope = true;
+  T.print(OS, PP, /*PlaceHolder*/ Name);
+  OS << " = ";
+  E->printPretty(OS, /*Helper=*/nullptr, Context.getPrintingPolicy());
+  OS << ";\n";
+  Replacements.emplace_back(SourceRange(InsertionLoc, InsertionLoc), OS.str());
+
+  // Replace the duplicates with a reference to the variable.
+  for (const Expr *E : DuplicateExpressions)
+    Replacements.emplace_back(
+        SourceRange(SM.getSpellingLoc(E->getLocStart()),
+                    getPreciseTokenLocEnd(SM.getSpellingLoc(E->getLocEnd()), SM,
+                                          Context.getLangOpts())),
+        Name);
+
+  return std::move(Replacements);
+}
diff --git a/lib/Tooling/Refactor/ExtractionUtils.cpp b/lib/Tooling/Refactor/ExtractionUtils.cpp
new file mode 100644
index 0000000..a733add
--- /dev/null
+++ b/lib/Tooling/Refactor/ExtractionUtils.cpp
@@ -0,0 +1,137 @@
+//===--- ExtractionUtils.cpp - Extraction helper functions ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ExtractionUtils.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/ExprObjC.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/Support/SaveAndRestore.h"
+
+using namespace clang;
+
+Optional<StringRef> tooling::extract::nameForExtractedVariable(const Expr *E) {
+  if (const auto *Call = dyn_cast<CallExpr>(E)) {
+    if (const auto *Fn = Call->getDirectCallee())
+      return Fn->getName();
+  } else if (const auto *Msg = dyn_cast<ObjCMessageExpr>(E)) {
+    if (const auto *M = Msg->getMethodDecl()) {
+      if (M->getSelector().isUnarySelector())
+        return M->getSelector().getNameForSlot(0);
+    }
+  } else if (const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    if (PRE->isImplicitProperty()) {
+      if (const auto *M = PRE->getImplicitPropertyGetter())
+        return M->getSelector().getNameForSlot(0);
+    } else if (const auto *Prop = PRE->getExplicitProperty())
+      return Prop->getName();
+  }
+  return None;
+}
+
+namespace {
+
+/// Checks if a set of expressions is directly contained in some AST region.
+class StmtReachabilityChecker
+    : public RecursiveASTVisitor<StmtReachabilityChecker> {
+  const llvm::SmallPtrSetImpl<const Stmt *> &Expressions;
+  unsigned Count = 0;
+
+  StmtReachabilityChecker(
+      const llvm::SmallPtrSetImpl<const Stmt *> &Expressions)
+      : Expressions(Expressions) {}
+
+  bool areAllExpressionsReached() const { return Count == Expressions.size(); }
+
+public:
+  bool VisitStmt(const Stmt *S) {
+    if (Expressions.count(S)) {
+      ++Count;
+      if (areAllExpressionsReached())
+        return false;
+    }
+    return true;
+  }
+
+  static bool areAllExpressionsReachableFrom(
+      CompoundStmt *S, const llvm::SmallPtrSetImpl<const Stmt *> &Expressions) {
+    StmtReachabilityChecker Checker(Expressions);
+    Checker.TraverseStmt(S);
+    return Checker.areAllExpressionsReached();
+  }
+};
+
+/// Figures out where the extracted variable should go.
+class ExtractedVariableInsertionLocFinder
+    : public RecursiveASTVisitor<ExtractedVariableInsertionLocFinder> {
+  llvm::SmallPtrSet<const Stmt *, 4> Expressions;
+  llvm::SmallVector<std::pair<CompoundStmt *, const Stmt *>, 4>
+      InsertionCandidateStack;
+  bool IsPrevCompoundStmt = false;
+
+public:
+  SourceLocation Loc;
+
+  /// Initializes the insertion location finder using the set of duplicate
+  /// \p Expressions from one function.
+  ExtractedVariableInsertionLocFinder(ArrayRef<const Expr *> Expressions) {
+    for (const Expr *E : Expressions)
+      this->Expressions.insert(E);
+  }
+
+  bool TraverseStmt(Stmt *S) {
+    if (!S)
+      return RecursiveASTVisitor::TraverseStmt(S);
+    if (IsPrevCompoundStmt && !InsertionCandidateStack.empty())
+      InsertionCandidateStack.back().second = S;
+    llvm::SaveAndRestore<bool> IsPrevCompoundStmtTracker(IsPrevCompoundStmt,
+                                                         false);
+    if (auto *CS = dyn_cast<CompoundStmt>(S)) {
+      IsPrevCompoundStmt = true;
+      InsertionCandidateStack.emplace_back(CS, nullptr);
+      RecursiveASTVisitor::TraverseStmt(S);
+      InsertionCandidateStack.pop_back();
+      return true;
+    }
+    return RecursiveASTVisitor::TraverseStmt(S);
+  }
+
+  bool VisitStmt(const Stmt *S) {
+    if (Expressions.count(S)) {
+      // The insertion location should be in the first compound statement that
+      // includes all of the expressions as descendants as we want the new
+      // variable to be visible to all uses.
+      for (auto I = InsertionCandidateStack.rbegin(),
+                E = InsertionCandidateStack.rend();
+           I != E; ++I) {
+        if (StmtReachabilityChecker::areAllExpressionsReachableFrom(
+                I->first, Expressions) &&
+            I->second) {
+          Loc = I->second->getLocStart();
+          break;
+        }
+      }
+      return false;
+    }
+    return true;
+  }
+};
+
+} // end anonymous namespace
+
+SourceLocation tooling::extract::locationForExtractedVariableDeclaration(
+    ArrayRef<const Expr *> Expressions, const Decl *ParentDecl,
+    const SourceManager &SM) {
+  ExtractedVariableInsertionLocFinder LocFinder(Expressions);
+  LocFinder.TraverseDecl(const_cast<Decl *>(ParentDecl));
+  SourceLocation Result = LocFinder.Loc;
+  if (Result.isValid() && Result.isMacroID())
+    return SM.getExpansionLoc(Result);
+  return Result;
+}
diff --git a/lib/Tooling/Refactor/ExtractionUtils.h b/lib/Tooling/Refactor/ExtractionUtils.h
new file mode 100644
index 0000000..816a081
--- /dev/null
+++ b/lib/Tooling/Refactor/ExtractionUtils.h
@@ -0,0 +1,40 @@
+//===--- ExtractionUtils.h - Extraction helper functions ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_TOOLING_REFACTOR_EXTRACTION_UTILS_H
+#define LLVM_CLANG_LIB_TOOLING_REFACTOR_EXTRACTION_UTILS_H
+
+#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+
+namespace clang {
+
+class Expr;
+class Decl;
+class SourceManager;
+
+namespace tooling {
+namespace extract {
+
+/// Returns a good name for an extracted variable based on the declaration
+/// that's used in the given expression \p E.
+Optional<StringRef> nameForExtractedVariable(const Expr *E);
+
+/// Returns an appropriate location for a variable declaration that will be
+/// visible to all the given expressions.
+SourceLocation
+locationForExtractedVariableDeclaration(ArrayRef<const Expr *> Expressions,
+                                        const Decl *ParentDecl,
+                                        const SourceManager &SM);
+
+} // end namespace extract
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_TOOLING_REFACTOR_EXTRACTION_UTILS_H
diff --git a/lib/Tooling/Refactor/FillInEnumSwitchCases.cpp b/lib/Tooling/Refactor/FillInEnumSwitchCases.cpp
new file mode 100644
index 0000000..2cab0ee
--- /dev/null
+++ b/lib/Tooling/Refactor/FillInEnumSwitchCases.cpp
@@ -0,0 +1,110 @@
+//===--- FillInEnumSwitchCases.cpp -  -------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the "Add missing switch cases" refactoring operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RefactoringOperations.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Edit/RefactoringFixits.h"
+
+using namespace clang;
+using namespace clang::tooling;
+
+namespace {
+
+class FillInEnumSwitchCasesOperation : public RefactoringOperation {
+public:
+  FillInEnumSwitchCasesOperation(const EnumDecl *Enum, const SwitchStmt *Switch,
+                                 const DeclContext *SwitchContext)
+      : Enum(Enum), Switch(Switch), SwitchContext(SwitchContext) {}
+
+  const Stmt *getTransformedStmt() const override { return Switch; }
+
+  llvm::Expected<RefactoringResult>
+  perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex) override;
+
+  const EnumDecl *Enum;
+  const SwitchStmt *Switch;
+  const DeclContext *SwitchContext;
+};
+
+} // end anonymous namespace
+
+RefactoringOperationResult
+clang::tooling::initiateFillInEnumSwitchCasesOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  const SwitchStmt *Switch;
+  const Decl *ParentDecl;
+  if (SelectionRange.isValid()) {
+    auto SelectedSet = Slice.getSelectedStmtSet();
+    if (!SelectedSet)
+      return None;
+    Switch = dyn_cast_or_null<SwitchStmt>(SelectedSet->containsSelectionRange);
+    // FIXME: Improve the interface for this to make it similar to SelectedStmt
+    if (SelectedSet->containsSelectionRange)
+      ParentDecl =
+          Slice.parentDeclForIndex(*SelectedSet->containsSelectionRangeIndex);
+  } else {
+    auto SelectedStmt = Slice.nearestSelectedStmt(Stmt::SwitchStmtClass);
+    if (!SelectedStmt)
+      return None;
+    Switch = cast<SwitchStmt>(SelectedStmt->getStmt());
+    ParentDecl = SelectedStmt->getParentDecl();
+  }
+  if (!Switch)
+    return None;
+
+  // Ensure that the type is an enum.
+  const Expr *Cond = Switch->getCond()->IgnoreImpCasts();
+  const EnumDecl *ED = nullptr;
+  if (const auto *ET = Cond->getType()->getAs<EnumType>())
+    ED = ET->getDecl();
+  else {
+    // Enum literals are 'int' in C.
+    if (const auto *DRE = dyn_cast<DeclRefExpr>(Cond)) {
+      if (const auto *EC = dyn_cast<EnumConstantDecl>(DRE->getDecl()))
+        ED = dyn_cast<EnumDecl>(EC->getDeclContext());
+    }
+  }
+
+  if (!ED)
+    return RefactoringOperationResult("The switch doesn't operate on an enum");
+  if (!ED->isCompleteDefinition())
+    return RefactoringOperationResult("The enum type is incomplete");
+
+  if (Switch->isAllEnumCasesCovered())
+    return RefactoringOperationResult("All enum cases are already covered");
+
+  RefactoringOperationResult Result;
+  Result.Initiated = true;
+  if (!CreateOperation)
+    return Result;
+  auto Operation = llvm::make_unique<FillInEnumSwitchCasesOperation>(
+      ED, Switch, dyn_cast<DeclContext>(ParentDecl));
+  Result.RefactoringOp = std::move(Operation);
+  return Result;
+}
+
+llvm::Expected<RefactoringResult>
+FillInEnumSwitchCasesOperation::perform(ASTContext &Context,
+                                        const Preprocessor &ThePreprocessor,
+                                        const RefactoringOptionSet &Options,
+                                        unsigned SelectedCandidateIndex) {
+  std::vector<RefactoringReplacement> Replacements;
+  edit::fillInMissingSwitchEnumCases(
+      Context, Switch, Enum, SwitchContext,
+      [&](const FixItHint &Hint) { Replacements.push_back(Hint); });
+  return std::move(Replacements);
+}
diff --git a/lib/Tooling/Refactor/FillInMissingMethodStubsFromAbstractClasses.cpp b/lib/Tooling/Refactor/FillInMissingMethodStubsFromAbstractClasses.cpp
new file mode 100644
index 0000000..ba730f6
--- /dev/null
+++ b/lib/Tooling/Refactor/FillInMissingMethodStubsFromAbstractClasses.cpp
@@ -0,0 +1,293 @@
+//===--- FillInMissingMethodStubsFromAbstractClasses.cpp -  ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the "Add missing abstract class method overrides" refactoring
+// operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RefactoringOperations.h"
+#include "SourceLocationUtilities.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "llvm/ADT/DenseSet.h"
+
+using namespace clang;
+using namespace clang::tooling;
+
+namespace {
+
+class FillInMissingMethodStubsFromAbstractClassesOperation
+    : public RefactoringOperation {
+public:
+  FillInMissingMethodStubsFromAbstractClassesOperation(
+      const CXXRecordDecl *Class)
+      : Class(Class) {}
+
+  const Decl *getTransformedDecl() const override { return Class; }
+
+  llvm::Expected<RefactoringResult> perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex) override;
+
+  const CXXRecordDecl *Class;
+};
+
+} // end anonymous namespace
+
+static bool hasAbstractBases(const CXXRecordDecl *Class) {
+  for (const CXXBaseSpecifier &Base : Class->bases()) {
+    if (const auto *RD = Base.getType()->getAsCXXRecordDecl()) {
+      if (RD->isAbstract())
+        return true;
+    }
+  }
+  return false;
+}
+
+RefactoringOperationResult
+clang::tooling::initiateFillInMissingMethodStubsFromAbstractClassesOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  auto SelectedDecl = Slice.innermostSelectedDecl(
+      llvm::makeArrayRef(Decl::CXXRecord), ASTSlice::InnermostDeclOnly);
+  if (!SelectedDecl)
+    return None;
+  const auto *Class = cast<CXXRecordDecl>(SelectedDecl->getDecl());
+  if (Class->isUnion() || !Class->isThisDeclarationADefinition())
+    return None;
+  if (!hasAbstractBases(Class))
+    return RefactoringOperationResult("The class has no abstract bases");
+  if (!Class->isDependentType() && !Class->isAbstract())
+    return RefactoringOperationResult(
+        "The class has no missing abstract class methods");
+
+  RefactoringOperationResult Result;
+  Result.Initiated = true;
+  if (!CreateOperation)
+    return Result;
+  auto Operation =
+      llvm::make_unique<FillInMissingMethodStubsFromAbstractClassesOperation>(
+          Class);
+  Result.RefactoringOp = std::move(Operation);
+  return Result;
+}
+
+namespace {
+
+class PureMethodSet {
+  llvm::DenseMap<const CXXMethodDecl *, int> Methods;
+
+  void addPureMethodsFromAbstractClasses(const CXXRecordDecl *Class,
+                                         int &Priority) {
+    for (const CXXBaseSpecifier &Base : Class->bases()) {
+      const auto *RD = Base.getType()->getAsCXXRecordDecl();
+      if (!RD || !RD->isAbstract())
+        continue;
+      for (const CXXMethodDecl *M : RD->methods()) {
+        if (M->isPure())
+          Methods.insert(std::make_pair(M->getCanonicalDecl(), Priority++));
+      }
+      addPureMethodsFromAbstractClasses(RD, Priority);
+    }
+  }
+
+  void addPureMethodsFromAbstractClasses(const CXXRecordDecl *Class) {
+    int Priority = 0;
+    addPureMethodsFromAbstractClasses(Class, Priority);
+  }
+
+  void subtractImplementedPureMethods(const CXXRecordDecl *Class) {
+    for (const CXXMethodDecl *M : Class->methods()) {
+      if (!M->isVirtual() || M->isPure())
+        continue;
+      for (const CXXMethodDecl *OM : M->overridden_methods()) {
+        OM = OM->getCanonicalDecl();
+        if (OM->isPure())
+          Methods.erase(OM);
+      }
+    }
+    for (const CXXBaseSpecifier &Base : Class->bases()) {
+      const auto *RD = Base.getType()->getAsCXXRecordDecl();
+      if (!RD || !RD->isAbstract())
+        continue;
+      subtractImplementedPureMethods(RD);
+    }
+  }
+
+public:
+  static std::vector<const CXXMethodDecl *>
+  gatherMissingMethods(const CXXRecordDecl *Class) {
+    PureMethodSet MethodSet;
+    MethodSet.addPureMethodsFromAbstractClasses(Class);
+    MethodSet.subtractImplementedPureMethods(Class);
+    // Sort the missing methods. That will place methods from the same abstract
+    // class together in the order in which they were declared.
+    struct MethodInfo {
+      const CXXMethodDecl *M;
+      int Priority;
+    };
+    std::vector<MethodInfo> MissingMethods;
+    for (const auto &M : MethodSet.Methods)
+      MissingMethods.push_back({M.first, M.second});
+    std::sort(MissingMethods.begin(), MissingMethods.end(),
+              [](const MethodInfo &LHS, const MethodInfo &RHS) {
+                return LHS.Priority < RHS.Priority;
+              });
+    std::vector<const CXXMethodDecl *> Result;
+    Result.reserve(MissingMethods.size());
+    for (const auto &M : MissingMethods)
+      Result.push_back(M.M);
+    return Result;
+  }
+};
+
+} // end anonymous namespace
+
+static SourceLocation findInsertionLocationForMethodsFromAbstractClass(
+    const CXXRecordDecl *AbstractClass, const CXXRecordDecl *Class,
+    const SourceManager &SM, const LangOptions &LangOpts) {
+  SourceLocation Loc;
+  for (const CXXMethodDecl *M : Class->methods()) {
+    if (!M->isVirtual() || M->isPure() || M->isImplicit())
+      continue;
+    for (const CXXMethodDecl *OM : M->overridden_methods()) {
+      OM = OM->getCanonicalDecl();
+      if (OM->getLexicalDeclContext() == AbstractClass) {
+        SourceLocation EndLoc = M->getLocEnd();
+        if (EndLoc.isMacroID())
+          EndLoc = SM.getExpansionRange(EndLoc).second;
+        if (Loc.isInvalid())
+          Loc = EndLoc;
+        else if (SM.isBeforeInTranslationUnit(Loc, EndLoc))
+          Loc = EndLoc;
+        break;
+      }
+    }
+  }
+  if (Loc.isInvalid())
+    return Loc;
+  return getLastLineLocationUnlessItHasOtherTokens(Loc, SM, LangOpts);
+}
+
+/// Returns true if the given \p Class implements the majority of declared
+/// methods in the class itself.
+static bool shouldImplementMethodsInClass(const CXXRecordDecl *Class) {
+  // Check if this class implements the methods in the class itself.
+  unsigned NumMethods = 0, NumImplementedMethods = 0;
+  for (const CXXMethodDecl *M : Class->methods()) {
+    if (M->isImplicit())
+      continue;
+    // Only look at methods/operators.
+    if (isa<CXXConstructorDecl>(M) || isa<CXXDestructorDecl>(M))
+      continue;
+    ++NumMethods;
+    if (M->hasBody())
+      ++NumImplementedMethods;
+  }
+  if (!NumMethods)
+    return false;
+  // Use the following arbitrary heuristic:
+  // If the number of method declarations is less than 4, then all of the
+  // methods must have bodies. Otherwise, at least 75% of the methods must
+  // have bodies.
+  return NumMethods < 4
+             ? NumMethods == NumImplementedMethods
+             : float(NumImplementedMethods) / float(NumMethods) > 0.75;
+}
+
+llvm::Expected<RefactoringResult>
+FillInMissingMethodStubsFromAbstractClassesOperation::perform(
+    ASTContext &Context, const Preprocessor &ThePreprocessor,
+    const RefactoringOptionSet &Options, unsigned SelectedCandidateIndex) {
+  std::vector<RefactoringReplacement> Replacements;
+
+  std::vector<const CXXMethodDecl *> MissingMethods =
+      PureMethodSet::gatherMissingMethods(Class);
+
+  bool GenerateBodyDummies = shouldImplementMethodsInClass(Class);
+
+  PrintingPolicy PP = Context.getPrintingPolicy();
+  PP.PolishForDeclaration = true;
+  PP.SuppressStrongLifetime = true;
+  PP.SuppressLifetimeQualifiers = true;
+  PP.SuppressUnwrittenScope = true;
+
+  std::string EndInsertionOSStr;
+  llvm::raw_string_ostream EndInsertionOS(EndInsertionOSStr);
+
+  std::string InsertionGroupOSStr;
+  llvm::raw_string_ostream InsertionGroupOS(InsertionGroupOSStr);
+
+  SourceLocation InsertionLoc = Class->getLocEnd();
+  const CXXRecordDecl *CurrentAbstractClass = nullptr;
+  SourceLocation CurrentGroupInsertionLoc;
+  for (const auto &I : llvm::enumerate(MissingMethods)) {
+    const CXXMethodDecl *Method = I.value();
+    const CXXRecordDecl *AbstractClass = Method->getParent();
+    if (CurrentAbstractClass != AbstractClass) {
+      if (!InsertionGroupOS.str().empty()) {
+        assert(CurrentGroupInsertionLoc.isValid());
+        Replacements.emplace_back(
+            SourceRange(CurrentGroupInsertionLoc, CurrentGroupInsertionLoc),
+            InsertionGroupOS.str());
+      }
+      InsertionGroupOSStr.clear();
+      CurrentAbstractClass = AbstractClass;
+      CurrentGroupInsertionLoc =
+          findInsertionLocationForMethodsFromAbstractClass(
+              CurrentAbstractClass, Class, Context.getSourceManager(),
+              Context.getLangOpts());
+    }
+    bool IsInsertingAfterRelatedMethods = CurrentGroupInsertionLoc.isValid();
+    raw_ostream &OS =
+        IsInsertingAfterRelatedMethods ? InsertionGroupOS : EndInsertionOS;
+
+    if (IsInsertingAfterRelatedMethods && InsertionGroupOS.str().empty())
+      OS << "\n\n";
+    // Print the method without the 'virtual' specifier and the pure '= 0'
+    // annotation.
+    auto *MD = const_cast<CXXMethodDecl *>(Method);
+    bool IsVirtual = MD->isVirtualAsWritten();
+    MD->setVirtualAsWritten(false);
+    bool IsPure = MD->isPure();
+    MD->setPure(false);
+    MD->print(OS, PP);
+    MD->setVirtualAsWritten(IsVirtual);
+    MD->setPure(IsPure);
+
+    OS << " override";
+    if (GenerateBodyDummies)
+      OS << " { \n  <#code#>\n}\n";
+    else
+      OS << ";\n";
+    // Avoid an additional newline for the last method in an insertion group.
+    if (IsInsertingAfterRelatedMethods) {
+      const CXXRecordDecl *NextAbstractClass =
+          (I.index() + 1) != MissingMethods.size()
+              ? MissingMethods[I.index() + 1]->getParent()
+              : nullptr;
+      if (NextAbstractClass == CurrentAbstractClass)
+        OS << "\n";
+    } else
+      OS << "\n";
+  }
+  if (!InsertionGroupOS.str().empty()) {
+    assert(CurrentGroupInsertionLoc.isValid());
+    Replacements.emplace_back(
+        SourceRange(CurrentGroupInsertionLoc, CurrentGroupInsertionLoc),
+        InsertionGroupOS.str());
+  }
+  if (!EndInsertionOS.str().empty())
+    Replacements.emplace_back(SourceRange(InsertionLoc, InsertionLoc),
+                              EndInsertionOS.str());
+
+  return std::move(Replacements);
+}
diff --git a/lib/Tooling/Refactor/FillInMissingProtocolStubs.cpp b/lib/Tooling/Refactor/FillInMissingProtocolStubs.cpp
new file mode 100644
index 0000000..de8cfbe
--- /dev/null
+++ b/lib/Tooling/Refactor/FillInMissingProtocolStubs.cpp
@@ -0,0 +1,91 @@
+//===--- FillInMissingProtocolStubs.cpp -  --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the "Add methods from protocol(s)" refactoring operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RefactoringOperations.h"
+#include "clang/AST/AST.h"
+#include "clang/Edit/RefactoringFixits.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace edit::fillInMissingProtocolStubs;
+
+namespace {
+
+class FillInMissingProtocolStubsOperation : public RefactoringOperation {
+public:
+  FillInMissingProtocolStubsOperation(const ObjCContainerDecl *Container,
+                                      FillInMissingProtocolStubs Impl)
+      : Container(Container), Impl(std::move(Impl)) {}
+
+  const Decl *getTransformedDecl() const override { return Container; }
+
+  llvm::Expected<RefactoringResult> perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex) override;
+
+  const ObjCContainerDecl *Container;
+  FillInMissingProtocolStubs Impl;
+};
+
+} // end anonymous namespace
+
+RefactoringOperationResult
+clang::tooling::initiateFillInMissingProtocolStubsOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  auto SelectedDecl = Slice.innermostSelectedDecl(
+      {Decl::ObjCImplementation, Decl::ObjCCategoryImpl, Decl::ObjCInterface,
+       Decl::ObjCCategory},
+      ASTSlice::InnermostDeclOnly);
+  if (!SelectedDecl)
+    return None;
+  const auto *Container = cast<ObjCContainerDecl>(SelectedDecl->getDecl());
+
+  // If this in a class extension, initiate the operation on the @implementation
+  // if it's in the same TU.
+  if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
+    if (Category->IsClassExtension()) {
+      const ObjCInterfaceDecl *I = Category->getClassInterface();
+      if (I && I->getImplementation())
+        Container = I->getImplementation();
+      else
+        return RefactoringOperationResult(
+            "Class extension without suitable @implementation");
+    }
+  }
+
+  FillInMissingProtocolStubs Impl;
+  if (Impl.initiate(Context, Container))
+    return None;
+  if (!Impl.hasMissingRequiredMethodStubs())
+    return RefactoringOperationResult("All of the @required methods are there");
+
+  RefactoringOperationResult Result;
+  Result.Initiated = true;
+  if (!CreateOperation)
+    return Result;
+  auto Operation = llvm::make_unique<FillInMissingProtocolStubsOperation>(
+      Container, std::move(Impl));
+  Result.RefactoringOp = std::move(Operation);
+  return Result;
+}
+
+llvm::Expected<RefactoringResult>
+FillInMissingProtocolStubsOperation::perform(
+    ASTContext &Context, const Preprocessor &ThePreprocessor,
+    const RefactoringOptionSet &Options, unsigned SelectedCandidateIndex) {
+  std::vector<RefactoringReplacement> Replacements;
+  Impl.perform(Context,
+               [&](const FixItHint &Hint) { Replacements.push_back(Hint); });
+  return std::move(Replacements);
+}
diff --git a/lib/Tooling/Refactor/IfSwitchConversion.cpp b/lib/Tooling/Refactor/IfSwitchConversion.cpp
new file mode 100644
index 0000000..5ce3955
--- /dev/null
+++ b/lib/Tooling/Refactor/IfSwitchConversion.cpp
@@ -0,0 +1,468 @@
+//===--- IfSwitchConversion.cpp -  ----------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the "convert to switch" refactoring operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RefactoringOperations.h"
+#include "SourceLocationUtilities.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+using namespace clang::tooling;
+
+namespace {
+
+class IfSwitchConversionOperation : public RefactoringOperation {
+public:
+  IfSwitchConversionOperation(const IfStmt *If) : If(If) {}
+
+  const Stmt *getTransformedStmt() const override { return If; }
+
+  llvm::Expected<RefactoringResult> perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex) override;
+
+  const IfStmt *If;
+};
+
+class ValidIfBodyVerifier : public RecursiveASTVisitor<ValidIfBodyVerifier> {
+  bool CheckBreaks = true;
+
+public:
+  bool IsValid = true;
+
+  bool VisitBreakStmt(const BreakStmt *S) {
+    if (!CheckBreaks)
+      return true;
+    IsValid = false;
+    return false;
+  }
+  bool VisitDefaultStmt(const DefaultStmt *S) {
+    IsValid = false;
+    return false;
+  }
+  bool VisitCaseStmt(const CaseStmt *S) {
+    IsValid = false;
+    return false;
+  }
+
+// Handle nested loops:
+
+#define TRAVERSE_LOOP(STMT)                                                    \
+  bool Traverse##STMT(STMT *S) {                                               \
+    bool Prev = CheckBreaks;                                                   \
+    CheckBreaks = false;                                                       \
+    RecursiveASTVisitor::Traverse##STMT(S);                                    \
+    CheckBreaks = Prev;                                                        \
+    return true;                                                               \
+  }
+
+  TRAVERSE_LOOP(ForStmt)
+  TRAVERSE_LOOP(WhileStmt)
+  TRAVERSE_LOOP(DoStmt)
+  TRAVERSE_LOOP(CXXForRangeStmt)
+  TRAVERSE_LOOP(ObjCForCollectionStmt)
+
+#undef TRAVERSE_LOOP
+
+  // Handle switches:
+
+  bool TraverseSwitchStmt(SwitchStmt *S) {
+    // Don't visit the body as 'break'/'case'/'default' are all allowed inside
+    // switches.
+    return true;
+  }
+};
+
+} // end anonymous namespace
+
+/// Returns true if any of the if statements in the given if construct have
+/// conditions that aren't allowed by the "convert to switch" operation.
+static bool checkIfsHaveConditionExpression(const IfStmt *If) {
+  for (; If; If = dyn_cast_or_null<IfStmt>(If->getElse())) {
+    if (If->getConditionVariable() || If->getInit() || !If->getCond())
+      return true;
+  }
+  return false;
+}
+
+static Optional<std::pair<const Expr *, const Expr *>>
+matchBinOp(const Expr *E, BinaryOperator::Opcode Kind) {
+  const auto *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
+  if (!BinOp || BinOp->getOpcode() != Kind)
+    return None;
+  return std::pair<const Expr *, const Expr *>(
+      BinOp->getLHS()->IgnoreParenImpCasts(), BinOp->getRHS()->IgnoreParens());
+}
+
+typedef llvm::SmallDenseSet<int64_t, 4> RHSValueSet;
+
+/// Returns true if the conditional expression of an 'if' statement allows
+/// the "convert to switch" refactoring action.
+static bool isConditionValid(const Expr *E, ASTContext &Context,
+                             Optional<llvm::FoldingSetNodeID> &MatchedLHSNodeID,
+                             RHSValueSet &RHSValues) {
+  auto Equals = matchBinOp(E, BO_EQ);
+  if (!Equals.hasValue()) {
+    auto LogicalOr = matchBinOp(E, BO_LOr);
+    if (!LogicalOr.hasValue())
+      return false;
+    return isConditionValid(LogicalOr.getValue().first, Context,
+                            MatchedLHSNodeID, RHSValues) &&
+           isConditionValid(LogicalOr.getValue().second, Context,
+                            MatchedLHSNodeID, RHSValues);
+  }
+  const Expr *LHS = Equals.getValue().first;
+  const Expr *RHS = Equals.getValue().second;
+  if (!LHS->getType()->isIntegralOrEnumerationType() ||
+      !RHS->getType()->isIntegralOrEnumerationType())
+    return false;
+
+  // RHS must be a constant and unique.
+  llvm::APSInt Value;
+  if (!RHS->EvaluateAsInt(Value, Context))
+    return false;
+  // Only allow constant that fix into 64 bits.
+  if (Value.getMinSignedBits() > 64 ||
+      !RHSValues.insert(Value.getExtValue()).second)
+    return false;
+
+  // LHS must be identical to the other LHS expressions.
+  llvm::FoldingSetNodeID LHSNodeID;
+  LHS->Profile(LHSNodeID, Context, /*Canonical=*/false);
+  if (MatchedLHSNodeID.hasValue()) {
+    if (MatchedLHSNodeID.getValue() != LHSNodeID)
+      return false;
+  } else
+    MatchedLHSNodeID = std::move(LHSNodeID);
+  return true;
+}
+
+RefactoringOperationResult clang::tooling::initiateIfSwitchConversionOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  // FIXME: Add support for selections.
+  const auto *If = cast_or_null<IfStmt>(Slice.nearestStmt(Stmt::IfStmtClass));
+  if (!If)
+    return None;
+
+  // Don't allow if statements without any 'else' or 'else if'.
+  if (!If->getElse())
+    return None;
+
+  // Don't allow ifs with variable declarations in conditions or C++17
+  // initializer statements.
+  if (checkIfsHaveConditionExpression(If))
+    return None;
+
+  // Find the ranges in which initiation can be performed and verify that the
+  // ifs don't have any initialization expressions or condition variables.
+  SmallVector<SourceRange, 4> Ranges;
+  SourceLocation RangeStart = If->getLocStart();
+  const IfStmt *CurrentIf = If;
+  const SourceManager &SM = Context.getSourceManager();
+  while (true) {
+    const Stmt *Then = CurrentIf->getThen();
+    Ranges.emplace_back(RangeStart,
+                        findLastLocationOfSourceConstruct(
+                            CurrentIf->getCond()->getLocEnd(), Then, SM));
+    const auto *Else = CurrentIf->getElse();
+    if (!Else)
+      break;
+    RangeStart =
+        findFirstLocationOfSourceConstruct(CurrentIf->getElseLoc(), Then, SM);
+    if (const auto *If = dyn_cast<IfStmt>(Else)) {
+      CurrentIf = If;
+      continue;
+    }
+    Ranges.emplace_back(RangeStart, findLastLocationOfSourceConstruct(
+                                        CurrentIf->getElseLoc(), Else, SM));
+    break;
+  }
+
+  if (!isLocationInAnyRange(Location, Ranges, SM))
+    return None;
+
+  // Verify that the bodies don't have any 'break'/'default'/'case' statements.
+  ValidIfBodyVerifier BodyVerifier;
+  BodyVerifier.TraverseStmt(const_cast<IfStmt *>(If));
+  if (!BodyVerifier.IsValid)
+    return RefactoringOperationResult(
+        "if's body contains a 'break'/'default'/'case' statement");
+
+  // FIXME: Use ASTMatchers if possible.
+  Optional<llvm::FoldingSetNodeID> MatchedLHSNodeID;
+  RHSValueSet RHSValues;
+  for (const IfStmt *CurrentIf = If; CurrentIf;
+       CurrentIf = dyn_cast_or_null<IfStmt>(CurrentIf->getElse())) {
+    if (!isConditionValid(CurrentIf->getCond(), Context, MatchedLHSNodeID,
+                          RHSValues))
+      return RefactoringOperationResult("unsupported conditional expression");
+  }
+
+  RefactoringOperationResult Result;
+  Result.Initiated = true;
+  if (CreateOperation)
+    Result.RefactoringOp.reset(new IfSwitchConversionOperation(If));
+  return Result;
+}
+
+/// Returns the first LHS expression in the if's condition.
+const Expr *getConditionFirstLHS(const Expr *E) {
+  auto Equals = matchBinOp(E, BO_EQ);
+  if (!Equals.hasValue()) {
+    auto LogicalOr = matchBinOp(E, BO_LOr);
+    if (!LogicalOr.hasValue())
+      return nullptr;
+    return getConditionFirstLHS(LogicalOr.getValue().first);
+  }
+  return Equals.getValue().first;
+}
+
+/// Gathers all of the RHS operands of the == expressions in the if's condition.
+void gatherCaseValues(const Expr *E,
+                      SmallVectorImpl<const Expr *> &CaseValues) {
+  auto Equals = matchBinOp(E, BO_EQ);
+  if (Equals.hasValue()) {
+    CaseValues.push_back(Equals.getValue().second);
+    return;
+  }
+  auto LogicalOr = matchBinOp(E, BO_LOr);
+  if (!LogicalOr.hasValue())
+    return;
+  gatherCaseValues(LogicalOr.getValue().first, CaseValues);
+  gatherCaseValues(LogicalOr.getValue().second, CaseValues);
+}
+
+/// Return true iff the given body should be terminated with a 'break' statement
+/// when used inside of a switch.
+static bool isBreakNeeded(const Stmt *Body) {
+  const auto *CS = dyn_cast<CompoundStmt>(Body);
+  if (!CS)
+    return !isa<ReturnStmt>(Body);
+  return CS->body_empty() ? true : isBreakNeeded(CS->body_back());
+}
+
+/// Returns true if the given statement declares a variable.
+static bool isVarDeclaringStatement(const Stmt *S) {
+  const auto *DS = dyn_cast<DeclStmt>(S);
+  if (!DS)
+    return false;
+  for (const Decl *D : DS->decls()) {
+    if (isa<VarDecl>(D))
+      return true;
+  }
+  return false;
+}
+
+/// Return true if the body of an if/else if/else needs to be wrapped in braces
+/// when put in a switch.
+static bool areBracesNeeded(const Stmt *Body) {
+  const auto *CS = dyn_cast<CompoundStmt>(Body);
+  if (!CS)
+    return isVarDeclaringStatement(Body);
+  for (const Stmt *S : CS->body()) {
+    if (isVarDeclaringStatement(S))
+      return true;
+  }
+  return false;
+}
+
+namespace {
+
+/// Information about the replacement that replaces 'if'/'else' with a 'case' or
+/// a 'default'.
+struct CasePlacement {
+  /// The location of the 'case' or 'default'.
+  SourceLocation CaseStartLoc;
+  /// True when this 'case' or 'default' statement needs a newline.
+  bool NeedsNewLine;
+  /// True if this the first 'if' in the source construct.
+  bool IsFirstIf;
+  /// True if we need to insert a 'break' to terminate the previous body
+  /// before the 'case' or 'default'.
+  bool IsBreakNeeded;
+  /// True if we need to insert a '}' before the case.
+  bool ArePreviousBracesNeeded;
+
+  CasePlacement(SourceLocation Loc)
+      : CaseStartLoc(Loc), NeedsNewLine(false), IsFirstIf(true),
+        IsBreakNeeded(false), ArePreviousBracesNeeded(false) {}
+
+  CasePlacement(const IfStmt *If, const SourceManager &SM,
+                bool AreBracesNeeded) {
+    CaseStartLoc = SM.getSpellingLoc(isa<CompoundStmt>(If->getThen())
+                                         ? If->getThen()->getLocEnd()
+                                         : If->getElseLoc());
+    SourceLocation BodyEndLoc = findLastNonCompoundLocation(If->getThen());
+    NeedsNewLine = BodyEndLoc.isValid()
+                       ? areOnSameLine(CaseStartLoc, BodyEndLoc, SM)
+                       : false;
+    IsFirstIf = false;
+    IsBreakNeeded = isBreakNeeded(If->getThen());
+    ArePreviousBracesNeeded = AreBracesNeeded;
+  }
+
+  std::string getCaseReplacementString(bool IsDefault = false,
+                                       bool AreNextBracesNeeded = false) const {
+    if (IsFirstIf)
+      return ") {\ncase ";
+    std::string Result;
+    llvm::raw_string_ostream OS(Result);
+    if (NeedsNewLine)
+      OS << '\n';
+    if (IsBreakNeeded)
+      OS << "break;\n";
+    if (ArePreviousBracesNeeded)
+      OS << "}\n";
+    OS << (IsDefault ? "default:" : "case ");
+    if (IsDefault && AreNextBracesNeeded)
+      OS << " {";
+    return std::move(OS.str());
+  }
+};
+
+} // end anonymous namespace
+
+static llvm::Error
+addCaseReplacements(const IfStmt *If, const CasePlacement &CaseInfo,
+                    bool &AreBracesNeeded,
+                    std::vector<RefactoringReplacement> &Replacements,
+                    const SourceManager &SM, const LangOptions &LangOpts) {
+  SmallVector<const Expr *, 2> CaseValues;
+  gatherCaseValues(If->getCond(), CaseValues);
+  assert(!CaseValues.empty());
+  Replacements.emplace_back(
+      SourceRange(CaseInfo.CaseStartLoc,
+                  SM.getSpellingLoc(CaseValues[0]->getLocStart())),
+      CaseInfo.getCaseReplacementString());
+
+  SourceLocation PrevCaseEnd = getPreciseTokenLocEnd(
+      SM.getSpellingLoc(CaseValues[0]->getLocEnd()), SM, LangOpts);
+  for (const Expr *CaseValue : llvm::makeArrayRef(CaseValues).drop_front()) {
+    Replacements.emplace_back(
+        SourceRange(PrevCaseEnd, SM.getSpellingLoc(CaseValue->getLocStart())),
+        StringRef(":\ncase "));
+    PrevCaseEnd = getPreciseTokenLocEnd(
+        SM.getSpellingLoc(CaseValue->getLocEnd()), SM, LangOpts);
+  }
+
+  AreBracesNeeded = areBracesNeeded(If->getThen());
+  StringRef ColonReplacement = AreBracesNeeded ? ": {" : ":";
+  if (isa<CompoundStmt>(If->getThen())) {
+    Replacements.emplace_back(
+        SourceRange(
+            PrevCaseEnd,
+            getPreciseTokenLocEnd(
+                SM.getSpellingLoc(If->getThen()->getLocStart()), SM, LangOpts)),
+        ColonReplacement);
+  } else {
+    // Find the location of the if's ')'
+    SourceLocation End = findClosingParenLocEnd(
+        SM.getSpellingLoc(If->getCond()->getLocEnd()), SM, LangOpts);
+    if (!End.isValid())
+      return llvm::make_error<RefactoringOperationError>(
+          "couldn't find the location of ')'");
+    Replacements.emplace_back(SourceRange(PrevCaseEnd, End), ColonReplacement);
+  }
+  return llvm::Error::success();
+}
+
+llvm::Expected<RefactoringResult>
+IfSwitchConversionOperation::perform(ASTContext &Context,
+                                     const Preprocessor &ThePreprocessor,
+                                     const RefactoringOptionSet &Options,
+                                     unsigned SelectedCandidateIndex) {
+  std::vector<RefactoringReplacement> Replacements;
+  const SourceManager &SM = Context.getSourceManager();
+  const LangOptions &LangOpts = Context.getLangOpts();
+
+  // The first if should be replaced with a 'switch' and the text for first LHS
+  // should be preserved.
+  const Expr *LHS = getConditionFirstLHS(If->getCond());
+  assert(LHS && "Missing == expression");
+  Replacements.emplace_back(SourceRange(SM.getSpellingLoc(If->getLocStart()),
+                                        SM.getSpellingLoc(LHS->getLocStart())),
+                            StringRef("switch ("));
+
+  bool AreBracesNeeded = false;
+  if (auto Error = addCaseReplacements(
+          If, CasePlacement(getPreciseTokenLocEnd(
+                  SM.getSpellingLoc(LHS->getLocEnd()), SM, LangOpts)),
+          AreBracesNeeded, Replacements, SM, LangOpts))
+    return std::move(Error);
+
+  // Convert the remaining ifs to 'case' statements.
+  const IfStmt *CurrentIf = If;
+  while (true) {
+    const IfStmt *NextIf = dyn_cast_or_null<IfStmt>(CurrentIf->getElse());
+    if (!NextIf)
+      break;
+    if (auto Error = addCaseReplacements(
+            NextIf, CasePlacement(CurrentIf, SM, AreBracesNeeded),
+            AreBracesNeeded, Replacements, SM, LangOpts))
+      return std::move(Error);
+    CurrentIf = NextIf;
+  }
+
+  // Convert the 'else' to 'default'
+  if (const Stmt *Else = CurrentIf->getElse()) {
+    CasePlacement DefaultInfo(CurrentIf, SM, AreBracesNeeded);
+    AreBracesNeeded = areBracesNeeded(Else);
+
+    SourceLocation EndLoc = getPreciseTokenLocEnd(
+        SM.getSpellingLoc(isa<CompoundStmt>(Else) ? Else->getLocStart()
+                                                  : CurrentIf->getElseLoc()),
+        SM, LangOpts);
+    Replacements.emplace_back(SourceRange(DefaultInfo.CaseStartLoc, EndLoc),
+                              DefaultInfo.getCaseReplacementString(
+                                  /*IsDefault=*/true, AreBracesNeeded));
+  }
+
+  // Add the trailing break and one or two '}' if needed.
+  const Stmt *LastBody =
+      CurrentIf->getElse() ? CurrentIf->getElse() : CurrentIf->getThen();
+  bool IsLastBreakNeeded = isBreakNeeded(LastBody);
+  SourceLocation TerminatingReplacementLoc;
+  std::string TerminatingReplacement;
+  llvm::raw_string_ostream OS(TerminatingReplacement);
+  if (!isa<CompoundStmt>(LastBody)) {
+    TerminatingReplacementLoc = LastBody->getLocEnd();
+    // Try to adjust the location in order to preserve any trailing comments on
+    // the last line of the last body.
+    if (!TerminatingReplacementLoc.isMacroID())
+      TerminatingReplacementLoc = getLastLineLocationUnlessItHasOtherTokens(
+          TerminatingReplacementLoc, SM, LangOpts);
+    if (IsLastBreakNeeded)
+      OS << "\nbreak;";
+    OS << "\n}";
+    if (AreBracesNeeded)
+      OS << "\n}";
+  } else {
+    TerminatingReplacementLoc = LastBody->getLocEnd();
+    if (IsLastBreakNeeded)
+      OS << "break;\n";
+    if (AreBracesNeeded)
+      OS << "}\n";
+  }
+
+  if (!OS.str().empty()) {
+    TerminatingReplacementLoc = SM.getSpellingLoc(TerminatingReplacementLoc);
+    Replacements.emplace_back(
+        SourceRange(TerminatingReplacementLoc, TerminatingReplacementLoc),
+        std::move(OS.str()));
+  }
+
+  return std::move(Replacements);
+}
diff --git a/lib/Tooling/Refactor/ImplementDeclaredMethods.cpp b/lib/Tooling/Refactor/ImplementDeclaredMethods.cpp
new file mode 100644
index 0000000..c5865e4
--- /dev/null
+++ b/lib/Tooling/Refactor/ImplementDeclaredMethods.cpp
@@ -0,0 +1,446 @@
+//===--- ImplementDeclaredMethods.cpp -  ----------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the "Generate missing method definitions" refactoring
+// operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RefactoringContinuations.h"
+#include "RefactoringOperations.h"
+#include "SourceLocationUtilities.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+using namespace clang;
+using namespace clang::tooling;
+
+namespace {
+
+template <typename ClassType, typename MethodType, typename Derived>
+class ImplementDeclaredMethodsOperation : public RefactoringOperation {
+public:
+  ImplementDeclaredMethodsOperation(
+      const ClassType *Container, ArrayRef<const MethodType *> SelectedMethods)
+      : Container(Container),
+        SelectedMethods(SelectedMethods.begin(), SelectedMethods.end()) {}
+
+  const Decl *getTransformedDecl() const override {
+    return SelectedMethods.front();
+  }
+
+  const Decl *getLastTransformedDecl() const override {
+    return SelectedMethods.back();
+  }
+
+  static RefactoringOperationResult
+  initiate(const ClassType *Container, ArrayRef<const MethodType *> Methods,
+           bool CreateOperation) {
+    if (Methods.empty())
+      return None;
+
+    RefactoringOperationResult Result;
+    Result.Initiated = true;
+    if (!CreateOperation)
+      return Result;
+    auto Operation = llvm::make_unique<Derived>(Container, Methods);
+    Result.RefactoringOp = std::move(Operation);
+    return Result;
+  }
+
+  const ClassType *Container;
+  llvm::SmallVector<const MethodType *, 8> SelectedMethods;
+};
+
+class ImplementDeclaredCXXMethodsOperation
+    : public ImplementDeclaredMethodsOperation<
+          CXXRecordDecl, CXXMethodDecl, ImplementDeclaredCXXMethodsOperation> {
+public:
+  ImplementDeclaredCXXMethodsOperation(
+      const CXXRecordDecl *Container,
+      ArrayRef<const CXXMethodDecl *> SelectedMethods)
+      : ImplementDeclaredMethodsOperation(Container, SelectedMethods) {}
+
+  llvm::Expected<RefactoringResult>
+  perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex) override;
+
+  static void addInlineBody(const CXXMethodDecl *MD, const ASTContext &Context,
+                            std::vector<RefactoringReplacement> &Replacements);
+
+  static llvm::Expected<RefactoringResult> runInImplementationAST(
+      ASTContext &Context, const FileID &File, const CXXRecordDecl *Class,
+      ArrayRef<indexer::Indexed<const CXXMethodDecl *>> SelectedMethods);
+};
+
+class ImplementDeclaredObjCMethodsOperation
+    : public ImplementDeclaredMethodsOperation<
+          ObjCContainerDecl, ObjCMethodDecl,
+          ImplementDeclaredObjCMethodsOperation> {
+  const ObjCInterfaceDecl *Interface;
+
+public:
+  ImplementDeclaredObjCMethodsOperation(
+      const ObjCContainerDecl *Container,
+      ArrayRef<const ObjCMethodDecl *> SelectedMethods)
+      : ImplementDeclaredMethodsOperation(Container, SelectedMethods) {
+    if (const auto *CD = dyn_cast<ObjCCategoryDecl>(Container))
+      Interface = CD->getClassInterface();
+    else
+      Interface = nullptr;
+  }
+
+  llvm::Expected<RefactoringResult>
+  perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex) override;
+
+  static llvm::Expected<RefactoringResult> runInImplementationAST(
+      ASTContext &Context, const FileID &File,
+      const ObjCContainerDecl *Container, const ObjCInterfaceDecl *Interface,
+      ArrayRef<std::string> MethodDeclarations,
+      ArrayRef<indexer::Indexed<const ObjCMethodDecl *>> SelectedMethods);
+};
+
+/// Returns true if the given Objective-C method has an implementation.
+bool isImplemented(const ObjCMethodDecl *M) {
+  if (M->hasBody() || M->isDefined())
+    return true;
+  return false;
+}
+
+} // end anonymous namespace
+
+RefactoringOperationResult
+clang::tooling::initiateImplementDeclaredMethodsOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  // Find the selected Class.
+  auto SelectedDecl = Slice.innermostSelectedDecl([](const Decl *D) {
+    return isa<CXXRecordDecl>(D) || isa<ObjCInterfaceDecl>(D) ||
+           isa<ObjCCategoryDecl>(D);
+  });
+  if (!SelectedDecl)
+    return None;
+  // Look at the set of methods that intersect with the selection.
+  if (const auto *CXXClass = dyn_cast<CXXRecordDecl>(SelectedDecl->getDecl())) {
+    if (CXXClass->isDependentType())
+      return RefactoringOperationResult("templates are unsupported");
+    llvm::SmallVector<const CXXMethodDecl *, 8> SelectedMethods;
+    for (const CXXMethodDecl *M : CXXClass->methods()) {
+      if (M->isImplicit() || M->hasBody() || M->isPure() || M->isDefaulted() ||
+          M->isDeletedAsWritten() || M->getDescribedFunctionTemplate())
+        continue;
+      if (Slice.isSourceRangeSelected(
+              CharSourceRange::getTokenRange(M->getSourceRange())))
+        SelectedMethods.push_back(M);
+    }
+    return ImplementDeclaredCXXMethodsOperation::initiate(
+        CXXClass, SelectedMethods, CreateOperation);
+  }
+  const ObjCContainerDecl *Container =
+      cast<ObjCContainerDecl>(SelectedDecl->getDecl());
+  llvm::SmallVector<const ObjCMethodDecl *, 8> SelectedMethods;
+  for (const ObjCMethodDecl *M : Container->methods()) {
+    if (M->isImplicit() || isImplemented(M))
+      continue;
+    if (Slice.isSourceRangeSelected(
+            CharSourceRange::getTokenRange(M->getSourceRange())))
+      SelectedMethods.push_back(M);
+  }
+  // Method declarations from class extensions should be defined in class
+  // @implementations.
+  if (const auto *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
+    if (Category->IsClassExtension())
+      Container = Category->getClassInterface();
+  }
+  return ImplementDeclaredObjCMethodsOperation::initiate(
+      Container, SelectedMethods, CreateOperation);
+}
+
+llvm::Expected<RefactoringResult>
+ImplementDeclaredCXXMethodsOperation::perform(
+    ASTContext &Context, const Preprocessor &ThePreprocessor,
+    const RefactoringOptionSet &Options, unsigned SelectedCandidateIndex) {
+  if (Container->isLexicallyWithinFunctionOrMethod()) {
+    // Local methods can be implemented inline.
+    std::vector<RefactoringReplacement> Replacements;
+    for (const CXXMethodDecl *MD : SelectedMethods)
+      addInlineBody(MD, Context, Replacements);
+    return std::move(Replacements);
+  }
+  using namespace indexer;
+  return continueInExternalASTUnit(
+      fileThatShouldContainImplementationOf(Container), runInImplementationAST,
+      Container, filter(llvm::makeArrayRef(SelectedMethods),
+                        [](const DeclEntity &D) { return !D.isDefined(); }));
+}
+
+void ImplementDeclaredCXXMethodsOperation::addInlineBody(
+    const CXXMethodDecl *MD, const ASTContext &Context,
+    std::vector<RefactoringReplacement> &Replacements) {
+  SourceLocation EndLoc = MD->getLocEnd();
+  SourceRange SemiRange = getRangeOfNextToken(
+      EndLoc, tok::semi, Context.getSourceManager(), Context.getLangOpts());
+  if (SemiRange.isValid()) {
+    Replacements.push_back(RefactoringReplacement(SemiRange));
+    EndLoc = SemiRange.getEnd();
+  }
+  SourceLocation InsertionLoc = getLastLineLocationUnlessItHasOtherTokens(
+      EndLoc, Context.getSourceManager(), Context.getLangOpts());
+  Replacements.push_back(
+      RefactoringReplacement(SourceRange(InsertionLoc, InsertionLoc),
+                             StringRef(" { \n  <#code#>;\n}")));
+}
+
+static const RecordDecl *findOutermostRecord(const RecordDecl *RD) {
+  const RecordDecl *Result = RD;
+  for (const DeclContext *DC = Result->getLexicalDeclContext();
+       isa<RecordDecl>(DC); DC = Result->getLexicalDeclContext())
+    Result = cast<RecordDecl>(DC);
+  return Result;
+}
+
+static bool containsUsingOf(const NamespaceDecl *ND,
+                            const ASTContext &Context) {
+  for (const Decl *D : Context.getTranslationUnitDecl()->decls()) {
+    if (const auto *UDD = dyn_cast<UsingDirectiveDecl>(D)) {
+      if (UDD->getNominatedNamespace() == ND)
+        return true;
+    }
+  }
+  return false;
+}
+
+llvm::Expected<RefactoringResult>
+ImplementDeclaredCXXMethodsOperation::runInImplementationAST(
+    ASTContext &Context, const FileID &File, const CXXRecordDecl *Class,
+    ArrayRef<indexer::Indexed<const CXXMethodDecl *>> SelectedMethods) {
+  if (!Class)
+    return llvm::make_error<RefactoringOperationError>(
+        "the target class is not defined in the continuation AST unit");
+
+  SourceManager &SM = Context.getSourceManager();
+
+  // Find the defined methods of the class.
+  llvm::SmallVector<const CXXMethodDecl *, 8> DefinedOutOfLineMethods;
+  for (const CXXMethodDecl *M : Class->methods()) {
+    if (M->isImplicit())
+      continue;
+    if (const FunctionDecl *MD = M->getDefinition()) {
+      if (!MD->isOutOfLine())
+        continue;
+      SourceLocation Loc = SM.getExpansionLoc(MD->getLocStart());
+      if (SM.getFileID(Loc) == File)
+        DefinedOutOfLineMethods.push_back(cast<CXXMethodDecl>(MD));
+    }
+  }
+
+  std::vector<RefactoringReplacement> Replacements;
+  std::string MethodString;
+  llvm::raw_string_ostream OS(MethodString);
+
+  // Pick a good insertion location.
+  SourceLocation InsertionLoc;
+  const CXXMethodDecl *InsertAfterMethod = nullptr;
+  NestedNameSpecifier *NamePrefix = nullptr;
+  if (DefinedOutOfLineMethods.empty()) {
+    const RecordDecl *OutermostRecord = findOutermostRecord(Class);
+    InsertionLoc = SM.getExpansionRange(OutermostRecord->getLocEnd()).second;
+    if (SM.getFileID(InsertionLoc) == File) {
+      // We can insert right after the class. Compute the appropriate
+      // qualification.
+      NamePrefix = NestedNameSpecifier::getRequiredQualification(
+          Context, OutermostRecord->getLexicalDeclContext(),
+          Class->getLexicalDeclContext());
+    } else {
+      // We can't insert after the end of the class, since the indexer told us
+      // that some file should have the implementation of it, even when there
+      // are no methods here. We should try to insert at the end of the file.
+      InsertionLoc = SM.getLocForEndOfFile(File);
+      NamePrefix = NestedNameSpecifier::getRequiredQualification(
+          Context, Context.getTranslationUnitDecl(),
+          Class->getLexicalDeclContext());
+      llvm::SmallVector<const NamespaceDecl *, 4> Namespaces;
+      for (const NestedNameSpecifier *Qualifier = NamePrefix; Qualifier;
+           Qualifier = Qualifier->getPrefix()) {
+        if (const NamespaceDecl *ND = Qualifier->getAsNamespace())
+          Namespaces.push_back(ND);
+      }
+      // When the class is in a namespace, add a 'using' declaration if it's
+      // needed and adjust the out-of-line qualification.
+      if (!Namespaces.empty()) {
+        const NamespaceDecl *InnermostNamespace = Namespaces[0];
+        if (!containsUsingOf(InnermostNamespace, Context)) {
+          std::string NamespaceString;
+          llvm::raw_string_ostream NamespaceOS(NamespaceString);
+          for (const NamespaceDecl *ND : llvm::reverse(Namespaces)) {
+            if (!NamespaceOS.str().empty())
+              NamespaceOS << "::";
+            NamespaceOS << ND->getDeclName();
+          }
+          OS << "\nusing namespace " << NamespaceOS.str() << ";";
+        }
+        // Re-compute the name qualifier without the namespace.
+        NamePrefix = NestedNameSpecifier::getRequiredQualification(
+            Context, InnermostNamespace, Class->getLexicalDeclContext());
+      }
+    }
+  } else {
+    // Insert at the end of the defined methods.
+    for (const CXXMethodDecl *M : DefinedOutOfLineMethods) {
+      SourceLocation EndLoc = SM.getExpansionRange(M->getLocEnd()).second;
+      if (InsertionLoc.isInvalid() ||
+          SM.isBeforeInTranslationUnit(InsertionLoc, EndLoc)) {
+        InsertionLoc = EndLoc;
+        InsertAfterMethod = M;
+      }
+    }
+  }
+  InsertionLoc = getLastLineLocationUnlessItHasOtherTokens(
+      InsertionLoc, SM, Context.getLangOpts());
+
+  PrintingPolicy PP = Context.getPrintingPolicy();
+  PP.PolishForDeclaration = true;
+  PP.SupressStorageClassSpecifiers = true;
+  PP.SuppressStrongLifetime = true;
+  PP.SuppressLifetimeQualifiers = true;
+  PP.SuppressUnwrittenScope = true;
+  OS << "\n";
+  for (const auto &I : SelectedMethods) {
+    const CXXMethodDecl *MD = I.Decl;
+    // Check if the method is already defined.
+    if (!MD)
+      continue;
+
+    // Drop the 'virtual' specifier.
+    bool IsVirtual = MD->isVirtualAsWritten();
+    const_cast<CXXMethodDecl *>(MD)->setVirtualAsWritten(false);
+
+    // Drop the default arguments.
+    llvm::SmallVector<std::pair<ParmVarDecl *, Expr *>, 4> DefaultArgs;
+    for (const ParmVarDecl *P : MD->parameters()) {
+      if (!P->hasDefaultArg())
+        continue;
+      Expr *E = const_cast<ParmVarDecl *>(P)->getDefaultArg();
+      const_cast<ParmVarDecl *>(P)->setDefaultArg(nullptr);
+      DefaultArgs.emplace_back(const_cast<ParmVarDecl *>(P), E);
+    }
+
+    // Add the nested name specifiers that are appropriate for an out-of-line
+    // method.
+    auto *Qualifier =
+        InsertAfterMethod
+            ? InsertAfterMethod->getQualifier()
+            : NestedNameSpecifier::Create(
+                  Context, /*Prefix=*/NamePrefix, /*Template=*/false,
+                  Context.getRecordType(Class).getTypePtr());
+    NestedNameSpecifierLoc PrevQualifierInfo = MD->getQualifierLoc();
+    const_cast<CXXMethodDecl *>(MD)->setQualifierInfo(
+        NestedNameSpecifierLoc(Qualifier, /*Loc=*/nullptr));
+
+    OS << "\n";
+    MD->print(OS, PP);
+    OS << " { \n  <#code#>;\n}\n";
+
+    // Restore the original method
+    for (const auto &DefaultArg : DefaultArgs)
+      DefaultArg.first->setDefaultArg(DefaultArg.second);
+    const_cast<CXXMethodDecl *>(MD)->setVirtualAsWritten(IsVirtual);
+    const_cast<CXXMethodDecl *>(MD)->setQualifierInfo(PrevQualifierInfo);
+  }
+
+  Replacements.push_back(RefactoringReplacement(
+      SourceRange(InsertionLoc, InsertionLoc), std::move(OS.str())));
+
+  return std::move(Replacements);
+}
+
+llvm::Expected<RefactoringResult>
+ImplementDeclaredObjCMethodsOperation::perform(
+    ASTContext &Context, const Preprocessor &ThePreprocessor,
+    const RefactoringOptionSet &Options, unsigned SelectedCandidateIndex) {
+  using namespace indexer;
+
+  // Print the methods before running the continuation because the continuation
+  // TU might not have these method declarations (e.g. category implemented in
+  // the class implementation).
+  PrintingPolicy PP = Context.getPrintingPolicy();
+  PP.PolishForDeclaration = true;
+  PP.SuppressStrongLifetime = true;
+  PP.SuppressLifetimeQualifiers = true;
+  PP.SuppressUnwrittenScope = true;
+  std::vector<std::string> MethodDeclarations;
+  for (const ObjCMethodDecl *MD : SelectedMethods) {
+    std::string MethodDeclStr;
+    llvm::raw_string_ostream MethodOS(MethodDeclStr);
+    MD->print(MethodOS, PP);
+    MethodDeclarations.push_back(std::move(MethodOS.str()));
+  }
+
+  return continueInExternalASTUnit(
+      fileThatShouldContainImplementationOf(Container), runInImplementationAST,
+      Container, Interface, MethodDeclarations,
+      filter(llvm::makeArrayRef(SelectedMethods),
+             [](const DeclEntity &D) { return !D.isDefined(); }));
+}
+
+static const ObjCImplDecl *
+getImplementationContainer(const ObjCContainerDecl *Container,
+                           const ObjCInterfaceDecl *Interface = nullptr) {
+  if (!Container)
+    return Interface ? getImplementationContainer(Interface) : nullptr;
+  if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(Container))
+    return ID->getImplementation();
+  if (const auto *CD = dyn_cast<ObjCCategoryDecl>(Container)) {
+    if (const auto *Impl = CD->getImplementation())
+      return Impl;
+    return getImplementationContainer(Interface);
+  }
+  return nullptr;
+}
+
+llvm::Expected<RefactoringResult>
+ImplementDeclaredObjCMethodsOperation::runInImplementationAST(
+    ASTContext &Context, const FileID &File, const ObjCContainerDecl *Container,
+    const ObjCInterfaceDecl *Interface,
+    ArrayRef<std::string> MethodDeclarations,
+    ArrayRef<indexer::Indexed<const ObjCMethodDecl *>> SelectedMethods) {
+  const ObjCImplDecl *ImplementationContainer =
+      getImplementationContainer(Container, Interface);
+  if (!ImplementationContainer)
+    return llvm::make_error<RefactoringOperationError>(
+        "the target @interface is not implemented in the continuation AST "
+        "unit");
+
+  std::vector<RefactoringReplacement> Replacements;
+
+  std::string MethodString;
+  llvm::raw_string_ostream OS(MethodString);
+
+  assert(MethodDeclarations.size() >= SelectedMethods.size() &&
+         "fewer declarations than selected methods?");
+  for (const auto &I : llvm::enumerate(SelectedMethods)) {
+    indexer::Indexed<const ObjCMethodDecl *> Decl = I.value();
+    // Skip methods that are already defined.
+    if (!Decl.isNotDefined())
+      continue;
+
+    OS << StringRef(MethodDeclarations[I.index()]).drop_back(); // Drop the ';'
+    OS << " { \n  <#code#>;\n}\n\n";
+  }
+  SourceLocation InsertionLoc = ImplementationContainer->getLocEnd();
+
+  Replacements.push_back(RefactoringReplacement(
+      SourceRange(InsertionLoc, InsertionLoc), std::move(OS.str())));
+
+  return std::move(Replacements);
+}
diff --git a/lib/Tooling/Refactor/IndexerQueries.cpp b/lib/Tooling/Refactor/IndexerQueries.cpp
new file mode 100644
index 0000000..f2392e4
--- /dev/null
+++ b/lib/Tooling/Refactor/IndexerQueries.cpp
@@ -0,0 +1,172 @@
+//===--- IndexerQueries.cpp - Indexer queries -----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Core/RefactoringDiagnostic.h"
+#include "clang/Tooling/Refactor/IndexerQuery.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/YAMLTraits.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace clang::tooling::indexer;
+using namespace clang::tooling::indexer::detail;
+using namespace llvm::yaml;
+
+const char *ASTProducerQuery::BaseUIDString = "ast.producer.query";
+const char *DeclarationsQuery::BaseUIDString = "decl.query";
+const char *ASTUnitForImplementationOfDeclarationQuery::NameUIDString =
+    "file.for.impl.of.decl";
+
+const char *DeclPredicateNodePredicate::NameUIDString = "decl.predicate";
+const char *DeclPredicateNotPredicate::NameUIDString = "not.decl.predicate";
+
+std::unique_ptr<DeclPredicateNode>
+DeclPredicateNode::create(const DeclPredicate &Predicate) {
+  return llvm::make_unique<DeclPredicateNodePredicate>(Predicate);
+}
+
+std::unique_ptr<DeclPredicateNode>
+DeclPredicateNode::create(const BoolDeclPredicate &Predicate) {
+  if (Predicate.IsInverted)
+    return llvm::make_unique<DeclPredicateNotPredicate>(
+        create(Predicate.Predicate));
+  return create(Predicate.Predicate);
+}
+
+std::unique_ptr<ASTUnitForImplementationOfDeclarationQuery>
+clang::tooling::indexer::fileThatShouldContainImplementationOf(const Decl *D) {
+  return llvm::make_unique<ASTUnitForImplementationOfDeclarationQuery>(D);
+}
+
+bool ASTUnitForImplementationOfDeclarationQuery::verify(ASTContext &Context) {
+  if (!D) {
+    assert(false && "Query should be verified before persisting");
+    return false;
+  }
+  // Check if we've got the filename.
+  if (!Result.Filename.empty())
+    return false;
+  Context.getDiagnostics().Report(
+      D->getLocation(), diag::err_ref_continuation_missing_implementation)
+      << isa<ObjCContainerDecl>(D) << cast<NamedDecl>(D);
+  return true;
+}
+
+bool DeclarationsQuery::verify(ASTContext &Context) {
+  if (Input.empty()) {
+    assert(false && "Query should be verified before persisting");
+    return false;
+  }
+  if (!Output.empty()) {
+    // At least one output declaration must be valid.
+    for (const auto &Ref : Output) {
+      if (!Ref.Decl.USR.empty())
+        return false;
+    }
+  }
+  // FIXME: This is too specific, the new refactoring engine at llvm.org should
+  // generalize this.
+  Context.getDiagnostics().Report(
+      Input[0]->getLocation(),
+      diag::err_implement_declared_methods_all_implemented);
+  return true;
+}
+
+namespace {
+
+struct QueryPredicateNode {
+  std::string Name;
+  std::vector<int> IntegerValues;
+};
+
+struct QueryYAMLNode {
+  std::string Name;
+  std::vector<QueryPredicateNode> PredicateResults;
+  std::string FilenameResult;
+};
+
+} // end anonymous namespace
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(QueryPredicateNode)
+LLVM_YAML_IS_SEQUENCE_VECTOR(QueryYAMLNode)
+
+namespace llvm {
+namespace yaml {
+
+template <> struct MappingTraits<QueryPredicateNode> {
+  static void mapping(IO &Yaml, QueryPredicateNode &Predicate) {
+    Yaml.mapRequired("name", Predicate.Name);
+    Yaml.mapRequired("intValues", Predicate.IntegerValues);
+  }
+};
+
+template <> struct MappingTraits<QueryYAMLNode> {
+  static void mapping(IO &Yaml, QueryYAMLNode &Query) {
+    Yaml.mapRequired("name", Query.Name);
+    Yaml.mapOptional("predicateResults", Query.PredicateResults);
+    Yaml.mapOptional("filenameResult", Query.FilenameResult);
+    // FIXME: Report an error if no results are provided at all.
+  }
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+llvm::Error
+IndexerQuery::loadResultsFromYAML(StringRef Source,
+                                  ArrayRef<IndexerQuery *> Queries) {
+  std::vector<QueryYAMLNode> QueryResults;
+  Input YamlIn(Source);
+  YamlIn >> QueryResults;
+  if (YamlIn.error())
+    return llvm::make_error<llvm::StringError>("Failed to parse query results",
+                                               YamlIn.error());
+  if (QueryResults.size() != Queries.size())
+    return llvm::make_error<llvm::StringError>("Mismatch in query results size",
+                                               llvm::errc::invalid_argument);
+  for (const auto &QueryTuple : llvm::zip(Queries, QueryResults)) {
+    IndexerQuery *Query = std::get<0>(QueryTuple);
+    const QueryYAMLNode &Result = std::get<1>(QueryTuple);
+    if ((Query->NameUID && Query->NameUID != Result.Name) &&
+        (Query->BaseUID && Query->BaseUID != Result.Name))
+      continue;
+    if (auto *DQ = dyn_cast<DeclarationsQuery>(Query)) {
+      const DeclPredicateNode &Predicate = DQ->getPredicateNode();
+      DeclPredicate ActualPredicate("");
+      bool IsNot = false;
+      if (const auto *Not = dyn_cast<DeclPredicateNotPredicate>(&Predicate)) {
+        ActualPredicate =
+            cast<DeclPredicateNodePredicate>(Not->getChild()).getPredicate();
+        IsNot = true;
+      } else
+        ActualPredicate =
+            cast<DeclPredicateNodePredicate>(Predicate).getPredicate();
+      for (const auto &PredicateResult : Result.PredicateResults) {
+        if (PredicateResult.Name != ActualPredicate.Name)
+          continue;
+        std::vector<Indexed<PersistentDeclRef<Decl>>> Output;
+        for (const auto &ResultTuple :
+             zip(DQ->getInputs(), PredicateResult.IntegerValues)) {
+          const Decl *D = std::get<0>(ResultTuple);
+          int Result = std::get<1>(ResultTuple);
+          bool Value = (IsNot ? !Result : !!Result);
+          Output.push_back(Indexed<PersistentDeclRef<Decl>>(
+              PersistentDeclRef<Decl>::create(Value ? D : nullptr),
+              Value ? QueryBoolResult::Yes : QueryBoolResult::No));
+        }
+        DQ->setOutput(std::move(Output));
+        break;
+      }
+    } else if (auto *AQ =
+                   dyn_cast<ASTUnitForImplementationOfDeclarationQuery>(Query))
+      AQ->setResult(Result.FilenameResult);
+  }
+  return llvm::Error::success();
+}
diff --git a/lib/Tooling/Refactor/LocalizeObjCStringLiteral.cpp b/lib/Tooling/Refactor/LocalizeObjCStringLiteral.cpp
new file mode 100644
index 0000000..08cf41d
--- /dev/null
+++ b/lib/Tooling/Refactor/LocalizeObjCStringLiteral.cpp
@@ -0,0 +1,83 @@
+//===--- LocalizeObjCString.cpp -  ----------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements the "Wrap in NSLocalizedString" refactoring operation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RefactoringOperations.h"
+#include "SourceLocationUtilities.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Expr.h"
+
+using namespace clang;
+using namespace clang::tooling;
+
+namespace {
+
+class LocalizeObjCStringLiteralOperation : public RefactoringOperation {
+public:
+  LocalizeObjCStringLiteralOperation(const ObjCStringLiteral *E) : E(E) {}
+
+  const Stmt *getTransformedStmt() const override { return E; }
+
+  llvm::Expected<RefactoringResult> perform(ASTContext &Context, const Preprocessor &ThePreprocessor,
+          const RefactoringOptionSet &Options,
+          unsigned SelectedCandidateIndex) override;
+
+  const ObjCStringLiteral *E;
+};
+
+} // end anonymous namespace
+
+RefactoringOperationResult
+clang::tooling::initiateLocalizeObjCStringLiteralOperation(
+    ASTSlice &Slice, ASTContext &Context, SourceLocation Location,
+    SourceRange SelectionRange, bool CreateOperation) {
+  const ObjCStringLiteral *E;
+  if (SelectionRange.isValid()) {
+    auto SelectedSet = Slice.getSelectedStmtSet();
+    if (!SelectedSet)
+      return None;
+    E = dyn_cast_or_null<ObjCStringLiteral>(
+        SelectedSet->containsSelectionRange);
+  } else
+    E = cast_or_null<ObjCStringLiteral>(
+        Slice.nearestStmt(Stmt::ObjCStringLiteralClass));
+  if (!E)
+    return None;
+
+  RefactoringOperationResult Result;
+  Result.Initiated = true;
+  if (!CreateOperation)
+    return Result;
+  auto Operation = llvm::make_unique<LocalizeObjCStringLiteralOperation>(E);
+  Result.RefactoringOp = std::move(Operation);
+  return Result;
+}
+
+llvm::Expected<RefactoringResult>
+LocalizeObjCStringLiteralOperation::perform(ASTContext &Context,
+                                            const Preprocessor &ThePreprocessor,
+                                            const RefactoringOptionSet &Options,
+                                            unsigned SelectedCandidateIndex) {
+  std::vector<RefactoringReplacement> Replacements;
+  // TODO: New API: Replace by something like Node.wrap("NSLocalizedString(", ",
+  // @""")
+  SourceLocation LocStart =
+      Context.getSourceManager().getSpellingLoc(E->getLocStart());
+  Replacements.emplace_back(SourceRange(LocStart, LocStart),
+                            StringRef("NSLocalizedString("));
+  SourceLocation LocEnd = getPreciseTokenLocEnd(
+      Context.getSourceManager().getSpellingLoc(E->getLocEnd()),
+      Context.getSourceManager(), Context.getLangOpts());
+  Replacements.emplace_back(SourceRange(LocEnd, LocEnd), StringRef(", @\"\")"));
+  return std::move(Replacements);
+}
diff --git a/lib/Tooling/Refactor/RefactoringActionFinder.cpp b/lib/Tooling/Refactor/RefactoringActionFinder.cpp
new file mode 100644
index 0000000..2fd7cd5
--- /dev/null
+++ b/lib/Tooling/Refactor/RefactoringActionFinder.cpp
@@ -0,0 +1,57 @@
+//===--- RefactoringActionFinder.cpp - Clang refactoring library ----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Implements methods that find the refactoring actions that can be
+/// performed at specific locations / source ranges in a translation unit.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/RefactoringActionFinder.h"
+#include "clang/Tooling/Refactor/RefactoringOperation.h"
+#include "clang/Tooling/Refactor/USRFinder.h"
+
+namespace clang {
+namespace tooling {
+
+RefactoringActionSet findActionSetAt(SourceLocation Location,
+                                     SourceRange SelectionRange,
+                                     ASTContext &Context) {
+  RefactoringActionSet Result;
+  if (const auto *ND = rename::getNamedDeclAt(Context, Location))
+    Result.Actions.push_back(isLocalSymbol(ND, Context.getLangOpts())
+                                 ? RefactoringActionType::Rename_Local
+                                 : RefactoringActionType::Rename);
+
+  // FIXME: We can avoid checking if some actions can be initiated when they're
+  // not allowed in the current language mode.
+  RefactoringActionType Actions[] = {
+#define REFACTORING_OPERATION_ACTION(Name, Spelling, Command)                  \
+  RefactoringActionType::Name,
+#include "clang/Tooling/Refactor/RefactoringActions.def"
+  };
+
+  for (auto Action : Actions) {
+    auto Op = initiateRefactoringOperationAt(Location, SelectionRange, Context,
+                                             Action,
+                                             /*CreateOperation=*/true);
+    if (Op.Initiated) {
+      Result.Actions.push_back(Action);
+      if (Op.RefactoringOp) {
+        for (const auto &SubAction : Op.RefactoringOp->getAvailableSubActions())
+          Result.Actions.push_back(SubAction);
+      }
+    }
+  }
+
+  return Result;
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/RefactoringActions.cpp b/lib/Tooling/Refactor/RefactoringActions.cpp
new file mode 100644
index 0000000..4b2b735
--- /dev/null
+++ b/lib/Tooling/Refactor/RefactoringActions.cpp
@@ -0,0 +1,30 @@
+//===--- RefactoringActions.cpp - Clang refactoring library ---------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Contains a list of all the supported refactoring actions.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/RefactoringActions.h"
+
+namespace clang {
+namespace tooling {
+
+StringRef getRefactoringActionTypeName(RefactoringActionType Action) {
+  switch (Action) {
+#define REFACTORING_ACTION(Name, Spelling)                                     \
+  case RefactoringActionType::Name:                                            \
+    return Spelling;
+#include "clang/Tooling/Refactor/RefactoringActions.def"
+  }
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/RefactoringContinuations.h b/lib/Tooling/Refactor/RefactoringContinuations.h
new file mode 100644
index 0000000..ec2ee1b
--- /dev/null
+++ b/lib/Tooling/Refactor/RefactoringContinuations.h
@@ -0,0 +1,398 @@
+//===--- RefactoringContinuations.h - Defines refactoring continuations ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_TOOLING_REFACTOR_REFACTORING_CONTINUATIONS_H
+#define LLVM_CLANG_LIB_TOOLING_REFACTOR_REFACTORING_CONTINUATIONS_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Tooling/Refactor/IndexerQuery.h"
+#include "clang/Tooling/Refactor/RefactoringOperation.h"
+#include "llvm/ADT/StringMap.h"
+#include <tuple>
+
+namespace clang {
+namespace tooling {
+
+namespace detail {
+
+struct ValidBase {};
+
+/// The ContinuationPassType determine which type is passed into the refactoring
+/// continuation.
+template <typename T> struct ContinuationPassType { using Type = T; };
+
+template <typename T> struct ContinuationPassType<std::vector<T>> {
+  using Type = ArrayRef<T>;
+};
+
+/// Refactoring operations can pass state to the continuations. Valid state
+/// values should have a corresponding \c StateTraits specialization.
+template <typename T> struct StateTraits {
+  /// Specializations should define the following types:
+  ///
+  /// StoredResultType: The TU-specific type which is then passed into the
+  /// continuation function. The continuation receives the result whose type is
+  /// \c ContinuationPassType<StoredResultType>::Type.
+  ///
+  /// PersistentType: The TU-independent type that's persisted even after the
+  /// TU in which the continuation was created is disposed.
+};
+
+template <typename T>
+struct StateTraits<const T *>
+    : std::enable_if<std::is_base_of<Decl, T>::value, ValidBase>::type {
+  using StoredResultType = const T *;
+  using PersistentType = PersistentDeclRef<T>;
+};
+
+template <typename T>
+struct StateTraits<ArrayRef<const T *>>
+    : std::enable_if<std::is_base_of<Decl, T>::value, ValidBase>::type {
+  using StoredResultType = std::vector<const T *>;
+  using PersistentType = std::vector<PersistentDeclRef<T>>;
+};
+
+template <typename T>
+struct StateTraits<std::unique_ptr<indexer::ManyToManyDeclarationsQuery<T>>>
+    : std::enable_if<std::is_base_of<Decl, T>::value, ValidBase>::type {
+  using StoredResultType = std::vector<indexer::Indexed<const T *>>;
+  using PersistentType = std::vector<indexer::Indexed<PersistentDeclRef<T>>>;
+};
+
+template <> struct StateTraits<std::vector<std::string>> {
+  using StoredResultType = std::vector<std::string>;
+  using PersistentType = std::vector<std::string>;
+};
+
+/// Conversion functions convert the TU-specific state to a TU independent
+/// state and vice-versa.
+template <typename T>
+PersistentDeclRef<T> convertToPersistentRepresentation(
+    const T *Declaration,
+    typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+        nullptr) {
+  return PersistentDeclRef<T>::create(Declaration);
+}
+
+template <typename T>
+std::vector<PersistentDeclRef<T>> convertToPersistentRepresentation(
+    ArrayRef<const T *> Declarations,
+    typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+        nullptr) {
+  std::vector<PersistentDeclRef<T>> Result;
+  Result.reserve(Declarations.size());
+  for (const T *D : Declarations)
+    Result.push_back(PersistentDeclRef<T>::create(D));
+  return Result;
+}
+
+template <typename T>
+std::vector<indexer::Indexed<PersistentDeclRef<T>>>
+convertToPersistentRepresentation(
+    std::unique_ptr<indexer::ManyToManyDeclarationsQuery<T>> &Query,
+    typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+        nullptr) {
+  Query->invalidateTUSpecificState();
+  return Query->getOutput();
+}
+
+inline std::vector<std::string>
+convertToPersistentRepresentation(const std::vector<std::string> &Values) {
+  return Values;
+}
+
+/// Converts the TU-independent state to the TU-specific state.
+class PersistentToASTSpecificStateConverter {
+  ASTContext &Context;
+  llvm::StringMap<const Decl *> ConvertedDeclRefs;
+
+  const Decl *lookupDecl(StringRef USR);
+
+public:
+  // FIXME: We can hide the addConvertible/convert interface so that
+  // the continuation will just invoke one conversion function for the entire
+  // tuple.
+  PersistentToASTSpecificStateConverter(ASTContext &Context)
+      : Context(Context) {}
+
+  template <typename T>
+  bool addConvertible(
+      const PersistentDeclRef<T> &Ref,
+      typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+          nullptr) {
+    if (!Ref.USR.empty())
+      ConvertedDeclRefs[Ref.USR] = nullptr;
+    return true;
+  }
+
+  template <typename T>
+  const T *
+  convert(const PersistentDeclRef<T> &Ref,
+          typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+              nullptr) {
+    return dyn_cast_or_null<T>(lookupDecl(Ref.USR));
+  }
+
+  template <typename T>
+  bool addConvertible(
+      const std::vector<PersistentDeclRef<T>> &Refs,
+      typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+          nullptr) {
+    for (const auto &Ref : Refs) {
+      if (!Ref.USR.empty())
+        ConvertedDeclRefs[Ref.USR] = nullptr;
+    }
+    return true;
+  }
+
+  template <typename T>
+  std::vector<const T *>
+  convert(const std::vector<PersistentDeclRef<T>> &Refs,
+          typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+              nullptr) {
+    std::vector<const T *> Results;
+    Results.reserve(Refs.size());
+    // Allow nulls in the produced array, the continuation will have to deal
+    // with them by itself.
+    for (const auto &Ref : Refs)
+      Results.push_back(dyn_cast_or_null<T>(lookupDecl(Ref.USR)));
+    return Results;
+  }
+
+  template <typename T>
+  bool addConvertible(
+      const std::vector<indexer::Indexed<PersistentDeclRef<T>>> &Refs,
+      typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+          nullptr) {
+    for (const auto &Ref : Refs) {
+      if (!Ref.Decl.USR.empty())
+        ConvertedDeclRefs[Ref.Decl.USR] = nullptr;
+    }
+    return true;
+  }
+
+  template <typename T>
+  std::vector<indexer::Indexed<const T *>>
+  convert(const std::vector<indexer::Indexed<PersistentDeclRef<T>>> &Refs,
+          typename std::enable_if<std::is_base_of<Decl, T>::value>::type * =
+              nullptr) {
+    std::vector<indexer::Indexed<const T *>> Results;
+    Results.reserve(Refs.size());
+    // Allow nulls in the produced array, the continuation will have to deal
+    // with them by itself.
+    for (const auto &Ref : Refs)
+      Results.push_back(indexer::Indexed<const T *>(
+          dyn_cast_or_null<T>(lookupDecl(Ref.Decl.USR)), Ref.IsNotDefined));
+    return Results;
+  }
+
+  bool addConvertible(const PersistentFileID &) {
+    // Do nothing since FileIDs are converted one-by-one.
+    return true;
+  }
+
+  FileID convert(const PersistentFileID &Ref);
+
+  bool addConvertible(const std::vector<std::string> &) { return true; }
+
+  std::vector<std::string> convert(const std::vector<std::string> &Values) {
+    return Values;
+  }
+
+  /// Converts the added persistent state into TU-specific state using one
+  /// efficient operation.
+  void runCoalescedConversions();
+};
+
+template <typename T, typename ASTQueryType, typename... QueryOrState>
+struct ContinuationFunction {
+  using Type = llvm::Expected<RefactoringResult> (*)(
+      ASTContext &, const T &,
+      typename ContinuationPassType<
+          typename StateTraits<QueryOrState>::StoredResultType>::Type...);
+
+  template <size_t... Is>
+  static llvm::Expected<RefactoringResult> dispatch(
+      Type Fn, detail::PersistentToASTSpecificStateConverter &Converter,
+      ASTContext &Context, const ASTQueryType &Query,
+      const std::tuple<typename StateTraits<QueryOrState>::StoredResultType...>
+          &Arguments,
+      llvm::index_sequence<Is...>) {
+    auto ASTQueryResult = Converter.convert(Query.getResult());
+    return Fn(Context, ASTQueryResult, std::get<Is>(Arguments)...);
+  }
+};
+
+template <typename ASTQueryType, typename... QueryOrState>
+struct ContinuationFunction<void, ASTQueryType, QueryOrState...> {
+  using Type = llvm::Expected<RefactoringResult> (*)(
+      ASTContext &,
+      typename ContinuationPassType<
+          typename StateTraits<QueryOrState>::StoredResultType>::Type...);
+
+  template <size_t... Is>
+  static llvm::Expected<RefactoringResult> dispatch(
+      Type Fn, detail::PersistentToASTSpecificStateConverter &,
+      ASTContext &Context, const ASTQueryType &,
+      const std::tuple<typename StateTraits<QueryOrState>::StoredResultType...>
+          &Arguments,
+      llvm::index_sequence<Is...>) {
+    return Fn(Context, std::get<Is>(Arguments)...);
+  }
+};
+
+/// The refactoring contination contains a set of structures that implement
+/// the refactoring operation continuation mechanism.
+template <typename ASTQueryType, typename... QueryOrState>
+class SpecificRefactoringContinuation final : public RefactoringContinuation {
+public:
+  static_assert(std::is_base_of<indexer::ASTProducerQuery, ASTQueryType>::value,
+                "Invalid AST Query");
+  // TODO: Validate the QueryOrState types.
+
+  /// The consumer function is the actual continuation. It receives the state
+  /// that was passed-in in the request or the results of the indexing queries
+  /// that were passed-in in the request.
+  using ConsumerFn =
+      typename ContinuationFunction<typename ASTQueryType::ResultTy,
+                                    ASTQueryType, QueryOrState...>::Type;
+
+private:
+  ConsumerFn Consumer;
+  std::unique_ptr<ASTQueryType> ASTQuery;
+  /// Inputs store state that's dependent on the original TU.
+  llvm::Optional<std::tuple<QueryOrState...>> Inputs;
+  /// State contains TU-independent values.
+  llvm::Optional<
+      std::tuple<typename StateTraits<QueryOrState>::PersistentType...>>
+      State;
+
+  /// Converts a tuple that contains the TU dependent state to a tuple with
+  /// TU independent state.
+  template <size_t... Is>
+  std::tuple<typename StateTraits<QueryOrState>::PersistentType...>
+  convertToPersistentImpl(llvm::index_sequence<Is...>) {
+    assert(Inputs && "TU-dependent state is already converted");
+    return std::make_tuple(
+        detail::convertToPersistentRepresentation(std::get<Is>(*Inputs))...);
+  }
+
+  template <typename T>
+  bool gatherQueries(
+      std::vector<indexer::IndexerQuery *> &Queries,
+      const std::unique_ptr<T> &Query,
+      typename std::enable_if<
+          std::is_base_of<indexer::IndexerQuery, T>::value>::type * = nullptr) {
+    Queries.push_back(Query.get());
+    return true;
+  }
+
+  template <typename T>
+  bool gatherQueries(std::vector<indexer::IndexerQuery *> &, const T &) {
+    // This input element is not a query.
+    return true;
+  }
+
+  template <size_t... Is>
+  std::vector<indexer::IndexerQuery *>
+  gatherQueries(llvm::index_sequence<Is...>) {
+    assert(Inputs && "TU-dependent state is already converted");
+    std::vector<indexer::IndexerQuery *> Queries;
+    std::make_tuple(gatherQueries(Queries, std::get<Is>(*Inputs))...);
+    return Queries;
+  }
+
+  /// Calls the consumer function with the given \p Context and the state
+  /// whose values are converted from the TU-independent to TU-specific values.
+  template <size_t... Is>
+  llvm::Expected<RefactoringResult> dispatch(ASTContext &Context,
+                                             llvm::index_sequence<Is...> Seq) {
+    assert(State && "TU-independent state is not yet produced");
+    detail::PersistentToASTSpecificStateConverter Converter(Context);
+    (void)std::make_tuple(Converter.addConvertible(std::get<Is>(*State))...);
+    Converter.runCoalescedConversions();
+    auto Results = std::make_tuple(Converter.convert(std::get<Is>(*State))...);
+    // TODO: Check for errors?
+    return detail::ContinuationFunction<
+        typename ASTQueryType::ResultTy, ASTQueryType,
+        QueryOrState...>::dispatch(Consumer, Converter, Context, *ASTQuery,
+                                   Results, Seq);
+  }
+
+public:
+  SpecificRefactoringContinuation(ConsumerFn Consumer,
+                                  std::unique_ptr<ASTQueryType> ASTQuery,
+                                  QueryOrState... Inputs)
+      : Consumer(Consumer), ASTQuery(std::move(ASTQuery)),
+        Inputs(std::make_tuple(std::move(Inputs)...)) {}
+
+  SpecificRefactoringContinuation(SpecificRefactoringContinuation &&) = default;
+  SpecificRefactoringContinuation &
+  operator=(SpecificRefactoringContinuation &&) = default;
+
+  indexer::ASTProducerQuery *getASTUnitIndexerQuery() override {
+    return ASTQuery.get();
+  }
+
+  std::vector<indexer::IndexerQuery *> getAdditionalIndexerQueries() override {
+    return gatherQueries(llvm::index_sequence_for<QueryOrState...>());
+  }
+
+  /// Query results are fetched. State is converted to a persistent
+  /// representation.
+  void persistTUSpecificState() override {
+    ASTQuery->invalidateTUSpecificState();
+    State =
+        convertToPersistentImpl(llvm::index_sequence_for<QueryOrState...>());
+    Inputs = None;
+  }
+
+  /// The state is converted to the AST representation in the given ASTContext
+  /// and the continuation is dispatched.
+  llvm::Expected<RefactoringResult>
+  runInExternalASTUnit(ASTContext &Context) override {
+    return dispatch(Context, llvm::index_sequence_for<QueryOrState...>());
+  }
+};
+
+} // end namespace detail
+
+/// Returns a refactoring continuation that will run within the context of a
+/// single external AST unit.
+///
+/// The indexer determines which AST unit should receive the continuation by
+/// evaluation the AST query operation \p ASTQuery.
+///
+/// \param ASTQuery The query that will determine which AST unit should the
+/// continuation run in.
+///
+/// \param Consumer The continuation function that will be called once the
+/// external AST unit is loaded.
+///
+/// \param Inputs Each individiual input element can contain either some
+/// state value that will be passed into the \p Consumer function or an
+/// indexer query whose results will be passed into the \p Consumer function.
+template <typename ASTQueryType, typename... QueryOrState>
+typename std::enable_if<
+    std::is_base_of<indexer::ASTProducerQuery, ASTQueryType>::value,
+    std::unique_ptr<RefactoringContinuation>>::type
+continueInExternalASTUnit(
+    std::unique_ptr<ASTQueryType> ASTQuery,
+    typename detail::SpecificRefactoringContinuation<
+        ASTQueryType, QueryOrState...>::ConsumerFn Consumer,
+    QueryOrState... Inputs) {
+  return llvm::make_unique<
+      detail::SpecificRefactoringContinuation<ASTQueryType, QueryOrState...>>(
+      Consumer, std::move(ASTQuery), std::move(Inputs)...);
+}
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_TOOLING_REFACTOR_REFACTORING_CONTINUATIONS_H
diff --git a/lib/Tooling/Refactor/RefactoringOperation.cpp b/lib/Tooling/Refactor/RefactoringOperation.cpp
new file mode 100644
index 0000000..a9f431f
--- /dev/null
+++ b/lib/Tooling/Refactor/RefactoringOperation.cpp
@@ -0,0 +1,93 @@
+//===--- RefactoringOperation.cpp - Defines a refactoring operation -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/RefactoringOperation.h"
+#include "ASTSlice.h"
+#include "RefactoringOperations.h"
+#include "SourceLocationUtilities.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/Tooling/Refactor/SymbolOperation.h"
+#include "clang/Tooling/Refactor/USRFinder.h"
+#include "llvm/Support/Errc.h"
+
+using namespace clang;
+using namespace clang::tooling;
+
+char RefactoringOperationError::ID;
+
+void RefactoringOperationError::log(raw_ostream &OS) const {
+  OS << "Refactoring operation failed: " << FailureReason;
+}
+
+std::error_code RefactoringOperationError::convertToErrorCode() const {
+  return make_error_code(llvm::errc::operation_not_permitted);
+}
+
+RefactoringOperationResult clang::tooling::initiateRefactoringOperationAt(
+    SourceLocation Location, SourceRange SelectionRange, ASTContext &Context,
+    RefactoringActionType ActionType, bool CreateOperation) {
+  if (Location.isInvalid())
+    return None;
+  if (ActionType == RefactoringActionType::Rename ||
+      ActionType == RefactoringActionType::Rename_Local) {
+    const NamedDecl *FoundDecl = rename::getNamedDeclAt(Context, Location);
+    if (!FoundDecl)
+      return None;
+    RefactoringOperationResult Result;
+    Result.Initiated = true;
+    if (CreateOperation)
+      Result.SymbolOp = llvm::make_unique<SymbolOperation>(FoundDecl, Context);
+    return Result;
+  }
+  SourceManager &SM = Context.getSourceManager();
+  if (Location.isMacroID())
+    Location = SM.getSpellingLoc(Location);
+  assert(Location.isFileID() && "Invalid location");
+
+  // TODO: Don't perform duplicate work when initiateRefactoringOperationAt is
+  // called from findRefactoringActionsAt.
+  if (SelectionRange.isValid()) {
+    if (SelectionRange.getBegin().isMacroID() ||
+        SelectionRange.getEnd().isMacroID())
+      SelectionRange = SourceRange(SM.getSpellingLoc(SelectionRange.getBegin()),
+                                   SM.getSpellingLoc(SelectionRange.getEnd()));
+    SelectionRange = trimSelectionRange(
+        SelectionRange, Context.getSourceManager(), Context.getLangOpts());
+  }
+  ASTSlice Slice(Location, SelectionRange, Context);
+
+  switch (ActionType) {
+#define REFACTORING_OPERATION_ACTION(Name, Spelling, Command)                  \
+  case RefactoringActionType::Name:                                            \
+    return initiate##Name##Operation(Slice, Context, Location, SelectionRange, \
+                                     CreateOperation);
+#define REFACTORING_OPERATION_SUB_ACTION(Name, Parent, Spelling, Command)      \
+  case RefactoringActionType::Parent##_##Name:                                 \
+    return initiate##Parent##Name##Operation(Slice, Context, Location,         \
+                                             SelectionRange, CreateOperation);
+#include "clang/Tooling/Refactor/RefactoringActions.def"
+  default:
+    break;
+  }
+  return RefactoringOperationResult();
+}
+
+RefactoringOperationResult clang::tooling::initiateRefactoringOperationOnDecl(
+    StringRef DeclUSR, ASTContext &Context, RefactoringActionType ActionType) {
+  if (ActionType != RefactoringActionType::Rename)
+    return None;
+  const NamedDecl *FoundDecl = rename::getNamedDeclWithUSR(Context, DeclUSR);
+  if (!FoundDecl)
+    return None;
+  RefactoringOperationResult Result;
+  Result.Initiated = true;
+  Result.SymbolOp = llvm::make_unique<SymbolOperation>(FoundDecl, Context);
+  return Result;
+}
diff --git a/lib/Tooling/Refactor/RefactoringOperations.h b/lib/Tooling/Refactor/RefactoringOperations.h
new file mode 100644
index 0000000..e02a3cf
--- /dev/null
+++ b/lib/Tooling/Refactor/RefactoringOperations.h
@@ -0,0 +1,37 @@
+//===--- RefactoringOperations.h - The supported refactoring operations ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_TOOLING_REFACTOR_REFACTORINGOPERATIONS_H
+#define LLVM_CLANG_LIB_TOOLING_REFACTOR_REFACTORINGOPERATIONS_H
+
+#include "ASTSlice.h"
+#include "clang/Tooling/Refactor/RefactoringOperation.h"
+
+namespace clang {
+
+class Expr;
+class IfStmt;
+class VarDecl;
+
+namespace tooling {
+
+#define REFACTORING_OPERATION_ACTION(Name, Spelling, Command)                  \
+  RefactoringOperationResult initiate##Name##Operation(                        \
+      ASTSlice &Slice, ASTContext &Context, SourceLocation Location,           \
+      SourceRange SelectionRange, bool CreateOperation = true);
+#define REFACTORING_OPERATION_SUB_ACTION(Name, Parent, Spelling, Command)      \
+  RefactoringOperationResult initiate##Parent##Name##Operation(                \
+      ASTSlice &Slice, ASTContext &Context, SourceLocation Location,           \
+      SourceRange SelectionRange, bool CreateOperation = true);
+#include "clang/Tooling/Refactor/RefactoringActions.def"
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_TOOLING_REFACTOR_REFACTORINGOPERATIONS_H
diff --git a/lib/Tooling/Refactor/RefactoringOptions.cpp b/lib/Tooling/Refactor/RefactoringOptions.cpp
new file mode 100644
index 0000000..fd2d8d1
--- /dev/null
+++ b/lib/Tooling/Refactor/RefactoringOptions.cpp
@@ -0,0 +1,65 @@
+//===--- RefactoringOptions.cpp - A set of all the refactoring options ----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/RefactoringOptions.h"
+#include "llvm/Support/YAMLTraits.h"
+
+using namespace clang;
+using namespace clang::tooling;
+using namespace clang::tooling::option;
+using namespace llvm::yaml;
+
+void RefactoringOptionSet::print(llvm::raw_ostream &OS) const {
+  Output YamlOut(OS);
+  if (YamlOut.preflightDocument(0)) {
+    YamlOut.beginFlowMapping();
+    for (const auto &Option : Options)
+      Option.getValue()->serialize(YamlOut);
+    YamlOut.endFlowMapping();
+    YamlOut.postflightDocument();
+  }
+}
+
+template <> struct CustomMappingTraits<RefactoringOptionSet> {
+  static void inputOne(IO &YamlIn, StringRef Key,
+                       RefactoringOptionSet &Result) {
+#define HANDLE(Type)                                                           \
+  if (Key == Type::Name) {                                                     \
+    Type Value;                                                                \
+    Value.serialize(YamlIn);                                                   \
+    Result.add(Value);                                                         \
+    return;                                                                    \
+  }
+    HANDLE(AvoidTextualMatches)
+#undef HANDLE
+    YamlIn.setError(Twine("Unknown refactoring option ") + Key);
+  }
+  static void output(IO &, RefactoringOptionSet &) {
+    llvm_unreachable("Output is done without mapping traits");
+  }
+};
+
+llvm::Expected<RefactoringOptionSet>
+RefactoringOptionSet::parse(StringRef Source) {
+  Input YamlIn(Source);
+  // FIXME: Don't dump errors to stderr.
+  RefactoringOptionSet Result;
+  YamlIn >> Result;
+  if (YamlIn.error())
+    return llvm::make_error<llvm::StringError>("Failed to parse the option set",
+                                               YamlIn.error());
+  return std::move(Result);
+}
+
+void RefactoringOption::serialize(const SerializationContext &) {}
+
+void clang::tooling::option::detail::BoolOptionBase::serializeImpl(
+    const SerializationContext &Context, const char *Name) {
+  Context.IO.mapRequired(Name, Value);
+}
diff --git a/lib/Tooling/Refactor/RenameIndexedFile.cpp b/lib/Tooling/Refactor/RenameIndexedFile.cpp
new file mode 100644
index 0000000..ef88e1f
--- /dev/null
+++ b/lib/Tooling/Refactor/RenameIndexedFile.cpp
@@ -0,0 +1,624 @@
+//===--- RenameIndexedFile.cpp - ------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/RenameIndexedFile.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Tooling/Refactor/RefactoringOptions.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Path.h"
+
+using namespace clang;
+
+namespace clang {
+namespace tooling {
+namespace rename {
+
+IndexedFileOccurrenceProducer::IndexedFileOccurrenceProducer(
+    ArrayRef<IndexedSymbol> Symbols, IndexedFileOccurrenceConsumer &Consumer,
+    const RefactoringOptionSet *Options)
+    : Symbols(Symbols), Consumer(Consumer), Options(Options) {
+  IsMultiPiece = false;
+  for (const auto &Symbol : Symbols) {
+    if (Symbol.Name.size() > 1) {
+      IsMultiPiece = true;
+      break;
+    }
+  }
+  if (IsMultiPiece) {
+    for (const auto &Symbol : Symbols) {
+      (void)Symbol;
+      assert(Symbol.Name.size() > 1 &&
+             "Mixed multi-piece and single piece symbols "
+             "are unsupported");
+    }
+  }
+}
+
+namespace {
+
+enum class MatchKind {
+  SourceMatch,
+  SourcePropSetterMatch,
+  MacroExpansion,
+  None
+};
+
+} // end anonymous namespace
+
+static bool isSetterNameEqualToPropName(StringRef SetterName,
+                                        StringRef PropertyName) {
+  assert(SetterName.startswith("set") && "invalid setter name");
+  SetterName = SetterName.drop_front(3);
+  return SetterName[0] == toUppercase(PropertyName[0]) &&
+         SetterName.drop_front() == PropertyName.drop_front();
+}
+
+static MatchKind checkOccurrence(const IndexedOccurrence &Occurrence,
+                                 const IndexedSymbol &Symbol,
+                                 const SourceManager &SM,
+                                 const LangOptions &LangOpts,
+                                 SourceRange &SymbolRange,
+                                 bool AllowObjCSetterProp = false) {
+  if (!Occurrence.Line || !Occurrence.Column)
+    return MatchKind::None; // Ignore any invalid indexed locations.
+
+  // Ensure that the first string in the name is present at the given
+  // location.
+  SourceLocation BeginLoc = SM.translateLineCol(
+      SM.getMainFileID(), Occurrence.Line, Occurrence.Column);
+  if (BeginLoc.isInvalid())
+    return MatchKind::None;
+  StringRef SymbolNameStart = Symbol.Name[0];
+  // Extract the token at the location.
+  auto DecomposedLoc = SM.getDecomposedLoc(BeginLoc);
+  const llvm::MemoryBuffer *File = SM.getBuffer(DecomposedLoc.first);
+  Lexer RawLex(
+      BeginLoc, LangOpts, File->getBufferStart() + DecomposedLoc.second,
+      File->getBufferStart() + DecomposedLoc.second, File->getBufferEnd());
+  Token Tok;
+  RawLex.LexFromRawLexer(Tok);
+  if (Tok.isNot(tok::raw_identifier) || Tok.getLocation() != BeginLoc) {
+    if (SymbolNameStart.empty() && Tok.is(tok::colon) &&
+        Tok.getLocation() == BeginLoc) {
+      // Must be the location of an empty Objective-C selector piece.
+      SymbolRange = SourceRange(BeginLoc, BeginLoc);
+      return MatchKind::SourceMatch;
+    }
+    // FIXME: Handle empty selector piece in a macro?
+    return MatchKind::None;
+  }
+  SymbolRange = SourceRange(BeginLoc, Tok.getEndLoc());
+  if (Tok.getRawIdentifier() == SymbolNameStart)
+    return MatchKind::SourceMatch;
+  // Match 'prop' when looking for 'setProp'.
+  // FIXME: Verify that the previous token is a '.' to be sure.
+  if (AllowObjCSetterProp &&
+      Occurrence.Kind == IndexedOccurrence::IndexedObjCMessageSend &&
+      SymbolNameStart.startswith("set") &&
+      isSetterNameEqualToPropName(SymbolNameStart, Tok.getRawIdentifier()))
+    return MatchKind::SourcePropSetterMatch;
+  return MatchKind::MacroExpansion;
+}
+
+static void
+findObjCMultiPieceSelectorOccurrences(CompilerInstance &CI,
+                                      ArrayRef<IndexedSymbol> Symbols,
+                                      IndexedFileOccurrenceConsumer &Consumer);
+
+namespace {
+
+struct TextualMatchOccurrence {
+  SourceLocation Location;
+  unsigned SymbolIndex;
+};
+
+/// Finds '@selector' expressions by looking at tokens one-by-one.
+class SelectorParser {
+  enum ParseState {
+    None,
+    At,
+    Selector,
+    ExpectingSelectorPiece,
+    ExpectingColon,
+    ExpectingRParenOrColon,
+    ExpectingRParen,
+    Success
+  };
+  ParseState State = None;
+  const SymbolName &Name;
+
+  ParseState stateForToken(const Token &RawTok);
+
+public:
+  unsigned SymbolIndex;
+  llvm::SmallVector<SourceLocation, 8> SelectorLocations;
+
+  SelectorParser(const SymbolName &Name, unsigned SymbolIndex)
+      : Name(Name), SymbolIndex(SymbolIndex) {}
+
+  /// Returns true if the parses has found a '@selector' expression.
+  bool handleToken(const Token &RawTok);
+};
+
+class InclusionLexer final : public Lexer {
+public:
+  InclusionLexer(SourceLocation FileLoc, const LangOptions &LangOpts,
+                 const char *BufStart, const char *BufEnd)
+      : Lexer(FileLoc, LangOpts, BufStart, BufStart, BufEnd) {}
+
+  void IndirectLex(Token &Result) override { LexFromRawLexer(Result); }
+};
+
+} // end anonymous namespace
+
+SelectorParser::ParseState SelectorParser::stateForToken(const Token &RawTok) {
+  assert(RawTok.isNot(tok::comment) && "unexpected comment token");
+  switch (State) {
+  case None:
+    break;
+  case At:
+    if (RawTok.is(tok::raw_identifier) &&
+        RawTok.getRawIdentifier() == "selector")
+      return Selector;
+    break;
+  case Selector:
+    if (RawTok.isNot(tok::l_paren))
+      break;
+    SelectorLocations.clear();
+    return ExpectingSelectorPiece;
+  case ExpectingSelectorPiece: {
+    assert(SelectorLocations.size() < Name.size() &&
+           "Expecting invalid selector piece");
+    StringRef NamePiece = Name[SelectorLocations.size()];
+    if ((RawTok.isNot(tok::raw_identifier) ||
+         RawTok.getRawIdentifier() != NamePiece) &&
+        !(NamePiece.empty() && RawTok.is(tok::colon))) {
+      break;
+    }
+    SelectorLocations.push_back(RawTok.getLocation());
+    if (SelectorLocations.size() == Name.size()) {
+      // We found the selector that we were looking for, now check for ')'.
+      return NamePiece.empty() ? ExpectingRParen : ExpectingRParenOrColon;
+    }
+    return NamePiece.empty() ? ExpectingSelectorPiece : ExpectingColon;
+  }
+  case ExpectingColon:
+    if (RawTok.is(tok::colon))
+      return ExpectingSelectorPiece;
+    break;
+  case ExpectingRParenOrColon:
+    if (RawTok.is(tok::colon))
+      return ExpectingRParen;
+  // Fallthrough
+  case ExpectingRParen:
+    if (RawTok.is(tok::r_paren)) {
+      // We found the selector that we were looking for.
+      return Success;
+    }
+    break;
+  case Success:
+    llvm_unreachable("should not get here");
+  }
+  // Look for the start of the selector expression.
+  return RawTok.is(tok::at) ? At : None;
+}
+
+bool SelectorParser::handleToken(const Token &RawTok) {
+  if (RawTok.is(tok::coloncolon)) {
+    // Split the '::' into two ':'.
+    Token T(RawTok);
+    T.setKind(tok::colon);
+    T.setLength(1);
+    handleToken(T);
+    T.setLocation(T.getLocation().getLocWithOffset(1));
+    return handleToken(T);
+  }
+  State = stateForToken(RawTok);
+  if (State != Success)
+    return false;
+  State = None;
+  return true;
+}
+
+static void collectTextualMatchesInComment(
+    ArrayRef<IndexedSymbol> Symbols, SourceLocation CommentLoc,
+    StringRef Comment, llvm::SmallVectorImpl<TextualMatchOccurrence> &Result) {
+  for (const auto &Symbol : llvm::enumerate(Symbols)) {
+    const SymbolName &Name = Symbol.value().Name;
+    if (Name.containsEmptyPiece()) // Ignore Objective-C selectors with empty
+                                   // pieces.
+      continue;
+    size_t Offset = 0;
+    while (true) {
+      Offset = Comment.find(Name[0], /*From=*/Offset);
+      if (Offset == StringRef::npos)
+        break;
+      Result.push_back(
+          {CommentLoc.getLocWithOffset(Offset), (unsigned)Symbol.index()});
+      Offset += Name[0].size();
+    }
+  }
+}
+
+/// Lex the comment to figure out if textual matches in a comment are standalone
+/// tokens.
+static void findTextualMatchesInComment(
+    const SourceManager &SM, const LangOptions &LangOpts,
+    ArrayRef<IndexedSymbol> Symbols,
+    ArrayRef<TextualMatchOccurrence> TextualMatches, SourceRange CommentRange,
+    llvm::function_ref<void(SymbolOccurrence::OccurrenceKind,
+                            ArrayRef<SourceLocation> Locations,
+                            unsigned SymbolIndex)>
+        MatchHandler) {
+  std::string Source =
+      Lexer::getSourceText(CharSourceRange::getCharRange(CommentRange), SM,
+                           LangOpts)
+          .str();
+  SymbolOccurrence::OccurrenceKind Kind =
+      RawComment(SM, CommentRange, /*Merged=*/false, /*ParseAllComments=*/false)
+              .isDocumentation()
+          ? SymbolOccurrence::MatchingDocComment
+          : SymbolOccurrence::MatchingComment;
+  // Replace some special characters  with ' ' to avoid comments and literals.
+  std::replace_if(
+      Source.begin(), Source.end(),
+      [](char c) -> bool { return c == '/' || c == '"' || c == '\''; }, ' ');
+  Lexer RawLex(CommentRange.getBegin(), LangOpts, Source.c_str(),
+               Source.c_str(), Source.c_str() + Source.size());
+  Token RawTok;
+  RawLex.LexFromRawLexer(RawTok);
+  while (RawTok.isNot(tok::eof)) {
+    auto It = std::find_if(TextualMatches.begin(), TextualMatches.end(),
+                           [&](const TextualMatchOccurrence &Match) {
+                             return Match.Location == RawTok.getLocation();
+                           });
+    if (It != TextualMatches.end()) {
+      StringRef TokenName =
+          Lexer::getSourceText(CharSourceRange::getCharRange(
+                                   RawTok.getLocation(), RawTok.getEndLoc()),
+                               SM, LangOpts);
+      // Only report matches that are identical to the symbol. When dealing with
+      // multi-piece selectors we only look for the first selector piece as we
+      // assume that textual matches correspond to a match of the first selector
+      // piece.
+      if (TokenName == Symbols[It->SymbolIndex].Name[0])
+        MatchHandler(Kind, It->Location, It->SymbolIndex);
+    }
+    RawLex.LexFromRawLexer(RawTok);
+  }
+}
+
+static void findMatchingTextualOccurrences(
+    const SourceManager &SM, const LangOptions &LangOpts,
+    ArrayRef<IndexedSymbol> Symbols,
+    llvm::function_ref<void(SymbolOccurrence::OccurrenceKind,
+                            ArrayRef<SourceLocation> Locations,
+                            unsigned SymbolIndex)>
+        MatchHandler) {
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
+  Lexer RawLex(SM.getMainFileID(), FromFile, SM, LangOpts);
+  RawLex.SetCommentRetentionState(true);
+
+  llvm::SmallVector<TextualMatchOccurrence, 4> CommentMatches;
+  llvm::SmallVector<SelectorParser, 2> SelectorParsers;
+  for (const auto &Symbol : llvm::enumerate(Symbols)) {
+    if (Symbol.value().IsObjCSelector)
+      SelectorParsers.push_back(
+          SelectorParser(Symbol.value().Name, Symbol.index()));
+  }
+
+  Token RawTok;
+  RawLex.LexFromRawLexer(RawTok);
+  while (RawTok.isNot(tok::eof)) {
+    if (RawTok.is(tok::comment)) {
+      SourceRange Range(RawTok.getLocation(), RawTok.getEndLoc());
+      StringRef Comment = Lexer::getSourceText(
+          CharSourceRange::getCharRange(Range), SM, LangOpts);
+      collectTextualMatchesInComment(Symbols, Range.getBegin(), Comment,
+                                     CommentMatches);
+      if (!CommentMatches.empty()) {
+        findTextualMatchesInComment(SM, LangOpts, Symbols, CommentMatches,
+                                    Range, MatchHandler);
+        CommentMatches.clear();
+      }
+    } else if (!SelectorParsers.empty()) {
+      for (auto &Parser : SelectorParsers) {
+        if (Parser.handleToken(RawTok))
+          MatchHandler(SymbolOccurrence::MatchingSelector,
+                       Parser.SelectorLocations, Parser.SymbolIndex);
+      }
+    }
+    RawLex.LexFromRawLexer(RawTok);
+  }
+}
+
+static void findInclusionDirectiveOccurrence(
+    const IndexedOccurrence &Occurrence, const IndexedSymbol &Symbol,
+    unsigned SymbolIndex, SourceManager &SM, const LangOptions &LangOpts,
+    IndexedFileOccurrenceConsumer &Consumer) {
+  if (!Occurrence.Line || !Occurrence.Column)
+    return; // Ignore any invalid indexed locations.
+
+  SourceLocation Loc = SM.translateLineCol(SM.getMainFileID(), Occurrence.Line,
+                                           Occurrence.Column);
+  if (Loc.isInvalid())
+    return;
+  unsigned Offset = SM.getDecomposedLoc(Loc).second;
+  const llvm::MemoryBuffer *File = SM.getBuffer(SM.getMainFileID());
+
+  InclusionLexer RawLex(Loc, LangOpts, File->getBufferStart() + Offset,
+                        File->getBufferEnd());
+  Token RawTok;
+  RawLex.LexFromRawLexer(RawTok);
+  if (RawTok.isNot(tok::hash))
+    return;
+  // include/import
+  RawLex.LexFromRawLexer(RawTok);
+  if (RawTok.isNot(tok::raw_identifier))
+    return;
+  // string literal/angled literal.
+  RawLex.setParsingPreprocessorDirective(true);
+  RawLex.LexIncludeFilename(RawTok);
+  if (RawTok.isNot(tok::string_literal) &&
+      RawTok.isNot(tok::angle_string_literal))
+    return;
+  StringRef Filename = llvm::sys::path::filename(
+      StringRef(RawTok.getLiteralData(), RawTok.getLength())
+          .drop_front()
+          .drop_back());
+  size_t NameOffset = Filename.rfind_lower(Symbol.Name[0]);
+  if (NameOffset == StringRef::npos)
+    return;
+  SymbolOccurrence Result(
+      SymbolOccurrence::MatchingFilename,
+      /*IsMacroExpansion=*/false, SymbolIndex,
+      RawTok.getLocation().getLocWithOffset(
+          NameOffset + (Filename.data() - RawTok.getLiteralData())));
+  Consumer.handleOccurrence(Result, SM, LangOpts);
+}
+
+void IndexedFileOccurrenceProducer::ExecuteAction() {
+  Preprocessor &PP = getCompilerInstance().getPreprocessor();
+  PP.EnterMainSourceFile();
+
+  SourceManager &SM = getCompilerInstance().getSourceManager();
+  const LangOptions &LangOpts = getCompilerInstance().getLangOpts();
+  if (IsMultiPiece) {
+    findObjCMultiPieceSelectorOccurrences(getCompilerInstance(), Symbols,
+                                          Consumer);
+  } else {
+    for (const auto &Symbol : llvm::enumerate(Symbols)) {
+      for (const IndexedOccurrence &Occurrence :
+           Symbol.value().IndexedOccurrences) {
+        if (Occurrence.Kind == IndexedOccurrence::InclusionDirective) {
+          findInclusionDirectiveOccurrence(Occurrence, Symbol.value(),
+                                           Symbol.index(), SM, LangOpts,
+                                           Consumer);
+          continue;
+        }
+        SourceRange SymbolRange;
+        MatchKind Match = checkOccurrence(Occurrence, Symbol.value(), SM,
+                                          LangOpts, SymbolRange,
+                                          /*AllowObjCSetterProp=*/true);
+        if (Match == MatchKind::None)
+          continue;
+        llvm::SmallVector<SourceLocation, 2> Locs;
+        Locs.push_back(SymbolRange.getBegin());
+        bool IsImpProp = Match == MatchKind::SourcePropSetterMatch;
+        if (IsImpProp)
+          Locs.push_back(SymbolRange.getEnd());
+        SymbolOccurrence Result(
+            IsImpProp ? SymbolOccurrence::MatchingImplicitProperty
+                      : SymbolOccurrence::MatchingSymbol,
+            /*IsMacroExpansion=*/Match == MatchKind::MacroExpansion,
+            Symbol.index(), Locs);
+        Consumer.handleOccurrence(Result, SM, LangOpts);
+      }
+    }
+  }
+
+  if (Options && Options->get(option::AvoidTextualMatches()))
+    return;
+  findMatchingTextualOccurrences(
+      SM, LangOpts, Symbols,
+      [&](SymbolOccurrence::OccurrenceKind Kind,
+          ArrayRef<SourceLocation> Locations, unsigned SymbolIndex) {
+        SymbolOccurrence Result(Kind, /*IsMacroExpansion=*/false, SymbolIndex,
+                                Locations);
+        Consumer.handleOccurrence(Result, SM, LangOpts);
+      });
+}
+
+namespace {
+
+/// Maps from source locations to the indexed occurrences.
+typedef llvm::DenseMap<unsigned, std::pair<IndexedOccurrence, unsigned>>
+    SourceLocationsToIndexedOccurrences;
+
+enum class ObjCSymbolSelectorKind { MessageSend, MethodDecl };
+
+} // end anonymous namespace
+
+static bool isMatchingSelectorName(const Token &Tok, const Token &Next,
+                                   StringRef NamePiece) {
+  if (NamePiece.empty())
+    return Tok.is(tok::colon);
+  return Tok.is(tok::raw_identifier) && Next.is(tok::colon) &&
+         Tok.getRawIdentifier() == NamePiece;
+}
+
+static bool
+findObjCSymbolSelectorPieces(ArrayRef<Token> Tokens, const SymbolName &Name,
+                             SmallVectorImpl<SourceLocation> &Pieces,
+                             ObjCSymbolSelectorKind Kind) {
+  assert(!Tokens.empty() && "no tokens");
+  assert(Name[0].empty() || Tokens[0].getRawIdentifier() == Name[0]);
+  assert(Name.size() > 1);
+  assert(Pieces.empty());
+
+  Pieces.push_back(Tokens[0].getLocation());
+
+  // We have to track square brackets, parens and braces as we want to skip the
+  // tokens inside them. This ensures that we don't use identical selector
+  // pieces in inner message sends, blocks, lambdas and @selector expressions.
+  unsigned SquareCount = 0;
+  unsigned ParenCount = 0;
+  unsigned BraceCount = 0;
+
+  // Start looking for the next selector piece.
+  unsigned Last = Tokens.size() - 1;
+  // Skip the ':' or any other token after the first selector piece token.
+  for (unsigned Index = Name[0].empty() ? 1 : 2; Index < Last; ++Index) {
+    const auto &Tok = Tokens[Index];
+
+    bool NoScoping = SquareCount == 0 && BraceCount == 0 && ParenCount == 0;
+    if (NoScoping &&
+        isMatchingSelectorName(Tok, Tokens[Index + 1], Name[Pieces.size()])) {
+      if (!Name[Pieces.size()].empty()) {
+        // Skip the ':' after the name. This ensures that it won't match a
+        // follow-up selector piece with an empty name.
+        ++Index;
+      }
+      Pieces.push_back(Tok.getLocation());
+      // All the selector pieces have been found.
+      if (Pieces.size() == Name.size())
+        return true;
+    } else if (Tok.is(tok::r_square)) {
+      // Stop scanning at the end of the message send.
+      // Also account for spurious ']' in blocks or lambdas.
+      if (Kind == ObjCSymbolSelectorKind::MessageSend && !SquareCount &&
+          !BraceCount)
+        break;
+      if (SquareCount)
+        --SquareCount;
+    } else if (Tok.is(tok::l_square))
+      ++SquareCount;
+    else if (Tok.is(tok::l_paren))
+      ++ParenCount;
+    else if (Tok.is(tok::r_paren)) {
+      if (!ParenCount)
+        break;
+      --ParenCount;
+    } else if (Tok.is(tok::l_brace)) {
+      // Stop scanning at the start of the of the method's body.
+      // Also account for any spurious blocks inside argument parameter types
+      // or parameter attributes.
+      if (Kind == ObjCSymbolSelectorKind::MethodDecl && !BraceCount &&
+          !ParenCount)
+        break;
+      ++BraceCount;
+    } else if (Tok.is(tok::r_brace)) {
+      if (!BraceCount)
+        break;
+      --BraceCount;
+    }
+    // Stop scanning at the end of the method's declaration.
+    if (Kind == ObjCSymbolSelectorKind::MethodDecl && NoScoping &&
+        (Tok.is(tok::semi) || Tok.is(tok::minus) || Tok.is(tok::plus)))
+      break;
+  }
+  return false;
+}
+
+// Scan the file and find multi-piece selector occurrences in a token stream.
+static void
+findObjCMultiPieceSelectorOccurrences(CompilerInstance &CI,
+                                      ArrayRef<IndexedSymbol> Symbols,
+                                      IndexedFileOccurrenceConsumer &Consumer) {
+  for (const auto &Symbol : Symbols) {
+    (void)Symbol;
+    assert(Symbol.Name.size() > 1 && "Not a multi-piece symbol!");
+  }
+
+  SourceManager &SM = CI.getSourceManager();
+  const LangOptions &LangOpts = CI.getLangOpts();
+  // Create a mapping from source locations to the indexed occurrences.
+  SourceLocationsToIndexedOccurrences MappedIndexedOccurrences;
+  for (const auto &Symbol : llvm::enumerate(Symbols)) {
+    for (const IndexedOccurrence &Occurrence :
+         Symbol.value().IndexedOccurrences) {
+      // Selectors and names in #includes shouldn't really mix.
+      if (Occurrence.Kind == IndexedOccurrence::InclusionDirective)
+        continue;
+      SourceRange SymbolRange;
+      MatchKind Match = checkOccurrence(Occurrence, Symbol.value(), SM,
+                                        LangOpts, SymbolRange);
+      if (Match == MatchKind::None)
+        continue;
+      SourceLocation Loc = SymbolRange.getBegin();
+      if (Match == MatchKind::MacroExpansion) {
+        SymbolOccurrence Result(SymbolOccurrence::MatchingSymbol,
+                                /*IsMacroExpansion=*/true, Symbol.index(), Loc);
+        Consumer.handleOccurrence(Result, SM, LangOpts);
+        continue;
+      }
+      MappedIndexedOccurrences.try_emplace(Loc.getRawEncoding(), Occurrence,
+                                           Symbol.index());
+    }
+  }
+
+  // Lex the file and look for tokens.
+  // Start lexing the specified input file.
+  const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
+  Lexer RawLex(SM.getMainFileID(), FromFile, SM, LangOpts);
+
+  std::vector<Token> Tokens;
+  bool SaveTokens = false;
+  Token RawTok;
+  RawLex.LexFromRawLexer(RawTok);
+  while (RawTok.isNot(tok::eof)) {
+    // Start saving tokens only when we've got a match
+    if (!SaveTokens) {
+      if (MappedIndexedOccurrences.find(
+              RawTok.getLocation().getRawEncoding()) !=
+          MappedIndexedOccurrences.end())
+        SaveTokens = true;
+    }
+    if (SaveTokens)
+      Tokens.push_back(RawTok);
+    RawLex.LexFromRawLexer(RawTok);
+  }
+
+  for (const auto &I : llvm::enumerate(Tokens)) {
+    const auto &Tok = I.value();
+    auto It = MappedIndexedOccurrences.find(Tok.getLocation().getRawEncoding());
+    if (It == MappedIndexedOccurrences.end())
+      continue;
+    unsigned SymbolIndex = It->second.second;
+    if (Tok.getKind() != tok::raw_identifier &&
+        !(Symbols[SymbolIndex].Name[0].empty() && Tok.is(tok::colon)))
+      continue;
+    const IndexedOccurrence &Occurrence = It->second.first;
+
+    // Scan the source for the remaining selector pieces.
+    SmallVector<SourceLocation, 4> SelectorPieces;
+    ObjCSymbolSelectorKind Kind =
+        Occurrence.Kind == IndexedOccurrence::IndexedObjCMessageSend
+            ? ObjCSymbolSelectorKind::MessageSend
+            : ObjCSymbolSelectorKind::MethodDecl;
+    if (findObjCSymbolSelectorPieces(
+            llvm::makeArrayRef(Tokens).drop_front(I.index()),
+            Symbols[SymbolIndex].Name, SelectorPieces, Kind)) {
+      SymbolOccurrence Result(SymbolOccurrence::MatchingSymbol,
+                              /*IsMacroExpansion=*/false, SymbolIndex,
+                              std::move(SelectorPieces));
+      Consumer.handleOccurrence(Result, SM, LangOpts);
+    }
+  }
+}
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/RenamedSymbol.cpp b/lib/Tooling/Refactor/RenamedSymbol.cpp
new file mode 100644
index 0000000..16ec01f
--- /dev/null
+++ b/lib/Tooling/Refactor/RenamedSymbol.cpp
@@ -0,0 +1,41 @@
+//===--- RenamedSymbol.cpp - ----------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/RenamedSymbol.h"
+#include "clang/AST/DeclObjC.h"
+#include <algorithm>
+
+using namespace clang;
+
+namespace clang {
+namespace tooling {
+namespace rename {
+
+Symbol::Symbol(const NamedDecl *FoundDecl, unsigned SymbolIndex,
+               const LangOptions &LangOpts)
+    : Name(FoundDecl->getNameAsString(), LangOpts), SymbolIndex(SymbolIndex),
+      FoundDecl(FoundDecl) {
+  if (const auto *MD = dyn_cast<ObjCMethodDecl>(FoundDecl))
+    ObjCSelector = MD->getSelector();
+}
+
+bool operator<(const SymbolOccurrence &LHS, const SymbolOccurrence &RHS) {
+  assert(!LHS.Locations.empty() && !RHS.Locations.empty());
+  return LHS.Locations[0] < RHS.Locations[0];
+}
+
+bool operator==(const SymbolOccurrence &LHS, const SymbolOccurrence &RHS) {
+  return LHS.Kind == RHS.Kind && LHS.SymbolIndex == RHS.SymbolIndex &&
+         std::equal(LHS.Locations.begin(), LHS.Locations.end(),
+                    RHS.Locations.begin());
+}
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/RenamingOperation.cpp b/lib/Tooling/Refactor/RenamingOperation.cpp
new file mode 100644
index 0000000..80aa1bc
--- /dev/null
+++ b/lib/Tooling/Refactor/RenamingOperation.cpp
@@ -0,0 +1,98 @@
+//===--- RenamingOperation.cpp - ------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/RenamingOperation.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Refactor/SymbolOperation.h"
+
+using namespace clang;
+
+/// \brief Lexes the given name string.
+///
+/// \return False if the name was consumed fully, true otherwise.
+static bool lexNameString(StringRef Name, Token &Result,
+                          const LangOptions &LangOpts) {
+  Lexer Lex(SourceLocation(), LangOpts, Name.data(), Name.data(),
+            Name.data() + Name.size());
+  return !Lex.LexFromRawLexer(Result);
+}
+
+namespace clang {
+namespace tooling {
+namespace rename {
+
+bool isNewNameValid(const SymbolName &NewName, bool IsSymbolObjCSelector,
+                    IdentifierTable &IDs, const LangOptions &LangOpts) {
+  Token Tok;
+  if (IsSymbolObjCSelector) {
+    // Check if the name is a valid selector.
+    for (const auto &Name : NewName.strings()) {
+      // Lex the name and verify that it was fully consumed. Then make sure that
+      // it's a valid identifier.
+      if (lexNameString(Name, Tok, LangOpts) || !Tok.isAnyIdentifier())
+        return false;
+    }
+    return true;
+  }
+
+  for (const auto &Name : NewName.strings()) {
+    // Lex the name and verify that it was fully consumed. Then make sure that
+    // it's a valid identifier that's also not a language keyword.
+    if (lexNameString(Name, Tok, LangOpts) || !Tok.isAnyIdentifier() ||
+        !tok::isAnyIdentifier(IDs.get(Name).getTokenID()))
+      return false;
+  }
+  return true;
+}
+
+bool isNewNameValid(const SymbolName &NewName, const SymbolOperation &Operation,
+                    IdentifierTable &IDs, const LangOptions &LangOpts) {
+  assert(!Operation.symbols().empty());
+  return isNewNameValid(NewName,
+                        Operation.symbols().front().ObjCSelector.hasValue(),
+                        IDs, LangOpts);
+}
+
+void determineNewNames(SymbolName NewName, const SymbolOperation &Operation,
+                       SmallVectorImpl<SymbolName> &NewNames,
+                       const LangOptions &LangOpts) {
+  auto Symbols = Operation.symbols();
+  assert(!Symbols.empty());
+  NewNames.push_back(std::move(NewName));
+  if (const auto *PropertyDecl =
+          dyn_cast<ObjCPropertyDecl>(Symbols.front().FoundDecl)) {
+    assert(NewNames.front().size() == 1 &&
+           "Property's name should have one string only");
+    StringRef PropertyName = NewNames.front()[0];
+    Symbols = Symbols.drop_front();
+
+    auto AddName = [&](const NamedDecl *D, StringRef Name) {
+      assert(Symbols.front().FoundDecl == D && "decl is missing");
+      NewNames.push_back(SymbolName(Name, LangOpts));
+      Symbols = Symbols.drop_front();
+    };
+
+    if (!PropertyDecl->hasExplicitGetterName()) {
+      if (const auto *Getter = PropertyDecl->getGetterMethodDecl())
+        AddName(Getter, PropertyName);
+    }
+    if (!PropertyDecl->hasExplicitSetterName()) {
+      if (const auto *Setter = PropertyDecl->getSetterMethodDecl()) {
+        auto SetterName = SelectorTable::constructSetterName(PropertyName);
+        AddName(Setter, SetterName);
+      }
+    }
+  }
+}
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/SourceLocationUtilities.cpp b/lib/Tooling/Refactor/SourceLocationUtilities.cpp
new file mode 100644
index 0000000..0a0c4cd
--- /dev/null
+++ b/lib/Tooling/Refactor/SourceLocationUtilities.cpp
@@ -0,0 +1,260 @@
+//===--- SourceLocationUtilities.cpp - Source location helper functions ---===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SourceLocationUtilities.h"
+#include "clang/AST/Stmt.h"
+#include "clang/Lex/Lexer.h"
+#include <limits>
+
+namespace clang {
+namespace tooling {
+
+SourceLocation findLastLocationOfSourceConstruct(SourceLocation HeaderEnd,
+                                                 const Stmt *Body,
+                                                 const SourceManager &SM) {
+  SourceLocation BodyStart = SM.getSpellingLoc(Body->getLocStart());
+  unsigned BodyLine = SM.getSpellingLineNumber(BodyStart);
+  unsigned HeaderLine = SM.getSpellingLineNumber(HeaderEnd);
+
+  if (BodyLine > HeaderLine) {
+    // The Last location on the previous line if the body is not on the same
+    // line as the last known location.
+    SourceLocation LineLocThatPrecedesBody =
+        SM.translateLineCol(SM.getFileID(BodyStart), BodyLine - 1,
+                            std::numeric_limits<unsigned>::max());
+    if (LineLocThatPrecedesBody.isValid())
+      return LineLocThatPrecedesBody;
+  }
+  // We want to include the location of the '{'.
+  return isa<CompoundStmt>(Body) ? BodyStart : BodyStart.getLocWithOffset(-1);
+}
+
+SourceLocation findFirstLocationOfSourceConstruct(SourceLocation HeaderStart,
+                                                  const Stmt *PreviousBody,
+                                                  const SourceManager &SM) {
+  if (!isa<CompoundStmt>(PreviousBody))
+    return HeaderStart;
+  SourceLocation BodyEnd = SM.getSpellingLoc(PreviousBody->getLocEnd());
+  unsigned BodyLine = SM.getSpellingLineNumber(BodyEnd);
+  unsigned HeaderLine = SM.getSpellingLineNumber(HeaderStart);
+  if (BodyLine >= HeaderLine)
+    return BodyEnd;
+  return HeaderStart;
+}
+
+bool isLocationInAnyRange(SourceLocation Location, ArrayRef<SourceRange> Ranges,
+                          const SourceManager &SM) {
+  for (const SourceRange &Range : Ranges) {
+    if (!isPointWithin(Location, Range.getBegin(), Range.getEnd(), SM))
+      continue;
+    return true;
+  }
+  return false;
+}
+
+SourceLocation getPreciseTokenLocEnd(SourceLocation Loc,
+                                     const SourceManager &SM,
+                                     const LangOptions &LangOpts) {
+  return Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts);
+}
+
+SourceLocation findClosingParenLocEnd(SourceLocation LastKnownLoc,
+                                      const SourceManager &SM,
+                                      const LangOptions &LangOpts) {
+  return Lexer::findLocationAfterToken(
+      LastKnownLoc, tok::r_paren, SM, LangOpts,
+      /*SkipTrailingWhitespaceAndNewLine=*/false);
+}
+
+SourceRange getRangeOfNextToken(SourceLocation Loc, tok::TokenKind Kind,
+                                const SourceManager &SM,
+                                const LangOptions &LangOpts) {
+  SourceLocation NextLoc =
+      Lexer::findLocationAfterToken(Loc, Kind, SM, LangOpts,
+                                    /*SkipTrailingWhitespaceAndNewLine=*/false);
+  if (NextLoc.isInvalid())
+    return SourceRange();
+  return SourceRange(
+      Lexer::GetBeginningOfToken(NextLoc.getLocWithOffset(-1), SM, LangOpts),
+      NextLoc);
+}
+
+SourceLocation findLastNonCompoundLocation(const Stmt *S) {
+  const auto *CS = dyn_cast<CompoundStmt>(S);
+  if (!CS)
+    return S->getLocEnd();
+  return CS->body_back() ? CS->body_back()->getLocEnd() : SourceLocation();
+}
+
+bool areOnSameLine(SourceLocation Loc1, SourceLocation Loc2,
+                   const SourceManager &SM) {
+  return !Loc1.isMacroID() && !Loc2.isMacroID() &&
+         SM.getSpellingLineNumber(Loc1) == SM.getSpellingLineNumber(Loc2);
+}
+
+SourceLocation
+getLastLineLocationUnlessItHasOtherTokens(SourceLocation SpellingLoc,
+                                          const SourceManager &SM,
+                                          const LangOptions &LangOpts) {
+  assert(!SpellingLoc.isMacroID() && "Expecting a spelling location");
+  SourceLocation NextTokenLoc =
+      Lexer::findNextTokenLocationAfterTokenAt(SpellingLoc, SM, LangOpts);
+  if (NextTokenLoc.isValid()) {
+    bool IsSameLine = areOnSameLine(SpellingLoc, NextTokenLoc, SM);
+    if (IsSameLine) {
+      // Could be a ';' on the same line, so try looking after the ';'
+      if (isSemicolonAtLocation(NextTokenLoc, SM, LangOpts))
+        return getLastLineLocationUnlessItHasOtherTokens(NextTokenLoc, SM,
+                                                         LangOpts);
+    } else {
+      SourceLocation LastLoc = SM.translateLineCol(
+          SM.getFileID(SpellingLoc), SM.getSpellingLineNumber(SpellingLoc),
+          std::numeric_limits<unsigned>::max());
+      if (LastLoc.isValid())
+        return LastLoc;
+    }
+  }
+  return getPreciseTokenLocEnd(SpellingLoc, SM, LangOpts);
+}
+
+bool isSemicolonAtLocation(SourceLocation TokenLoc, const SourceManager &SM,
+                           const LangOptions &LangOpts) {
+  return Lexer::getSourceText(
+             CharSourceRange::getTokenRange(TokenLoc, TokenLoc), SM,
+             LangOpts) == ";";
+}
+
+SourceRange trimSelectionRange(SourceRange Range, const SourceManager &SM,
+                               const LangOptions &LangOpts) {
+  bool IsInvalid = false;
+  StringRef Text = Lexer::getSourceText(CharSourceRange::getCharRange(Range),
+                                        SM, LangOpts, &IsInvalid);
+  if (IsInvalid || Text.empty())
+    return Range;
+  assert(Range.getBegin().isFileID() && "Not a file range!");
+
+  std::string Source = Text.str();
+  Lexer Lex(Range.getBegin(), LangOpts, Source.c_str(), Source.c_str(),
+            Source.c_str() + Source.size());
+  // Get comment tokens as well.
+  Lex.SetCommentRetentionState(true);
+  SourceLocation StartLoc, EndLoc;
+  while (true) {
+    Token Tok;
+    Lex.LexFromRawLexer(Tok);
+    if (Tok.getKind() == tok::eof)
+      break;
+    if (StartLoc.isInvalid())
+      StartLoc = Tok.getLocation();
+    if (Tok.getKind() != tok::semi)
+      EndLoc = Tok.getEndLoc();
+  }
+  return StartLoc.isValid() && EndLoc.isValid() ? SourceRange(StartLoc, EndLoc)
+                                                : SourceRange();
+}
+
+/// Tokenize the given file and check if it contains a comment that ends at the
+/// given location.
+static SourceLocation findCommentThatEndsAt(FileID FID,
+                                            SourceLocation StartOfFile,
+                                            const SourceManager &SM,
+                                            const LangOptions &LangOpts,
+                                            SourceLocation ExpectedEndLoc) {
+  // Try to load the file buffer.
+  bool InvalidTemp = false;
+  StringRef File = SM.getBufferData(FID, &InvalidTemp);
+  if (InvalidTemp)
+    return SourceLocation();
+
+  // Search for the comment that ends at the given location.
+  Lexer Lex(StartOfFile, LangOpts, File.begin(), File.begin(), File.end());
+  Lex.SetCommentRetentionState(true);
+  Token Tok;
+  while (!Lex.LexFromRawLexer(Tok)) {
+    if (Tok.is(tok::comment) && Tok.getEndLoc() == ExpectedEndLoc)
+      return Tok.getLocation();
+  }
+  // Find the token.
+  return SourceLocation();
+}
+
+SourceLocation getLocationOfPrecedingComment(SourceLocation Location,
+                                             const SourceManager &SM,
+                                             const LangOptions &LangOpts) {
+  SourceLocation PrevResult = Location;
+  SourceLocation Result = Location;
+  if (Result.isMacroID())
+    Result = SM.getExpansionLoc(Result);
+  FileID FID = SM.getFileID(Result);
+  SourceLocation StartOfFile = SM.getLocForStartOfFile(FID);
+  Token Tok;
+  Tok.setKind(tok::unknown);
+  SourceLocation TokenLoc = Result;
+  auto GetPreviousToken = [&]() -> bool {
+    TokenLoc =
+        Lexer::GetBeginningOfToken(TokenLoc.getLocWithOffset(-1), SM, LangOpts);
+    return !Lexer::getRawToken(TokenLoc, Tok, SM, LangOpts);
+  };
+  // Look for a comment token.
+  while (TokenLoc != StartOfFile) {
+    bool LocHasToken = GetPreviousToken();
+    if (LocHasToken && Tok.is(tok::slash)) {
+      // Check if this  the end of a multiline '/*' comment before returning.
+      SourceLocation CommentLoc = findCommentThatEndsAt(
+          FID, StartOfFile, SM, LangOpts, Tok.getEndLoc());
+      return CommentLoc.isInvalid() ? Result : CommentLoc;
+    }
+    if (LocHasToken && Tok.isNot(tok::comment))
+      break;
+    if (!LocHasToken)
+      continue;
+    // We found a preceding comment. Check if there are other preceding
+    // comments.
+    PrevResult = Result;
+    Result = Tok.getLocation();
+    while (TokenLoc != StartOfFile) {
+      bool LocHasToken = GetPreviousToken();
+      if (LocHasToken && Tok.isNot(tok::comment)) {
+        // Reset the result to the previous location if this comment trails
+        // another token on the same line.
+        if (SM.getSpellingLineNumber(Tok.getEndLoc()) ==
+            SM.getSpellingLineNumber(Result))
+          Result = PrevResult;
+        break;
+      }
+      if (!LocHasToken)
+        continue;
+      // The location of this comment is accepted only when the next comment
+      // is located immediately after this comment.
+      if (SM.getSpellingLineNumber(Tok.getEndLoc()) !=
+          SM.getSpellingLineNumber(Result) - 1)
+        break;
+      PrevResult = Result;
+      Result = Tok.getLocation();
+    }
+    break;
+  }
+  return Result;
+}
+
+SourceLocation getLocationOfPrecedingToken(SourceLocation Loc,
+                                           const SourceManager &SM,
+                                           const LangOptions &LangOpts) {
+  SourceLocation Result = Loc;
+  if (Result.isMacroID())
+    Result = SM.getExpansionLoc(Result);
+  FileID FID = SM.getFileID(Result);
+  SourceLocation StartOfFile = SM.getLocForStartOfFile(FID);
+  if (Loc == StartOfFile)
+    return SourceLocation();
+  return Lexer::GetBeginningOfToken(Result.getLocWithOffset(-1), SM, LangOpts);
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/SourceLocationUtilities.h b/lib/Tooling/Refactor/SourceLocationUtilities.h
new file mode 100644
index 0000000..ba7425b
--- /dev/null
+++ b/lib/Tooling/Refactor/SourceLocationUtilities.h
@@ -0,0 +1,174 @@
+//===--- SourceLocationUtilities.h - Source location helper functions -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_TOOLING_REFACTOR_SOURCE_LOCATION_UTILITIES_H
+#define LLVM_CLANG_LIB_TOOLING_REFACTOR_SOURCE_LOCATION_UTILITIES_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/TokenKinds.h"
+
+namespace clang {
+
+class Stmt;
+class LangOptions;
+
+namespace tooling {
+
+inline bool isPairOfFileLocations(SourceLocation Start, SourceLocation End) {
+  return Start.isValid() && Start.isFileID() && End.isValid() && End.isFileID();
+}
+
+/// Return true if the Point is within Start and End.
+inline bool isPointWithin(SourceLocation Location, SourceLocation Start,
+                          SourceLocation End, const SourceManager &SM) {
+  return Location == Start || Location == End ||
+         (SM.isBeforeInTranslationUnit(Start, Location) &&
+          SM.isBeforeInTranslationUnit(Location, End));
+}
+
+/// Return true if the two given ranges overlap with each other.
+inline bool areRangesOverlapping(SourceRange R1, SourceRange R2,
+                                 const SourceManager &SM) {
+  return isPointWithin(R1.getBegin(), R2.getBegin(), R2.getEnd(), SM) ||
+         isPointWithin(R2.getBegin(), R1.getBegin(), R1.getEnd(), SM);
+}
+
+/// \brief Return the source location that can be considered the last location
+/// of the source construct before its body.
+///
+/// The returned location is determined using the following rules:
+///
+/// 1) If the source construct has a compound body that starts on the same line,
+///    then this function will return the location of the opening '{'.
+///
+///    if (condition) {
+///                   ^
+///
+/// 2) If the source construct's body is not a compound statement that starts
+///    on the same line, then this function will return the location just before
+///    the starting location of the body.
+///
+///    if (condition) foo()
+///                  ^
+///
+/// 3) Otherwise, this function will return the last location on the line prior
+///    to the the line on which the body starts.
+///
+///    if (condition)
+///                  ^
+///      foo()
+///
+/// \param HeaderEnd The last known location of the pre-body portion of the
+/// source construct. For example, for an if statement, HeaderEnd should
+/// be the ending location of its conditional expression.
+SourceLocation findLastLocationOfSourceConstruct(SourceLocation HeaderEnd,
+                                                 const Stmt *Body,
+                                                 const SourceManager &SM);
+
+/// \brief Return the source location that can be considered the first location
+/// of the source construct prior to the previous portion of its body.
+///
+/// The returned location is determined using the following rules:
+///
+/// 1) If the source construct's body is a compound statement that ends
+///    on the same line, then this function will return the location of the
+///    closing '}'.
+///
+///    } else if (condition)
+///    ^
+///
+/// 2) Otherwise, this function will return the starting location of the source
+///    construct.
+///
+///      foo();
+///    else if (condition)
+///    ^
+///
+///    }
+///    else if (condition)
+///    ^
+///
+/// \param HeaderStart The first known location of the post-body portion of the
+/// source construct. For example, for an if statement, HeaderStart should
+/// be the starting location of the if keyword.
+SourceLocation findFirstLocationOfSourceConstruct(SourceLocation HeaderStart,
+                                                  const Stmt *PreviousBody,
+                                                  const SourceManager &SM);
+
+/// Return true if the given \p Location is within any range.
+bool isLocationInAnyRange(SourceLocation Location, ArrayRef<SourceRange> Ranges,
+                          const SourceManager &SM);
+
+/// Return the precise end location for the given token.
+SourceLocation getPreciseTokenLocEnd(SourceLocation Loc,
+                                     const SourceManager &SM,
+                                     const LangOptions &LangOpts);
+
+/// \brief Find the source location right after the location of the next ')'.
+///
+/// If the token that's located after \p LastKnownLoc isn't ')', then this
+/// function returns an invalid source location.
+SourceLocation findClosingParenLocEnd(SourceLocation LastKnownLoc,
+                                      const SourceManager &SM,
+                                      const LangOptions &LangOpts);
+
+/// Return the range of the next token if it has the given kind.
+SourceRange getRangeOfNextToken(SourceLocation Loc, tok::TokenKind Kind,
+                                const SourceManager &SM,
+                                const LangOptions &LangOpts);
+
+/// Return the end location of the body when \p S is a compound statement or an
+/// invalid location when \p S is an empty compound statement. Otherwise,
+/// return the end location of the given statement \p S.
+SourceLocation findLastNonCompoundLocation(const Stmt *S);
+
+/// Return true if the two locations are on the same line and aren't
+///  macro locations.
+bool areOnSameLine(SourceLocation Loc1, SourceLocation Loc2,
+                   const SourceManager &SM);
+
+/// Return the last location of the line which contains the given spellling
+/// location \p SpellingLoc unless that line has other tokens after the given
+/// location.
+SourceLocation
+getLastLineLocationUnlessItHasOtherTokens(SourceLocation SpellingLoc,
+                                          const SourceManager &SM,
+                                          const LangOptions &LangOpts);
+
+/// Return true if the token at the given location is a semicolon.
+bool isSemicolonAtLocation(SourceLocation TokenLoc, const SourceManager &SM,
+                           const LangOptions &LangOpts);
+
+/// Shrink the given range by ignoring leading whitespace and trailing
+/// whitespace and semicolons.
+///
+/// Returns an invalid source range if the source range consists of whitespace
+/// or semicolons only.
+SourceRange trimSelectionRange(SourceRange Range, const SourceManager &SM,
+                               const LangOptions &LangOpts);
+
+/// Return the source location of the conjoined comment(s) that precede the
+/// given location \p Loc, or the same location if there's no comment before
+/// \p Loc.
+SourceLocation getLocationOfPrecedingComment(SourceLocation Loc,
+                                             const SourceManager &SM,
+                                             const LangOptions &LangOpts);
+
+/// Return the source location of the token that comes before the token at the
+/// given location.
+SourceLocation getLocationOfPrecedingToken(SourceLocation Loc,
+                                           const SourceManager &SM,
+                                           const LangOptions &LangOpts);
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_TOOLING_REFACTOR_SOURCE_LOCATION_UTILITIES_H
diff --git a/lib/Tooling/Refactor/StmtUtils.cpp b/lib/Tooling/Refactor/StmtUtils.cpp
new file mode 100644
index 0000000..d5644b2
--- /dev/null
+++ b/lib/Tooling/Refactor/StmtUtils.cpp
@@ -0,0 +1,72 @@
+//===--- StmtUtils.cpp - Statement helper functions -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "StmtUtils.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang;
+
+SourceLocation
+clang::tooling::getLexicalEndLocForDecl(const Decl *D, const SourceManager &SM,
+                                        const LangOptions &LangOpts) {
+  if (!isa<ObjCImplDecl>(D))
+    return D->getSourceRange().getEnd();
+  auto AtEnd = D->getSourceRange().getEnd();
+  auto AdjustedEnd =
+      Lexer::findNextTokenLocationAfterTokenAt(AtEnd, SM, LangOpts);
+  return AdjustedEnd.isValid() ? AdjustedEnd : AtEnd;
+}
+
+bool clang::tooling::isSemicolonRequiredAfter(const Stmt *S) {
+  if (isa<CompoundStmt>(S))
+    return false;
+  if (const auto *If = dyn_cast<IfStmt>(S))
+    return isSemicolonRequiredAfter(If->getElse() ? If->getElse()
+                                                  : If->getThen());
+  if (const auto *While = dyn_cast<WhileStmt>(S))
+    return isSemicolonRequiredAfter(While->getBody());
+  if (const auto *For = dyn_cast<ForStmt>(S))
+    return isSemicolonRequiredAfter(For->getBody());
+  if (const auto *CXXFor = dyn_cast<CXXForRangeStmt>(S))
+    return isSemicolonRequiredAfter(CXXFor->getBody());
+  if (const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(S))
+    return isSemicolonRequiredAfter(ObjCFor->getBody());
+  switch (S->getStmtClass()) {
+  case Stmt::SwitchStmtClass:
+  case Stmt::CXXTryStmtClass:
+  case Stmt::ObjCAtSynchronizedStmtClass:
+  case Stmt::ObjCAutoreleasePoolStmtClass:
+  case Stmt::ObjCAtTryStmtClass:
+    return false;
+  default:
+    return true;
+  }
+}
+
+static bool isAssignmentOperator(const Stmt *S) {
+  if (const auto *PseudoExpr = dyn_cast<PseudoObjectExpr>(S))
+    return isAssignmentOperator(PseudoExpr->getSyntacticForm());
+  if (const auto *BO = dyn_cast<BinaryOperator>(S))
+    return BO->isAssignmentOp();
+  return false;
+}
+
+bool clang::tooling::isLexicalExpression(const Stmt *S, const Stmt *Parent) {
+  if (!isa<Expr>(S))
+    return false;
+  // Assignment operators should be treated as statements unless they are a part
+  // of an expression.
+  if (isAssignmentOperator(S) && (!Parent || !isa<Expr>(Parent)))
+    return false;
+  return !cast<Expr>(S)->getType()->isVoidType();
+}
diff --git a/lib/Tooling/Refactor/StmtUtils.h b/lib/Tooling/Refactor/StmtUtils.h
new file mode 100644
index 0000000..5bc3195
--- /dev/null
+++ b/lib/Tooling/Refactor/StmtUtils.h
@@ -0,0 +1,38 @@
+//===--- StmtUtils.h - Statement helper functions -------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_TOOLING_REFACTOR_STMT_UTILS_H
+#define LLVM_CLANG_LIB_TOOLING_REFACTOR_STMT_UTILS_H
+
+#include "clang/Basic/SourceLocation.h"
+
+namespace clang {
+
+class Decl;
+class LangOptions;
+class Stmt;
+
+namespace tooling {
+
+SourceLocation getLexicalEndLocForDecl(const Decl *D, const SourceManager &SM,
+                                       const LangOptions &LangOpts);
+
+/// \brief Returns true if there should be a semicolon after the given
+/// statement.
+bool isSemicolonRequiredAfter(const Stmt *S);
+
+/// Returns true if the given statement \p S is an actual expression in the
+/// source. Assignment expressions are considered to be statements unless they
+/// are a part of an expression.
+bool isLexicalExpression(const Stmt *S, const Stmt *Parent);
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_TOOLING_REFACTOR_STMT_UTILS_H
diff --git a/lib/Tooling/Refactor/SymbolName.cpp b/lib/Tooling/Refactor/SymbolName.cpp
new file mode 100644
index 0000000..2d30d18
--- /dev/null
+++ b/lib/Tooling/Refactor/SymbolName.cpp
@@ -0,0 +1,58 @@
+//===--- SymbolName.cpp - Clang refactoring library -----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/SymbolName.h"
+#include "clang/Basic/LangOptions.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace clang {
+namespace tooling {
+
+static void initNames(std::vector<std::string> &Strings, StringRef Name,
+                      bool IsObjectiveCSelector) {
+  if (!IsObjectiveCSelector) {
+    Strings.push_back(Name.str());
+    return;
+  }
+  // Decompose an Objective-C selector name into multiple strings.
+  do {
+    auto StringAndName = Name.split(':');
+    Strings.push_back(StringAndName.first.str());
+    Name = StringAndName.second;
+  } while (!Name.empty());
+}
+
+SymbolName::SymbolName(StringRef Name, const LangOptions &LangOpts) {
+  initNames(Strings, Name, LangOpts.ObjC1);
+}
+
+SymbolName::SymbolName(StringRef Name, bool IsObjectiveCSelector) {
+  initNames(Strings, Name, IsObjectiveCSelector);
+}
+
+SymbolName::SymbolName(ArrayRef<StringRef> Name) {
+  for (const auto &Piece : Name)
+    Strings.push_back(Piece.str());
+}
+
+void SymbolName::print(raw_ostream &OS) const {
+  for (size_t I = 0, E = Strings.size(); I != E; ++I) {
+    if (I != 0)
+      OS << ':';
+    OS << Strings[I];
+  }
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const SymbolName &N) {
+  N.print(OS);
+  return OS;
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/SymbolOccurrenceFinder.cpp b/lib/Tooling/Refactor/SymbolOccurrenceFinder.cpp
new file mode 100644
index 0000000..38f4cc8
--- /dev/null
+++ b/lib/Tooling/Refactor/SymbolOccurrenceFinder.cpp
@@ -0,0 +1,412 @@
+//===--- SymbolOccurrenceFinder.cpp - Clang refactoring library -----------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Methods for finding all instances of a USR. Our strategy is very
+/// simple; we just compare the USR at every relevant AST node with the one
+/// provided.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/SymbolOccurrenceFinder.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DependentASTVisitor.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Basic/SourceManager.h"
+#include "clang/Index/USRGeneration.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Refactor/USRFinder.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+
+using namespace llvm;
+
+namespace clang {
+namespace tooling {
+namespace rename {
+
+namespace {
+// \brief This visitor recursively searches for all instances of a USR in a
+// translation unit and stores them for later usage.
+class SymbolOccurrenceFinderASTVisitor
+    : public DependentASTVisitor<SymbolOccurrenceFinderASTVisitor> {
+public:
+  explicit SymbolOccurrenceFinderASTVisitor(
+      const SymbolOperation &Operation, const ASTContext &Context,
+      std::vector<SymbolOccurrence> &Occurrences)
+      : Operation(Operation), Context(Context), Occurrences(Occurrences) {}
+
+  /// Returns a \c Symbol if the given declaration corresponds to the symbol
+  /// that we're looking for.
+  const Symbol *symbolForDecl(const Decl *D) const {
+    if (!D)
+      return nullptr;
+    std::string USR = getUSRForDecl(D);
+    return Operation.getSymbolForUSR(USR);
+  }
+
+  void checkDecl(const Decl *D, SourceLocation Loc,
+                 SymbolOccurrence::OccurrenceKind Kind =
+                     SymbolOccurrence::MatchingSymbol) {
+    if (!D)
+      return;
+    std::string USR = getUSRForDecl(D);
+    if (const Symbol *S = Operation.getSymbolForUSR(USR))
+      checkAndAddLocations(S->SymbolIndex, Loc, Kind);
+  }
+
+  // Declaration visitors:
+
+  bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
+    for (const auto *Initializer : ConstructorDecl->inits()) {
+      // Ignore implicit initializers.
+      if (!Initializer->isWritten())
+        continue;
+      if (const clang::FieldDecl *FieldDecl = Initializer->getMember())
+        checkDecl(FieldDecl, Initializer->getSourceLocation());
+    }
+    return true;
+  }
+
+  bool VisitNamedDecl(const NamedDecl *Decl) {
+    checkDecl(Decl, Decl->getLocation());
+    return true;
+  }
+
+  bool WalkUpFromTypedefNameDecl(const TypedefNameDecl *D) {
+    // Don't visit the NamedDecl for TypedefNameDecl.
+    return VisitTypedefNamedDecl(D);
+  }
+
+  bool VisitTypedefNamedDecl(const TypedefNameDecl *D) {
+    if (D->isTransparentTag()) {
+      if (const auto *Underlying = D->getUnderlyingType()->getAsTagDecl()) {
+        checkDecl(Underlying, D->getLocation());
+        return true;
+      }
+    }
+    return VisitNamedDecl(D);
+  }
+
+  bool WalkUpFromUsingDecl(const UsingDecl *D) {
+    // Don't visit the NamedDecl for UsingDecl.
+    return VisitUsingDecl(D);
+  }
+
+  bool VisitUsingDecl(const UsingDecl *D) {
+    for (const auto *Shadow : D->shadows()) {
+      const NamedDecl *UD = Shadow->getUnderlyingDecl();
+      if (UD->isImplicit() || UD == D)
+        continue;
+      if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(UD)) {
+        UD = FTD->getTemplatedDecl();
+        if (!UD)
+          continue;
+      }
+      checkDecl(UD, D->getLocation());
+    }
+    return true;
+  }
+
+  bool WalkUpFromUsingDirectiveDecl(const UsingDirectiveDecl *D) {
+    // Don't visit the NamedDecl for UsingDirectiveDecl.
+    return VisitUsingDirectiveDecl(D);
+  }
+
+  bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
+    checkDecl(D->getNominatedNamespaceAsWritten(), D->getLocation());
+    return true;
+  }
+
+  bool WalkUpFromUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
+    // Don't visit the NamedDecl for UnresolvedUsingValueDecl.
+    // FIXME: Can we try to lookup the name?
+    return true;
+  }
+
+  bool
+  WalkUpFromUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
+    // Don't visit the NamedDecl for UnresolvedUsingTypenameDecl.
+    // FIXME: Can we try to lookup the name?
+    return true;
+  }
+
+  bool WalkUpFromObjCMethodDecl(const ObjCMethodDecl *Decl) {
+    // Don't visit the NamedDecl for Objective-C methods.
+    return VisitObjCMethodDecl(Decl);
+  }
+
+  bool VisitObjCMethodDecl(const ObjCMethodDecl *Decl) {
+    const Symbol *S = symbolForDecl(Decl);
+    if (!S)
+      return true;
+    SmallVector<SourceLocation, 8> SelectorLocs;
+    Decl->getSelectorLocs(SelectorLocs);
+    checkAndAddLocations(S->SymbolIndex, SelectorLocs);
+    return true;
+  }
+
+  bool handleObjCProtocolList(const ObjCProtocolList &Protocols) {
+    for (auto It : enumerate(Protocols))
+      checkDecl(It.value(), Protocols.loc_begin()[It.index()]);
+    return true;
+  }
+
+  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *Decl) {
+    if (!Decl->hasDefinition())
+      return true;
+    return handleObjCProtocolList(Decl->getReferencedProtocols());
+  }
+
+  bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl) {
+    if (!Decl->hasDefinition())
+      return true;
+    return handleObjCProtocolList(Decl->getReferencedProtocols());
+  }
+
+  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl) {
+    checkDecl(Decl, Decl->getCategoryNameLoc());
+    // The location of the class name is the location of the declaration.
+    checkDecl(Decl->getClassInterface(), Decl->getLocation());
+    return handleObjCProtocolList(Decl->getReferencedProtocols());
+  }
+
+  bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *Decl) {
+    checkDecl(Decl, Decl->getCategoryNameLoc());
+    // The location of the class name is the location of the declaration.
+    checkDecl(Decl->getClassInterface(), Decl->getLocation());
+    return true;
+  }
+
+  bool VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *Decl) {
+    checkDecl(Decl->getClassInterface(), Decl->getClassInterfaceLoc());
+    return true;
+  }
+
+  bool VisitObjCPropertyDecl(const ObjCPropertyDecl *Decl) {
+    if (Decl->hasExplicitGetterName())
+      checkDecl(Decl->getGetterMethodDecl(), Decl->getGetterNameLoc());
+    if (Decl->hasExplicitSetterName())
+      checkDecl(Decl->getSetterMethodDecl(), Decl->getSetterNameLoc());
+    return true;
+  }
+
+  bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *Decl) {
+    checkDecl(Decl->getPropertyDecl(), Decl->getLocation());
+    if (Decl->isIvarNameSpecified())
+      checkDecl(Decl->getPropertyIvarDecl(), Decl->getPropertyIvarDeclLoc());
+    return true;
+  }
+
+  // Expression visitors:
+
+  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
+    checkDecl(Expr->getFoundDecl(), Expr->getLocation());
+    return true;
+  }
+
+  bool VisitMemberExpr(const MemberExpr *Expr) {
+    checkDecl(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
+    return true;
+  }
+
+  bool VisitObjCMessageExpr(const ObjCMessageExpr *Expr) {
+    const Symbol *S = symbolForDecl(Expr->getMethodDecl());
+    if (!S)
+      return true;
+    SmallVector<SourceLocation, 8> SelectorLocs;
+    Expr->getSelectorLocs(SelectorLocs);
+    checkAndAddLocations(S->SymbolIndex, SelectorLocs);
+    return true;
+  }
+
+  bool VisitObjCProtocolExpr(const ObjCProtocolExpr *Expr) {
+    checkDecl(Expr->getProtocol(), Expr->getProtocolIdLoc());
+    return true;
+  }
+
+  bool VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Expr) {
+    checkDecl(Expr->getDecl(), Expr->getLocation());
+    return true;
+  }
+
+  bool VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Expr) {
+    if (Expr->isClassReceiver())
+      checkDecl(Expr->getClassReceiver(), Expr->getReceiverLocation());
+    if (Expr->isImplicitProperty()) {
+      // Class properties that are explicitly defined using @property
+      // declarations are represented implicitly as there is no ivar for class
+      // properties.
+      if (const ObjCMethodDecl *Getter = Expr->getImplicitPropertyGetter()) {
+        if (Getter->isClassMethod())
+          if (const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl()) {
+            checkDecl(PD, Expr->getLocation());
+            return true;
+          }
+      }
+
+      checkDecl(Expr->getImplicitPropertyGetter(), Expr->getLocation(),
+                SymbolOccurrence::MatchingImplicitProperty);
+      // Add a manual location for a setter since a token like 'property' won't
+      // match the the name of the renamed symbol like 'setProperty'.
+      if (const auto *S = symbolForDecl(Expr->getImplicitPropertySetter()))
+        addLocation(S->SymbolIndex, Expr->getLocation(),
+                    SymbolOccurrence::MatchingImplicitProperty);
+      return true;
+    }
+    checkDecl(Expr->getExplicitProperty(), Expr->getLocation());
+    return true;
+  }
+
+  // Other visitors:
+
+  bool VisitTypeLoc(const TypeLoc Loc) {
+    TypedefTypeLoc TTL = Loc.getAs<TypedefTypeLoc>();
+    if (TTL) {
+      const auto *TND = TTL.getTypedefNameDecl();
+      if (TND->isTransparentTag()) {
+        if (const auto *Underlying = TND->getUnderlyingType()->getAsTagDecl()) {
+          checkDecl(Underlying, TTL.getNameLoc());
+          return true;
+        }
+      }
+      checkDecl(TND, TTL.getNameLoc());
+      return true;
+    }
+    TypeSpecTypeLoc TSTL = Loc.getAs<TypeSpecTypeLoc>();
+    if (TSTL) {
+      checkDecl(Loc.getType()->getAsTagDecl(), TSTL.getNameLoc());
+    }
+    if (const auto *TemplateTypeParm =
+            dyn_cast<TemplateTypeParmType>(Loc.getType())) {
+      checkDecl(TemplateTypeParm->getDecl(), Loc.getBeginLoc());
+    }
+    if (const auto *TemplateSpecType =
+            dyn_cast<TemplateSpecializationType>(Loc.getType())) {
+      checkDecl(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
+                Loc.getBeginLoc());
+    }
+    return true;
+  }
+
+  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc Loc) {
+    checkDecl(Loc.getIFaceDecl(), Loc.getNameLoc());
+    return true;
+  }
+
+  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc Loc) {
+    for (unsigned I = 0, E = Loc.getNumProtocols(); I < E; ++I)
+      checkDecl(Loc.getProtocol(I), Loc.getProtocolLoc(I));
+    return true;
+  }
+
+  bool VisitDependentSymbolReference(const NamedDecl *Symbol,
+                                     SourceLocation SymbolNameLoc) {
+    checkDecl(Symbol, SymbolNameLoc);
+    return true;
+  }
+
+  // Non-visitors:
+
+  // Namespace traversal:
+  void handleNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
+    while (NameLoc) {
+      checkDecl(NameLoc.getNestedNameSpecifier()->getAsNamespace(),
+                NameLoc.getLocalBeginLoc());
+      NameLoc = NameLoc.getPrefix();
+    }
+  }
+
+private:
+  size_t getOffsetForString(SourceLocation Loc, StringRef PrevNameString) {
+    const SourceLocation BeginLoc = Loc;
+    const SourceLocation EndLoc = Lexer::getLocForEndOfToken(
+        BeginLoc, 0, Context.getSourceManager(), Context.getLangOpts());
+    StringRef TokenName =
+        Lexer::getSourceText(CharSourceRange::getTokenRange(BeginLoc, EndLoc),
+                             Context.getSourceManager(), Context.getLangOpts());
+    return TokenName.find(PrevNameString);
+  }
+
+  void checkAndAddLocations(unsigned SymbolIndex,
+                            ArrayRef<SourceLocation> Locations,
+                            SymbolOccurrence::OccurrenceKind Kind =
+                                SymbolOccurrence::MatchingSymbol) {
+    if (Locations.size() != Operation.symbols()[SymbolIndex].Name.size())
+      return;
+
+    SmallVector<SourceLocation, 4> StringLocations;
+    for (size_t I = 0, E = Locations.size(); I != E; ++I) {
+      SourceLocation Loc = Locations[I];
+      bool IsMacroExpansion = Loc.isMacroID();
+      if (IsMacroExpansion) {
+        const SourceManager &SM = Context.getSourceManager();
+        if (SM.isMacroArgExpansion(Loc)) {
+          Loc = SM.getSpellingLoc(Loc);
+          IsMacroExpansion = false;
+        } else
+          Loc = SM.getExpansionLoc(Loc);
+      }
+      if (IsMacroExpansion) {
+        Occurrences.push_back(SymbolOccurrence(Kind, /*IsMacroExpansion=*/true,
+                                               SymbolIndex, Loc));
+        return;
+      }
+      size_t Offset =
+          getOffsetForString(Loc, Operation.symbols()[SymbolIndex].Name[I]);
+      if (Offset == StringRef::npos)
+        return;
+      StringLocations.push_back(Loc.getLocWithOffset(Offset));
+    }
+
+    Occurrences.push_back(SymbolOccurrence(Kind, /*IsMacroExpansion=*/false,
+                                           SymbolIndex, StringLocations));
+  }
+
+  /// Adds a location without checking if the name is actually there.
+  void addLocation(unsigned SymbolIndex, SourceLocation Location,
+                   SymbolOccurrence::OccurrenceKind Kind) {
+    if (1 != Operation.symbols()[SymbolIndex].Name.size())
+      return;
+    bool IsMacroExpansion = Location.isMacroID();
+    if (IsMacroExpansion) {
+      const SourceManager &SM = Context.getSourceManager();
+      if (SM.isMacroArgExpansion(Location)) {
+        Location = SM.getSpellingLoc(Location);
+        IsMacroExpansion = false;
+      } else
+        Location = SM.getExpansionLoc(Location);
+    }
+    Occurrences.push_back(
+        SymbolOccurrence(Kind, IsMacroExpansion, SymbolIndex, Location));
+  }
+
+  const SymbolOperation &Operation;
+  const ASTContext &Context;
+  std::vector<SymbolOccurrence> &Occurrences;
+};
+} // namespace
+
+std::vector<SymbolOccurrence>
+findSymbolOccurrences(const SymbolOperation &Operation, Decl *Decl) {
+  std::vector<SymbolOccurrence> Occurrences;
+  SymbolOccurrenceFinderASTVisitor Visitor(Operation, Decl->getASTContext(),
+                                           Occurrences);
+  Visitor.TraverseDecl(Decl);
+  NestedNameSpecifierLocFinder Finder(Decl->getASTContext());
+
+  for (const auto &Location : Finder.getNestedNameSpecifierLocations())
+    Visitor.handleNestedNameSpecifierLoc(Location);
+
+  return Occurrences;
+}
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/SymbolOperation.cpp b/lib/Tooling/Refactor/SymbolOperation.cpp
new file mode 100644
index 0000000..111b6c0
--- /dev/null
+++ b/lib/Tooling/Refactor/SymbolOperation.cpp
@@ -0,0 +1,210 @@
+//===--- SymbolOperation.cpp - --------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/SymbolOperation.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Tooling/Refactor/RefactoringActionFinder.h"
+
+using namespace clang;
+
+/// Return true if the given local record decl escapes the given enclosing
+/// function or block \p Ctx.
+static bool escapesEnclosingDecl(const DeclContext *Ctx, const RecordDecl *RD) {
+  QualType ReturnType;
+  bool DependentBlock = false;
+  if (const auto *FD = dyn_cast<FunctionDecl>(Ctx))
+    ReturnType = FD->getReturnType();
+  else if (const auto *BD = dyn_cast<BlockDecl>(Ctx)) {
+    ReturnType = BD->getSignatureAsWritten()->getType();
+    // Blocks that don't have an explicitly specified type (represented with a
+    // dependent type) could potentially return the record, e.g.
+    // auto block = ^ {
+    //   struct Foo { };
+    //   return Foo();
+    // };
+    if (const auto *FT = ReturnType->getAs<FunctionType>())
+      ReturnType = FT->getReturnType();
+    if (ReturnType->isDependentType())
+      DependentBlock = true;
+  } else
+    return false;
+
+  // The record can be returned from its enclosing function when the function's
+  // return type is auto.
+  //
+  // FIXME: Use a smarter heuristic that detects if the record type is
+  // actually returned from the function. Have to account for inner records,
+  // like in the example below:
+  //
+  //   auto foo() {
+  //     struct Foo { struct Bar { }; };
+  //     return Foo::Bar();
+  //   };
+  //
+  // for types that depend on the record, like in the example below:
+  //
+  //   auto foo() {
+  //     template<typename T> struct C<T> { T x; };
+  //     struct Foo { struct Bar { }; };
+  //     return C<Bar>();
+  //   }
+  //
+  // and for things like typedefs and function types as well.
+  if (!DependentBlock && !ReturnType->getContainedAutoType())
+    return false;
+
+  // Even if the enclosing function returns the local record, this record is
+  // still local if the enclosing function is inside a function/method that
+  // doesn't return this record.
+  const auto *D = cast<Decl>(Ctx);
+  if (D->isLexicallyWithinFunctionOrMethod())
+    return escapesEnclosingDecl(D->getParentFunctionOrMethod(), RD);
+
+  return true;
+}
+
+static bool escapesEnclosingDecl(const RecordDecl *RD,
+                                 const LangOptions &LangOpts) {
+  // We only care about things that escape in header files since things that
+  // escape in source files will be used only in the initial TU.
+  return LangOpts.IsHeaderFile &&
+         escapesEnclosingDecl(RD->getParentFunctionOrMethod(), RD);
+}
+
+/// Return true if the given declaration corresponds to a local symbol.
+bool clang::tooling::isLocalSymbol(const NamedDecl *FoundDecl,
+                                   const LangOptions &LangOpts) {
+  // Template parameters aren't indexed, so use local rename.
+  if (isa<TemplateTypeParmDecl>(FoundDecl) ||
+      isa<NonTypeTemplateParmDecl>(FoundDecl) ||
+      isa<TemplateTemplateParmDecl>(FoundDecl))
+    return true;
+
+  if (const auto *VD = dyn_cast<VarDecl>(FoundDecl))
+    return VD->isLocalVarDeclOrParm();
+
+  // Objective-C selector renames must be global.
+  if (isa<ObjCMethodDecl>(FoundDecl))
+    return false;
+
+  // Local declarations are defined in a function or a method, or are anonymous.
+  if (!FoundDecl->isLexicallyWithinFunctionOrMethod())
+    return false;
+
+  // A locally defined record is global when it is returned from the enclosing
+  // function because we can refer to its destructor externally.
+  if (const auto *RD = dyn_cast<CXXRecordDecl>(FoundDecl))
+    return !escapesEnclosingDecl(RD, LangOpts);
+
+  // A locally defined field is global when its record is returned from the
+  // enclosing function.
+  if (const auto *FD = dyn_cast<FieldDecl>(FoundDecl))
+    return !escapesEnclosingDecl(FD->getParent(), LangOpts);
+
+  if (const auto *MD = dyn_cast<CXXMethodDecl>(FoundDecl)) {
+    // A locally defined method is global when its record is returned from the
+    // enclosing function.
+    if (escapesEnclosingDecl(MD->getParent(), LangOpts))
+      return false;
+
+    // Method renames can be local only iff this method doesn't override
+    // a global method, for example:
+    //
+    //   void func() {
+    //     struct Foo: GlobalSuper {
+    //       // When renaming foo we should also rename GlobalSuper's foo
+    //       void foo() override;
+    //     }
+    //   }
+    //
+    // FIXME: We can try to be smarter about it and check if we override
+    // a local method, which would make this method local as well.
+    return !MD->isVirtual();
+  }
+
+  return true;
+}
+
+static const NamedDecl *
+findDeclThatRequiresImplementationTU(const NamedDecl *FoundDecl) {
+  // TODO: implement the rest.
+  if (const ObjCIvarDecl *IVarDecl = dyn_cast<ObjCIvarDecl>(FoundDecl)) {
+    // We need the implementation TU when the IVAR is declared in an @interface
+    // without an @implementation.
+    if (const auto *ID =
+            dyn_cast<ObjCInterfaceDecl>(IVarDecl->getDeclContext())) {
+      if (!ID->getImplementation())
+        return IVarDecl;
+    }
+  }
+  return nullptr;
+}
+
+namespace clang {
+namespace tooling {
+
+SymbolOperation::SymbolOperation(const NamedDecl *FoundDecl,
+                                 ASTContext &Context)
+    : IsLocal(isLocalSymbol(FoundDecl, Context.getLangOpts())) {
+  // Take the category declaration if this is a category implementation.
+  if (const auto *CategoryImplDecl =
+          dyn_cast<ObjCCategoryImplDecl>(FoundDecl)) {
+    if (const auto *CategoryDecl = CategoryImplDecl->getCategoryDecl())
+      FoundDecl = CategoryDecl;
+  }
+  // Use the property if this method is a getter/setter.
+  else if (const auto *MethodDecl = dyn_cast<ObjCMethodDecl>(FoundDecl)) {
+    if (const auto *PropertyDecl =
+            MethodDecl->getCanonicalDecl()->findPropertyDecl()) {
+      // Don't use the property if the getter/setter method has an explicitly
+      // specified name.
+      if (MethodDecl->param_size() == 0
+              ? !PropertyDecl->hasExplicitGetterName()
+              : !PropertyDecl->hasExplicitSetterName())
+        FoundDecl = PropertyDecl;
+    }
+  }
+
+  DeclThatRequiresImplementationTU =
+      findDeclThatRequiresImplementationTU(FoundDecl);
+
+  // TODO: Split into initiation that works after implementation TU is loaded.
+
+  // Find the set of symbols that this operation has to work on.
+  auto AddSymbol = [this, &Context](const NamedDecl *FoundDecl) {
+    unsigned Index = Symbols.size();
+    Symbols.push_back(rename::Symbol(FoundDecl, Index, Context.getLangOpts()));
+    for (const auto &USR : findSymbolsUSRSet(FoundDecl, Context))
+      USRToSymbol.insert(std::make_pair(USR.getKey(), Index));
+  };
+  AddSymbol(FoundDecl);
+  // Take getters, setters and ivars into account when dealing with
+  // Objective-C @property declarations.
+  if (const auto *PropertyDecl = dyn_cast<ObjCPropertyDecl>(FoundDecl)) {
+    // FIXME: findSymbolsUSRSet is called for every symbol we add, which is
+    // inefficient since we currently have to traverse the AST every time it is
+    // called. Fix this so that the AST isn't traversed more than once.
+    if (!PropertyDecl->hasExplicitGetterName()) {
+      if (const auto *Getter = PropertyDecl->getGetterMethodDecl())
+        AddSymbol(Getter);
+    }
+    if (!PropertyDecl->hasExplicitSetterName()) {
+      if (const auto *Setter = PropertyDecl->getSetterMethodDecl())
+        AddSymbol(Setter);
+    }
+  }
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/SymbolUSRFinder.cpp b/lib/Tooling/Refactor/SymbolUSRFinder.cpp
new file mode 100644
index 0000000..267f90c
--- /dev/null
+++ b/lib/Tooling/Refactor/SymbolUSRFinder.cpp
@@ -0,0 +1,206 @@
+//===--- SymbolUSRFinder.cpp - Clang refactoring library ------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief Implements methods that find the set of USRs that correspond to
+/// a symbol that's required for a refactoring operation.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Tooling/Refactor/RefactoringActionFinder.h"
+#include "clang/Tooling/Refactor/USRFinder.h"
+#include "llvm/ADT/StringRef.h"
+
+#include <vector>
+
+using namespace clang;
+using namespace clang::tooling::rename;
+
+namespace {
+
+/// \brief NamedDeclFindingConsumer delegates finding USRs of a found Decl to
+/// \c AdditionalUSRFinder. \c AdditionalUSRFinder adds USRs of ctors and dtor
+/// if the found declaration refers to a class and adds USRs of all overridden
+/// methods if the declaration refers to a virtual C++ method or an ObjC method.
+class AdditionalUSRFinder : public RecursiveASTVisitor<AdditionalUSRFinder> {
+public:
+  AdditionalUSRFinder(const Decl *FoundDecl, ASTContext &Context)
+      : FoundDecl(FoundDecl), Context(Context) {}
+
+  llvm::StringSet<> Find() {
+    llvm::StringSet<> USRSet;
+
+    // Fill OverriddenMethods and PartialSpecs storages.
+    TraverseDecl(Context.getTranslationUnitDecl());
+    if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(FoundDecl)) {
+      addUSRsOfOverridenFunctions(MethodDecl, USRSet);
+      // FIXME: Use a more efficient/optimal algorithm to find the related
+      // methods.
+      for (const auto &OverriddenMethod : OverriddenMethods) {
+        if (checkIfOverriddenFunctionAscends(OverriddenMethod, USRSet))
+          USRSet.insert(getUSRForDecl(OverriddenMethod));
+      }
+    } else if (const auto *RecordDecl = dyn_cast<CXXRecordDecl>(FoundDecl)) {
+      handleCXXRecordDecl(RecordDecl, USRSet);
+    } else if (const auto *TemplateDecl =
+                   dyn_cast<ClassTemplateDecl>(FoundDecl)) {
+      handleClassTemplateDecl(TemplateDecl, USRSet);
+    } else if (const auto *MethodDecl = dyn_cast<ObjCMethodDecl>(FoundDecl)) {
+      addUSRsOfOverriddenObjCMethods(MethodDecl, USRSet);
+      for (const auto &PotentialOverrider : PotentialObjCMethodOverridders)
+        if (checkIfPotentialObjCMethodOverriddes(PotentialOverrider, USRSet))
+          USRSet.insert(getUSRForDecl(PotentialOverrider));
+    } else {
+      USRSet.insert(getUSRForDecl(FoundDecl));
+    }
+    return USRSet;
+  }
+
+  bool VisitCXXMethodDecl(const CXXMethodDecl *MethodDecl) {
+    if (MethodDecl->isVirtual())
+      OverriddenMethods.push_back(MethodDecl);
+    return true;
+  }
+
+  bool VisitObjCMethodDecl(const ObjCMethodDecl *MethodDecl) {
+    if (const auto *FoundMethodDecl = dyn_cast<ObjCMethodDecl>(FoundDecl))
+      if (DeclarationName::compare(MethodDecl->getDeclName(),
+                                   FoundMethodDecl->getDeclName()) == 0 &&
+          MethodDecl->isOverriding())
+        PotentialObjCMethodOverridders.push_back(MethodDecl);
+    return true;
+  }
+
+  bool VisitClassTemplatePartialSpecializationDecl(
+      const ClassTemplatePartialSpecializationDecl *PartialSpec) {
+    if (!isa<ClassTemplateDecl>(FoundDecl) && !isa<CXXRecordDecl>(FoundDecl))
+      return true;
+    PartialSpecs.push_back(PartialSpec);
+    return true;
+  }
+
+private:
+  void handleCXXRecordDecl(const CXXRecordDecl *RecordDecl,
+                           llvm::StringSet<> &USRSet) {
+    const auto *RD = RecordDecl->getDefinition();
+    if (!RD) {
+      USRSet.insert(getUSRForDecl(RecordDecl));
+      return;
+    }
+    if (const auto *ClassTemplateSpecDecl =
+            dyn_cast<ClassTemplateSpecializationDecl>(RD))
+      handleClassTemplateDecl(ClassTemplateSpecDecl->getSpecializedTemplate(),
+                              USRSet);
+    addUSRsOfCtorDtors(RD, USRSet);
+  }
+
+  void handleClassTemplateDecl(const ClassTemplateDecl *TemplateDecl,
+                               llvm::StringSet<> &USRSet) {
+    for (const auto *Specialization : TemplateDecl->specializations())
+      addUSRsOfCtorDtors(Specialization, USRSet);
+
+    for (const auto *PartialSpec : PartialSpecs) {
+      if (PartialSpec->getSpecializedTemplate() == TemplateDecl)
+        addUSRsOfCtorDtors(PartialSpec, USRSet);
+    }
+    addUSRsOfCtorDtors(TemplateDecl->getTemplatedDecl(), USRSet);
+  }
+
+  void addUSRsOfCtorDtors(const CXXRecordDecl *RecordDecl,
+                          llvm::StringSet<> &USRSet) {
+    const CXXRecordDecl *RD = RecordDecl;
+    RecordDecl = RD->getDefinition();
+    if (!RecordDecl) {
+      USRSet.insert(getUSRForDecl(RD));
+      return;
+    }
+
+    for (const auto *CtorDecl : RecordDecl->ctors()) {
+      auto USR = getUSRForDecl(CtorDecl);
+      if (!USR.empty())
+        USRSet.insert(USR);
+    }
+
+    auto USR = getUSRForDecl(RecordDecl->getDestructor());
+    if (!USR.empty())
+      USRSet.insert(USR);
+    USRSet.insert(getUSRForDecl(RecordDecl));
+  }
+
+  void addUSRsOfOverridenFunctions(const CXXMethodDecl *MethodDecl,
+                                   llvm::StringSet<> &USRSet) {
+    USRSet.insert(getUSRForDecl(MethodDecl));
+    // Recursively visit each OverridenMethod.
+    for (const auto &OverriddenMethod : MethodDecl->overridden_methods())
+      addUSRsOfOverridenFunctions(OverriddenMethod, USRSet);
+  }
+
+  bool checkIfOverriddenFunctionAscends(const CXXMethodDecl *MethodDecl,
+                                        const llvm::StringSet<> &USRSet) {
+    for (const auto &OverriddenMethod : MethodDecl->overridden_methods()) {
+      if (USRSet.find(getUSRForDecl(OverriddenMethod)) != USRSet.end())
+        return true;
+      return checkIfOverriddenFunctionAscends(OverriddenMethod, USRSet);
+    }
+    return false;
+  }
+
+  /// \brief Recursively visit all the methods which the given method
+  /// declaration overrides and adds them to the USR set.
+  void addUSRsOfOverriddenObjCMethods(const ObjCMethodDecl *MethodDecl,
+                                      llvm::StringSet<> &USRSet) {
+    // Exit early if this method was already visited.
+    if (!USRSet.insert(getUSRForDecl(MethodDecl)).second)
+      return;
+    SmallVector<const ObjCMethodDecl *, 8> Overrides;
+    MethodDecl->getOverriddenMethods(Overrides);
+    for (const auto &OverriddenMethod : Overrides)
+      addUSRsOfOverriddenObjCMethods(OverriddenMethod, USRSet);
+  }
+
+  /// \brief Returns true if the given Objective-C method overrides the
+  /// found Objective-C method declaration.
+  bool checkIfPotentialObjCMethodOverriddes(const ObjCMethodDecl *MethodDecl,
+                                            const llvm::StringSet<> &USRSet) {
+    SmallVector<const ObjCMethodDecl *, 8> Overrides;
+    MethodDecl->getOverriddenMethods(Overrides);
+    for (const auto &OverriddenMethod : Overrides) {
+      if (USRSet.find(getUSRForDecl(OverriddenMethod)) != USRSet.end())
+        return true;
+      if (checkIfPotentialObjCMethodOverriddes(OverriddenMethod, USRSet))
+        return true;
+    }
+    return false;
+  }
+
+  const Decl *FoundDecl;
+  ASTContext &Context;
+  std::vector<const CXXMethodDecl *> OverriddenMethods;
+  std::vector<const ClassTemplatePartialSpecializationDecl *> PartialSpecs;
+  /// \brief An array of Objective-C methods that potentially override the
+  /// found Objective-C method declaration \p FoundDecl.
+  std::vector<const ObjCMethodDecl *> PotentialObjCMethodOverridders;
+};
+} // end anonymous namespace
+
+namespace clang {
+namespace tooling {
+
+llvm::StringSet<> findSymbolsUSRSet(const NamedDecl *FoundDecl,
+                                    ASTContext &Context) {
+  return AdditionalUSRFinder(FoundDecl, Context).Find();
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/TypeUtils.cpp b/lib/Tooling/Refactor/TypeUtils.cpp
new file mode 100644
index 0000000..c07136b
--- /dev/null
+++ b/lib/Tooling/Refactor/TypeUtils.cpp
@@ -0,0 +1,200 @@
+//===--- TypeUtils.cpp - Type helper functions ----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TypeUtils.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/NSAPI.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+
+using namespace clang;
+
+namespace {
+
+/// Returns false if a BOOL expression is found.
+class BOOLUseFinder : public RecursiveASTVisitor<BOOLUseFinder> {
+public:
+  NSAPI API;
+
+  BOOLUseFinder(const ASTContext &Context)
+      : API(const_cast<ASTContext &>(Context)) {}
+
+  bool VisitStmt(const Stmt *S) {
+    if (const auto *E = dyn_cast<Expr>(S))
+      return !API.isObjCBOOLType(E->getType());
+    return true;
+  }
+
+  static bool hasUseOfObjCBOOL(const ASTContext &Ctx, const Expr *E) {
+    return !BOOLUseFinder(Ctx).TraverseStmt(const_cast<Expr *>(E));
+  }
+};
+
+} // end anonymous namespace
+
+static QualType preferredBoolType(const Decl *FunctionLikeParentDecl,
+                                  const Expr *E, QualType T,
+                                  const PrintingPolicy &Policy,
+                                  const ASTContext &Ctx) {
+  // We want to target expressions that return either 'int' or 'bool'
+  const auto *BTy = T->getAs<BuiltinType>();
+  if (!BTy)
+    return T;
+  switch (BTy->getKind()) {
+  case BuiltinType::Int:
+  case BuiltinType::Bool:
+    // In Objective-C[++] we want to try to use 'BOOL' when the 'BOOL' typedef
+    // is defined.
+    if (Ctx.getLangOpts().ObjC1 && Ctx.getBOOLDecl()) {
+      if (Ctx.getLangOpts().CPlusPlus && FunctionLikeParentDecl) {
+        // When extracting expression from a standalone function in
+        // Objective-C++ we should use BOOL when expression uses BOOL, otherwise
+        // we should use bool.
+        if (isa<FunctionDecl>(FunctionLikeParentDecl)) {
+          if (BOOLUseFinder::hasUseOfObjCBOOL(Ctx, E))
+            return Ctx.getBOOLType();
+          return T;
+        }
+      }
+      return Ctx.getBOOLType();
+    }
+    // In C mode we want to use 'bool' instead of 'int' when the 'bool' macro
+    // is defined.
+    if (!Ctx.getLangOpts().CPlusPlus && Policy.Bool)
+      return Ctx.BoolTy;
+    break;
+  default:
+    break;
+  }
+  return T;
+}
+
+static bool isInStdNamespace(const Decl *D) {
+  const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
+  const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
+  if (!ND)
+    return false;
+
+  while (const DeclContext *Parent = ND->getParent()) {
+    if (!isa<NamespaceDecl>(Parent))
+      break;
+    ND = cast<NamespaceDecl>(Parent);
+  }
+
+  return ND->isStdNamespace();
+}
+
+static QualType desugarStdTypedef(QualType T) {
+  const auto *TT = T->getAs<TypedefType>();
+  if (!TT)
+    return QualType();
+  const TypedefNameDecl *TND = TT->getDecl();
+  if (!isInStdNamespace(TND))
+    return QualType();
+  return TT->desugar();
+}
+
+// Desugars a typedef of a typedef that are both defined in STL.
+//
+// This is used to find the right type for a c_str() call on a std::string
+// object: we want to return const char *, not const value_type *.
+static QualType desugarStdType(QualType T) {
+  QualType DesugaredType = T;
+  if (const auto *PT = T->getAs<PointerType>())
+    DesugaredType = PT->getPointeeType();
+  DesugaredType = desugarStdTypedef(DesugaredType);
+  if (DesugaredType.isNull())
+    return T;
+  if (const auto *ET = DesugaredType->getAs<ElaboratedType>())
+    DesugaredType = ET->desugar();
+  DesugaredType = desugarStdTypedef(DesugaredType);
+  if (DesugaredType.isNull())
+    return T;
+  return T.getCanonicalType();
+}
+
+// Given an operator call like std::string() + "", we would like to ensure
+// that we return std::string instead of std::basic_string.
+static QualType canonicalizeStdOperatorReturnType(const Expr *E, QualType T) {
+  const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E->IgnoreParenImpCasts());
+  if (!OCE)
+    return T;
+  if (OCE->getNumArgs() < 2 || !isInStdNamespace(OCE->getCalleeDecl()))
+    return T;
+  QualType CanonicalReturn = T.getCanonicalType();
+  if (const auto *RD = CanonicalReturn->getAsCXXRecordDecl()) {
+    if (!isInStdNamespace(RD))
+      return T;
+  } else
+    return T;
+  for (unsigned I = 0, E = OCE->getNumArgs(); I < E; ++I) {
+    const Expr *Arg = OCE->getArgs()[I];
+    QualType T = Arg->getType();
+    if (const auto *ET = dyn_cast<ElaboratedType>(T))
+      T = ET->desugar();
+    if (desugarStdTypedef(T).isNull())
+      continue;
+    QualType CanonicalArg = Arg->getType().getCanonicalType();
+    CanonicalArg.removeLocalFastQualifiers();
+    if (CanonicalArg == CanonicalReturn) {
+      QualType Result = Arg->getType();
+      Result.removeLocalFastQualifiers();
+      return Result;
+    }
+  }
+  return T;
+}
+
+namespace clang {
+namespace tooling {
+
+/// Tthe return type of the extracted function should match user's intent,
+/// e.g. we want to use bool type whenever possible.
+QualType findExpressionLexicalType(const Decl *FunctionLikeParentDecl,
+                                   const Expr *E, QualType T,
+                                   const PrintingPolicy &Policy,
+                                   const ASTContext &Ctx) {
+  // Get the correct property type.
+  if (const auto *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
+    if (PRE->isMessagingGetter()) {
+      if (PRE->isExplicitProperty()) {
+        QualType ReceiverType = PRE->getReceiverType(Ctx);
+        return PRE->getExplicitProperty()->getUsageType(ReceiverType);
+      }
+      if (const ObjCMethodDecl *M = PRE->getImplicitPropertyGetter()) {
+        if (!PRE->isObjectReceiver())
+          return M->getSendResultType(PRE->getReceiverType(Ctx));
+        const Expr *Base = PRE->getBase();
+        return M->getSendResultType(findExpressionLexicalType(
+            FunctionLikeParentDecl, Base, Base->getType(), Policy, Ctx));
+      }
+    }
+  }
+
+  // Perform STL-specific type corrections.
+  if (Ctx.getLangOpts().CPlusPlus) {
+    T = desugarStdType(T);
+    T = canonicalizeStdOperatorReturnType(E, T);
+  }
+
+  // The bool type adjustment is required only in C or Objective-C[++].
+  if (Ctx.getLangOpts().CPlusPlus && !Ctx.getLangOpts().ObjC1)
+    return T;
+  E = E->IgnoreParenImpCasts();
+  if (const auto *BinOp = dyn_cast<BinaryOperator>(E)) {
+    if (BinOp->isLogicalOp() || BinOp->isComparisonOp())
+      return preferredBoolType(FunctionLikeParentDecl, E, T, Policy, Ctx);
+  } else if (const auto *UnOp = dyn_cast<UnaryOperator>(E)) {
+    if (UnOp->getOpcode() == UO_LNot)
+      return preferredBoolType(FunctionLikeParentDecl, E, T, Policy, Ctx);
+  }
+  return T;
+}
+
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactor/TypeUtils.h b/lib/Tooling/Refactor/TypeUtils.h
new file mode 100644
index 0000000..8d575e8
--- /dev/null
+++ b/lib/Tooling/Refactor/TypeUtils.h
@@ -0,0 +1,35 @@
+//===--- TypeUtils.h - Type helper functions ------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_TOOLING_REFACTOR_TYPE_UTILS_H
+#define LLVM_CLANG_LIB_TOOLING_REFACTOR_TYPE_UTILS_H
+
+#include "clang/AST/Type.h"
+
+namespace clang {
+
+class Decl;
+
+namespace tooling {
+
+/// \brief Find the most lexically appropriate type that can be used to describe
+/// the return type of the given expression \p E.
+///
+/// When extracting code, we want to produce a function that returns a type
+/// that matches the user's intent. This function can be used to find such a
+/// type.
+QualType findExpressionLexicalType(const Decl *FunctionLikeParentDecl,
+                                   const Expr *E, QualType T,
+                                   const PrintingPolicy &Policy,
+                                   const ASTContext &Ctx);
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_LIB_TOOLING_REFACTOR_TYPE_UTILS_H
diff --git a/lib/Tooling/Refactor/USRFinder.cpp b/lib/Tooling/Refactor/USRFinder.cpp
new file mode 100644
index 0000000..6959490
--- /dev/null
+++ b/lib/Tooling/Refactor/USRFinder.cpp
@@ -0,0 +1,706 @@
+//===--- USRFinder.cpp - Clang refactoring library ------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file Implements a recursive AST visitor that finds the USR of a symbol at a
+/// point.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/Refactor/USRFinder.h"
+#include "SourceLocationUtilities.h"
+#include "clang/AST/AST.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DependentASTVisitor.h"
+#include "clang/Index/USRGeneration.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Core/RefactoringDiagnostic.h"
+#include "llvm/ADT/SmallVector.h"
+#include <functional>
+
+using namespace llvm;
+
+namespace clang {
+namespace tooling {
+namespace rename {
+
+typedef std::function<bool(const NamedDecl *, SourceLocation, SourceLocation)>
+    OccurrenceCheckerType;
+
+// NamedDeclFindingASTVisitor recursively visits each AST node to find the
+// symbol underneath the cursor.
+// FIXME: move to seperate .h/.cc file if this gets too large.
+namespace {
+class NamedDeclFindingASTVisitor
+    : public DependentASTVisitor<NamedDeclFindingASTVisitor> {
+public:
+  // \brief Finds the NamedDecl at a point in the source.
+  // \param Point the location in the source to search for the NamedDecl.
+  explicit NamedDeclFindingASTVisitor(
+      const OccurrenceCheckerType &OccurrenceChecker, const ASTContext &Context)
+      : Result(nullptr), OccurrenceChecker(OccurrenceChecker),
+        Context(Context) {}
+
+  // Declaration visitors:
+
+  // \brief Checks if the point falls within the NameDecl. This covers every
+  // declaration of a named entity that we may come across. Usually, just
+  // checking if the point lies within the length of the name of the declaration
+  // and the start location is sufficient.
+  bool VisitNamedDecl(const NamedDecl *Decl) {
+    return dyn_cast<CXXConversionDecl>(Decl)
+               ? true
+               : checkOccurrence(Decl, Decl->getLocation(),
+                                 Decl->getNameAsString().length());
+  }
+
+  bool WalkUpFromTypedefNameDecl(const TypedefNameDecl *D) {
+    // Don't visit the NamedDecl for TypedefNameDecl.
+    return VisitTypedefNamedDecl(D);
+  }
+
+  bool VisitTypedefNamedDecl(const TypedefNameDecl *D) {
+    if (D->isTransparentTag()) {
+      if (const auto *Underlying = D->getUnderlyingType()->getAsTagDecl())
+        return checkOccurrence(Underlying, D->getLocation(),
+                               D->getNameAsString().size());
+    }
+    return VisitNamedDecl(D);
+  }
+
+  bool WalkUpFromUsingDecl(const UsingDecl *D) {
+    // Don't visit the NamedDecl for UsingDecl.
+    return VisitUsingDecl(D);
+  }
+
+  bool VisitUsingDecl(const UsingDecl *D) {
+    for (const auto *Shadow : D->shadows()) {
+      // Currently we always find the first declaration, but is this the right
+      // behaviour?
+      const NamedDecl *UD = Shadow->getUnderlyingDecl();
+      if (UD->isImplicit() || UD == D)
+        continue;
+      if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(UD)) {
+        UD = FTD->getTemplatedDecl();
+        if (!UD)
+          continue;
+      }
+      if (!checkOccurrence(UD, D->getLocation()))
+        return false;
+    }
+    return true;
+  }
+
+  bool WalkUpFromUsingDirectiveDecl(const UsingDirectiveDecl *D) {
+    // Don't visit the NamedDecl for UsingDirectiveDecl.
+    return VisitUsingDirectiveDecl(D);
+  }
+
+  bool VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
+    return checkOccurrence(D->getNominatedNamespaceAsWritten(),
+                           D->getLocation());
+  }
+
+  bool WalkUpFromUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
+    // Don't visit the NamedDecl for UnresolvedUsingValueDecl.
+    // FIXME: Can we try to lookup the name?
+    return true;
+  }
+
+  bool
+  WalkUpFromUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
+    // Don't visit the NamedDecl for UnresolvedUsingTypenameDecl.
+    // FIXME: Can we try to lookup the name?
+    return true;
+  }
+
+  bool WalkUpFromObjCMethodDecl(const ObjCMethodDecl *Decl) {
+    // Don't visit the NamedDecl for Objective-C methods.
+    return VisitObjCMethodDecl(Decl);
+  }
+
+  bool VisitObjCMethodDecl(const ObjCMethodDecl *Decl) {
+    // Check all of the selector source ranges.
+    for (unsigned I = 0, E = Decl->getNumSelectorLocs(); I != E; ++I) {
+      SourceLocation Loc = Decl->getSelectorLoc(I);
+      if (!checkOccurrence(Decl, Loc,
+                           Loc.getLocWithOffset(
+                               Decl->getSelector().getNameForSlot(I).size())))
+        return false;
+    }
+    return true;
+  }
+
+  bool VisitObjCProtocolList(const ObjCProtocolList &Protocols) {
+    for (unsigned I = 0, E = Protocols.size(); I != E; ++I) {
+      if (!checkOccurrence(Protocols[I], Protocols.loc_begin()[I]))
+        return false;
+    }
+    return true;
+  }
+
+  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *Decl) {
+    if (!Decl->hasDefinition())
+      return true;
+    return VisitObjCProtocolList(Decl->getReferencedProtocols());
+  }
+
+  bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl) {
+    if (!Decl->hasDefinition())
+      return true;
+    return VisitObjCProtocolList(Decl->getReferencedProtocols());
+  }
+
+  bool WalkUpFromObjCCategoryDecl(const ObjCCategoryDecl *Decl) {
+    // Don't visit the NamedDecl for Objective-C categories because the location
+    // of the name refers to the interface declaration.
+    return VisitObjCCategoryDecl(Decl);
+  }
+
+  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl) {
+    if (!checkOccurrence(Decl, Decl->getCategoryNameLoc()))
+      return false;
+    if (const auto *Class = Decl->getClassInterface()) {
+      // The location of the class name is the location of the declaration.
+      if (!checkOccurrence(Class, Decl->getLocation()))
+        return false;
+    }
+    return VisitObjCProtocolList(Decl->getReferencedProtocols());
+  }
+
+  bool WalkUpFromObjCCategoryImplDecl(const ObjCCategoryImplDecl *Decl) {
+    // Don't visit the NamedDecl for Objective-C categories because the location
+    // of the name refers to the interface declaration.
+    return VisitObjCCategoryImplDecl(Decl);
+  }
+
+  bool VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *Decl) {
+    if (!checkOccurrence(Decl, Decl->getCategoryNameLoc()))
+      return false;
+    if (const auto *Class = Decl->getClassInterface()) {
+      // The location of the class name is the location of the declaration.
+      if (!checkOccurrence(Class, Decl->getLocation()))
+        return false;
+    }
+    return true;
+  }
+
+  bool VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *Decl) {
+    return checkOccurrence(Decl->getClassInterface(),
+                           Decl->getClassInterfaceLoc());
+  }
+
+  bool WalkUpFromObjCIvarDecl(ObjCIvarDecl *Decl) {
+    // Don't visit the NamedDecl for automatically synthesized ivars as the
+    // implicit ivars have the same location as the property declarations, and
+    // we want to find the property declarations.
+    if (Decl->getSynthesize())
+      return true;
+    return RecursiveASTVisitor::WalkUpFromObjCIvarDecl(Decl);
+  }
+
+  bool VisitObjCPropertyDecl(const ObjCPropertyDecl *Decl) {
+    if (Decl->hasExplicitGetterName()) {
+      if (const auto *Getter = Decl->getGetterMethodDecl())
+        if (!checkOccurrence(Getter, Decl->getGetterNameLoc(),
+                             Decl->getGetterName().getNameForSlot(0).size()))
+          return false;
+    }
+    if (Decl->hasExplicitSetterName()) {
+      if (const auto *Setter = Decl->getSetterMethodDecl())
+        return checkOccurrence(Setter, Decl->getSetterNameLoc(),
+                               Decl->getSetterName().getNameForSlot(0).size());
+    }
+    return true;
+  }
+
+  bool VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *Decl) {
+    if (!checkOccurrence(Decl->getPropertyDecl(), Decl->getLocation()))
+      return false;
+    if (Decl->isIvarNameSpecified())
+      return checkOccurrence(Decl->getPropertyIvarDecl(),
+                             Decl->getPropertyIvarDeclLoc());
+    return true;
+  }
+
+  // Expression visitors:
+
+  bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
+    const NamedDecl *Decl = Expr->getFoundDecl();
+    return checkOccurrence(Decl, Expr->getLocation(),
+                           Decl->getNameAsString().length());
+  }
+
+  bool VisitMemberExpr(const MemberExpr *Expr) {
+    const NamedDecl *Decl = Expr->getFoundDecl().getDecl();
+    return checkOccurrence(Decl, Expr->getMemberLoc(),
+                           Decl->getNameAsString().length());
+  }
+
+  bool VisitObjCMessageExpr(const ObjCMessageExpr *Expr) {
+    const ObjCMethodDecl *Decl = Expr->getMethodDecl();
+    if (Decl == nullptr)
+      return true;
+
+    // Check all of the selector source ranges.
+    for (unsigned I = 0, E = Expr->getNumSelectorLocs(); I != E; ++I) {
+      SourceLocation Loc = Expr->getSelectorLoc(I);
+      if (!checkOccurrence(Decl, Loc,
+                           Loc.getLocWithOffset(
+                               Decl->getSelector().getNameForSlot(I).size())))
+        return false;
+    }
+    return true;
+  }
+
+  bool VisitObjCProtocolExpr(const ObjCProtocolExpr *Expr) {
+    return checkOccurrence(Expr->getProtocol(), Expr->getProtocolIdLoc());
+  }
+
+  bool VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Expr) {
+    return checkOccurrence(Expr->getDecl(), Expr->getLocation());
+  }
+
+  bool VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Expr) {
+    if (Expr->isClassReceiver())
+      checkOccurrence(Expr->getClassReceiver(), Expr->getReceiverLocation());
+    if (Expr->isImplicitProperty()) {
+      // Class properties that are explicitly defined using @property
+      // declarations are represented implicitly as there is no ivar for class
+      // properties.
+      if (const ObjCMethodDecl *Getter = Expr->getImplicitPropertyGetter()) {
+        if (Getter->isClassMethod()) {
+          if (const auto *PD = Getter->getCanonicalDecl()->findPropertyDecl())
+            return checkOccurrence(PD, Expr->getLocation());
+        }
+      }
+
+      if (Expr->isMessagingGetter()) {
+        if (const ObjCMethodDecl *Getter = Expr->getImplicitPropertyGetter())
+          return checkOccurrence(Getter, Expr->getLocation());
+      } else if (const ObjCMethodDecl *Setter =
+                     Expr->getImplicitPropertySetter()) {
+        return checkOccurrence(Setter, Expr->getLocation());
+      }
+
+      return true;
+    }
+    return checkOccurrence(Expr->getExplicitProperty(), Expr->getLocation());
+  }
+
+  // Other visitors:
+
+  bool VisitTypeLoc(const TypeLoc Loc) {
+    const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
+    const SourceLocation TypeEndLoc = Lexer::getLocForEndOfToken(
+        TypeBeginLoc, 0, Context.getSourceManager(), Context.getLangOpts());
+    if (const auto *TemplateTypeParm =
+            dyn_cast<TemplateTypeParmType>(Loc.getType()))
+      return checkOccurrence(TemplateTypeParm->getDecl(), TypeBeginLoc,
+                             TypeEndLoc);
+    if (const auto *TemplateSpecType =
+            dyn_cast<TemplateSpecializationType>(Loc.getType())) {
+      return checkOccurrence(
+          TemplateSpecType->getTemplateName().getAsTemplateDecl(), TypeBeginLoc,
+          TypeEndLoc);
+    }
+    TypedefTypeLoc TTL = Loc.getAs<TypedefTypeLoc>();
+    if (TTL) {
+      const auto *TND = TTL.getTypedefNameDecl();
+      if (TND->isTransparentTag()) {
+        if (const auto *Underlying = TND->getUnderlyingType()->getAsTagDecl())
+          return checkOccurrence(Underlying, TTL.getNameLoc());
+      }
+      return checkOccurrence(TND, TTL.getNameLoc());
+    }
+    TypeSpecTypeLoc TSTL = Loc.getAs<TypeSpecTypeLoc>();
+    if (TSTL) {
+      return checkOccurrence(Loc.getType()->getAsTagDecl(), TSTL.getNameLoc());
+    }
+    return true;
+  }
+
+  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc Loc) {
+    return checkOccurrence(Loc.getIFaceDecl(), Loc.getNameLoc());
+  }
+
+  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc Loc) {
+    for (unsigned I = 0, E = Loc.getNumProtocols(); I < E; ++I) {
+      if (!checkOccurrence(Loc.getProtocol(I), Loc.getProtocolLoc(I)))
+        return false;
+    }
+    return true;
+  }
+
+  bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
+    for (const auto *Initializer : ConstructorDecl->inits()) {
+      // Ignore implicit initializers.
+      if (!Initializer->isWritten())
+        continue;
+      if (const clang::FieldDecl *FieldDecl = Initializer->getMember()) {
+        const SourceLocation InitBeginLoc = Initializer->getSourceLocation(),
+                             InitEndLoc = Lexer::getLocForEndOfToken(
+                                 InitBeginLoc, 0, Context.getSourceManager(),
+                                 Context.getLangOpts());
+        if (!checkOccurrence(FieldDecl, InitBeginLoc, InitEndLoc))
+          return false;
+      }
+    }
+    return true;
+  }
+
+  bool VisitDependentSymbolReference(const NamedDecl *Symbol,
+                                     SourceLocation SymbolNameLoc) {
+    return checkOccurrence(Symbol, SymbolNameLoc);
+  }
+
+  // Other:
+
+  const NamedDecl *getNamedDecl() { return Result; }
+
+  bool isDone() const { return Result; }
+
+  // \brief Determines if a namespace qualifier contains the point.
+  // \returns false on success and sets Result.
+  void handleNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
+    while (NameLoc) {
+      const NamespaceDecl *Decl =
+          NameLoc.getNestedNameSpecifier()->getAsNamespace();
+      checkOccurrence(Decl, NameLoc.getLocalBeginLoc(),
+                      NameLoc.getLocalEndLoc());
+      NameLoc = NameLoc.getPrefix();
+    }
+  }
+
+private:
+  /// \brief Sets Result to \p Decl if the occurrence checker returns true.
+  ///
+  /// \returns false on success.
+  bool checkRange(const NamedDecl *Decl, SourceLocation Start,
+                  SourceLocation End) {
+    assert(!Start.isMacroID() && !End.isMacroID() && "Macro location?");
+    if (!Decl)
+      return true;
+    if (isa<ImplicitParamDecl>(Decl))
+      return true;
+    if (const auto *FD = dyn_cast<FunctionDecl>(Decl)) {
+      // Don't match operators.
+      if (FD->isOverloadedOperator())
+        return true;
+    }
+    if (!OccurrenceChecker(Decl, Start, End))
+      return true;
+    Result = Decl;
+    return false;
+  }
+
+  /// Checks if the given declaration is valid, and if it is, sets Result to
+  /// \p Decl if the occurrence checker returns true.
+  ///
+  /// \returns false if the point of interest is inside the range that
+  /// corresponds the occurrence of this declaration.
+  bool checkOccurrence(const NamedDecl *Decl, SourceLocation Loc) {
+    if (!Decl)
+      return true;
+    return checkOccurrence(Decl, Loc, Decl->getNameAsString().size());
+  }
+
+  /// \brief Sets Result to \p Decl if the occurrence checker returns true.
+  ///
+  /// \returns false on success.
+  bool checkOccurrence(const NamedDecl *Decl, SourceLocation Loc,
+                       unsigned Length) {
+    if (Loc.isMacroID()) {
+      const SourceManager &SM = Context.getSourceManager();
+      if (SM.isMacroArgExpansion(Loc))
+        Loc = SM.getSpellingLoc(Loc);
+      else
+        return true;
+    }
+
+    return Length == 0 ||
+           checkRange(Decl, Loc, Loc.getLocWithOffset(Length - 1));
+  }
+
+  bool checkOccurrence(const NamedDecl *ND, SourceLocation Start,
+                       SourceLocation End) {
+    const SourceManager &SM = Context.getSourceManager();
+    if (Start.isMacroID()) {
+      if (SM.isMacroArgExpansion(Start))
+        Start = SM.getSpellingLoc(Start);
+      else
+        return true;
+    }
+    if (End.isMacroID()) {
+      if (SM.isMacroArgExpansion(End))
+        End = SM.getSpellingLoc(End);
+      else
+        return true;
+    }
+    return checkRange(ND, Start, End);
+  }
+
+  const NamedDecl *Result;
+  const OccurrenceCheckerType &OccurrenceChecker;
+  const ASTContext &Context;
+};
+
+} // namespace
+
+static const ExternalSourceSymbolAttr *getExternalSymAttr(const Decl *D) {
+  if (const auto *A = D->getAttr<ExternalSourceSymbolAttr>())
+    return A;
+  if (const auto *DCD = dyn_cast<Decl>(D->getDeclContext())) {
+    if (const auto *A = DCD->getAttr<ExternalSourceSymbolAttr>())
+      return A;
+  }
+  return nullptr;
+}
+
+static bool overridesSystemMethod(const ObjCMethodDecl *MD,
+                                  const SourceManager &SM) {
+  SmallVector<const ObjCMethodDecl *, 8> Overrides;
+  MD->getOverriddenMethods(Overrides);
+  for (const auto *Override : Overrides) {
+    SourceLocation Loc = Override->getLocStart();
+    if (Loc.isValid()) {
+      if (SM.getFileCharacteristic(Loc) != SrcMgr::C_User)
+        return true;
+    }
+    if (overridesSystemMethod(Override, SM))
+      return true;
+  }
+  return false;
+}
+
+// TODO: Share with the indexer?
+static bool isTemplateImplicitInstantiation(const Decl *D) {
+  TemplateSpecializationKind TKind = TSK_Undeclared;
+  if (const ClassTemplateSpecializationDecl *SD =
+          dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+    TKind = SD->getSpecializationKind();
+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    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:
+  case TSK_ExplicitSpecialization:
+    return false;
+  case TSK_ImplicitInstantiation:
+  case TSK_ExplicitInstantiationDeclaration:
+  case TSK_ExplicitInstantiationDefinition:
+    return true;
+  }
+  llvm_unreachable("invalid TemplateSpecializationKind");
+}
+
+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 NamedDecl *
+adjustTemplateImplicitInstantiation(const NamedDecl *D) {
+  if (const ClassTemplateSpecializationDecl *SD =
+          dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+    return SD->getTemplateInstantiationPattern();
+  } else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    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 D;
+}
+
+const NamedDecl *getNamedDeclAt(const ASTContext &Context,
+                                SourceLocation Point) {
+  if (Point.isMacroID())
+    Point = Context.getSourceManager().getSpellingLoc(Point);
+  // FIXME: If point is in a system header, return early here.
+
+  OccurrenceCheckerType PointChecker = [Point, &Context](
+      const NamedDecl *Decl, SourceLocation Start, SourceLocation End) -> bool {
+    return Start.isValid() && Start.isFileID() && End.isValid() &&
+           End.isFileID() &&
+           isPointWithin(Point, Start, End, Context.getSourceManager());
+  };
+  NamedDeclFindingASTVisitor Visitor(PointChecker, Context);
+
+  // We only want to search the decls that exist in the same file as the point.
+  FileID InitiationFile = Context.getSourceManager().getFileID(Point);
+  for (auto *CurrDecl : Context.getTranslationUnitDecl()->decls()) {
+    const SourceRange DeclRange = CurrDecl->getSourceRange();
+    SourceLocation FileLoc;
+    if (DeclRange.getBegin().isMacroID() && !DeclRange.getEnd().isMacroID())
+      FileLoc = DeclRange.getEnd();
+    else
+      FileLoc = Context.getSourceManager().getSpellingLoc(DeclRange.getBegin());
+    // FIXME: Add test.
+    if (Context.getSourceManager().getFileID(FileLoc) == InitiationFile)
+      Visitor.TraverseDecl(CurrDecl);
+    if (Visitor.isDone())
+      break;
+  }
+
+  if (!Visitor.isDone()) {
+    NestedNameSpecifierLocFinder Finder(const_cast<ASTContext &>(Context));
+    for (const auto &Location : Finder.getNestedNameSpecifierLocations()) {
+      Visitor.handleNestedNameSpecifierLoc(Location);
+      if (Visitor.isDone())
+        break;
+    }
+  }
+
+  const auto Diag = [&](unsigned DiagID) -> DiagnosticBuilder {
+    return Context.getDiagnostics().Report(Point, DiagID);
+  };
+  const auto *ND = Visitor.getNamedDecl();
+  if (!ND)
+    return nullptr;
+
+  // Canonicalize the found declaration.
+  //
+  // If FoundDecl is a constructor or destructor, we want to instead take
+  // the Decl of the corresponding class.
+  if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(ND))
+    ND = CtorDecl->getParent();
+  else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(ND))
+    ND = DtorDecl->getParent();
+
+  if (isTemplateImplicitInstantiation(ND))
+    ND = adjustTemplateImplicitInstantiation(ND);
+
+  // Builtins can't be renamed.
+  if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
+    if (FD->getBuiltinID()) {
+      Diag(diag::err_rename_builtin_function) << ND->getDeclName();
+      return nullptr;
+    }
+  }
+  // Declarations with invalid locations are probably implicit.
+  if (ND->getLocStart().isInvalid())
+    return nullptr;
+  // Declarations in system headers can't be renamed.
+  auto CheckSystemLoc = [&](SourceLocation Loc) -> bool {
+    if (Context.getSourceManager().getFileCharacteristic(Loc) !=
+        SrcMgr::C_User) {
+      Diag(diag::err_rename_sys_header) << ND->getDeclName();
+      return true;
+    }
+    return false;
+  };
+  if (CheckSystemLoc(ND->getLocStart()))
+    return nullptr;
+  if (const auto *TD = dyn_cast<TypedefNameDecl>(ND)) {
+    if (const TypedefNameDecl *CTD = TD->getCanonicalDecl()) {
+      if (CheckSystemLoc(CTD->getLocStart()))
+        return nullptr;
+    }
+  } else if (const auto *TD = dyn_cast<TagDecl>(ND)) {
+    if (const TagDecl *CTD = TD->getCanonicalDecl()) {
+      if (CheckSystemLoc(CTD->getLocStart()))
+        return nullptr;
+    }
+  } else if (const auto *FD = dyn_cast<FunctionDecl>(ND)) {
+    if (const FunctionDecl *CFD = FD->getCanonicalDecl()) {
+      if (CheckSystemLoc(CFD->getLocStart()))
+        return nullptr;
+    }
+  } else if (const auto *VD = dyn_cast<VarDecl>(ND)) {
+    if (const VarDecl *CVD = VD->getCanonicalDecl()) {
+      if (CheckSystemLoc(CVD->getLocStart()))
+        return nullptr;
+    }
+  }
+  // Declarations from other languages can't be renamed.
+  if (const ExternalSourceSymbolAttr *ESSA = getExternalSymAttr(ND)) {
+    Diag(diag::err_rename_external_source_symbol) << ND->getDeclName()
+                                                  << ESSA->getLanguage();
+    return nullptr;
+  }
+  // Methods that override methods from system headers can't be renamed.
+  if (const auto *MD = dyn_cast<ObjCMethodDecl>(ND)) {
+    if (overridesSystemMethod(MD, Context.getSourceManager())) {
+      Diag(diag::err_method_rename_override_sys_framework) << ND->getDeclName();
+      return nullptr;
+    }
+  }
+  return ND;
+}
+
+const NamedDecl *getNamedDeclWithUSR(const ASTContext &Context, StringRef USR) {
+  // TODO: Remove in favour of the new converter.
+  OccurrenceCheckerType USRChecker =
+      [USR](const NamedDecl *Decl, SourceLocation Start, SourceLocation End) {
+        return USR == getUSRForDecl(Decl);
+      };
+  NamedDeclFindingASTVisitor Visitor(USRChecker, Context);
+
+  for (auto *CurrDecl : Context.getTranslationUnitDecl()->decls()) {
+    Visitor.TraverseDecl(CurrDecl);
+    if (Visitor.isDone())
+      break;
+  }
+
+  // Don't need to visit nested name specifiers as they refer to previously
+  // declared declarations that we've already seen.
+  return Visitor.getNamedDecl();
+}
+
+std::string getUSRForDecl(const Decl *Decl) {
+  llvm::SmallVector<char, 128> Buff;
+
+  // FIXME: Add test for the nullptr case.
+  if (Decl == nullptr || index::generateUSRForDecl(Decl, Buff))
+    return "";
+
+  return std::string(Buff.data(), Buff.size());
+}
+
+} // end namespace rename
+} // end namespace tooling
+} // end namespace clang
diff --git a/lib/Tooling/Refactoring/CMakeLists.txt b/lib/Tooling/Refactoring/CMakeLists.txt
index 288582f..68c3004 100644
--- a/lib/Tooling/Refactoring/CMakeLists.txt
+++ b/lib/Tooling/Refactoring/CMakeLists.txt
@@ -3,7 +3,7 @@
   Support
   )
 
-add_clang_library(clangToolingRefactor
+add_clang_library(clangToolingRefactoring
   AtomicChange.cpp
   Rename/RenamingAction.cpp
   Rename/USRFinder.cpp
diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt
index 27cb83a..470f190 100644
--- a/runtime/CMakeLists.txt
+++ b/runtime/CMakeLists.txt
@@ -108,7 +108,7 @@
                     USES_TERMINAL)
 
   # Add top-level targets that build specific compiler-rt runtimes.
-  set(COMPILER_RT_RUNTIMES asan builtins dfsan lsan msan profile tsan ubsan)
+  set(COMPILER_RT_RUNTIMES asan builtins dfsan lsan msan profile tsan ubsan ubsan-minimal)
   foreach(runtime ${COMPILER_RT_RUNTIMES})
     get_ext_project_build_command(build_runtime_cmd ${runtime})
     add_custom_target(${runtime}
@@ -125,7 +125,7 @@
 
     # Add top-level targets for various compiler-rt test suites.
     set(COMPILER_RT_TEST_SUITES check-asan check-asan-dynamic check-dfsan
-      check-lsan check-msan check-sanitizer check-tsan check-ubsan
+      check-lsan check-msan check-sanitizer check-tsan check-ubsan check-ubsan-minimal
       check-profile check-cfi check-cfi-and-supported check-safestack)
     foreach(test_suite ${COMPILER_RT_TEST_SUITES})
       get_ext_project_build_command(run_test_suite ${test_suite})
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..572c714
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.apinotes
@@ -0,0 +1,156 @@
+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
+Functions:
+  - Name: unversionedRenameDUMP
+    SwiftName: 'unversionedRename_NOTES()'
+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
+Typedefs:
+  - Name: MultiVersionedTypedef34Notes
+    SwiftName: MultiVersionedTypedef34Notes_NEW
+  - Name: MultiVersionedTypedef345Notes
+    SwiftName: MultiVersionedTypedef345Notes_NEW
+  - Name: MultiVersionedTypedef4Notes
+    SwiftName: MultiVersionedTypedef4Notes_NEW
+  - Name: MultiVersionedTypedef45Notes
+    SwiftName: MultiVersionedTypedef45Notes_NEW
+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
+      - Name: MultiVersionedTypedef34
+        SwiftName: MultiVersionedTypedef34_3
+      - Name: MultiVersionedTypedef34Header
+        SwiftName: MultiVersionedTypedef34Header_3
+      - Name: MultiVersionedTypedef34Notes
+        SwiftName: MultiVersionedTypedef34Notes_3
+      - Name: MultiVersionedTypedef345
+        SwiftName: MultiVersionedTypedef345_3
+      - Name: MultiVersionedTypedef345Header
+        SwiftName: MultiVersionedTypedef345Header_3
+      - Name: MultiVersionedTypedef345Notes
+        SwiftName: MultiVersionedTypedef345Notes_3
+  - Version: 5
+    Typedefs:
+      - Name: MultiVersionedTypedef345
+        SwiftName: MultiVersionedTypedef345_5
+      - Name: MultiVersionedTypedef345Header
+        SwiftName: MultiVersionedTypedef345Header_5
+      - Name: MultiVersionedTypedef345Notes
+        SwiftName: MultiVersionedTypedef345Notes_5
+      - Name: MultiVersionedTypedef45
+        SwiftName: MultiVersionedTypedef45_5
+      - Name: MultiVersionedTypedef45Header
+        SwiftName: MultiVersionedTypedef45Header_5
+      - Name: MultiVersionedTypedef45Notes
+        SwiftName: MultiVersionedTypedef45Notes_5
+  - Version: 4 # Versions are deliberately ordered as "3, 5, 4" to catch bugs.
+    Classes:
+      - Name: Swift4RenamedDUMP
+        SwiftName: SpecialSwift4Name
+    Typedefs:
+      - Name: MultiVersionedTypedef34
+        SwiftName: MultiVersionedTypedef34_4
+      - Name: MultiVersionedTypedef34Header
+        SwiftName: MultiVersionedTypedef34Header_4
+      - Name: MultiVersionedTypedef34Notes
+        SwiftName: MultiVersionedTypedef34Notes_4
+      - Name: MultiVersionedTypedef345
+        SwiftName: MultiVersionedTypedef345_4
+      - Name: MultiVersionedTypedef345Header
+        SwiftName: MultiVersionedTypedef345Header_4
+      - Name: MultiVersionedTypedef345Notes
+        SwiftName: MultiVersionedTypedef345Notes_4
+      - Name: MultiVersionedTypedef4
+        SwiftName: MultiVersionedTypedef4_4
+      - Name: MultiVersionedTypedef4Header
+        SwiftName: MultiVersionedTypedef4Header_4
+      - Name: MultiVersionedTypedef4Notes
+        SwiftName: MultiVersionedTypedef4Notes_4
+      - Name: MultiVersionedTypedef45
+        SwiftName: MultiVersionedTypedef45_4
+      - Name: MultiVersionedTypedef45Header
+        SwiftName: MultiVersionedTypedef45Header_4
+      - Name: MultiVersionedTypedef45Notes
+        SwiftName: MultiVersionedTypedef45Notes_4
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..9ce9563
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/VersionedKit.framework/Headers/VersionedKit.h
@@ -0,0 +1,137 @@
+void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(x:y:)")));
+
+void unversionedRenameDUMP(void) __attribute__((swift_name("unversionedRename_HEADER()")));
+
+void acceptClosure(void (^ __attribute__((noescape)) block)(void));
+
+void privateFunc(void) __attribute__((swift_private));
+
+typedef double MyDoubleWrapper __attribute__((swift_wrapper(struct)));
+
+#if __OBJC__
+@class NSString;
+
+extern NSString *MyErrorDomain;
+
+enum __attribute__((ns_error_domain(MyErrorDomain))) MyErrorCode {
+  MyErrorCodeFailed = 1
+};
+
+__attribute__((swift_bridge("MyValueType")))
+@interface MyReferenceType
+@end
+
+@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
+
+@interface Swift4RenamedDUMP
+@end
+
+#endif
+
+
+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)));
+
+
+typedef int MultiVersionedTypedef4;
+typedef int MultiVersionedTypedef4Notes;
+typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_NEW")));
+
+typedef int MultiVersionedTypedef34;
+typedef int MultiVersionedTypedef34Notes;
+typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_NEW")));
+
+typedef int MultiVersionedTypedef45;
+typedef int MultiVersionedTypedef45Notes;
+typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_NEW")));
+
+typedef int MultiVersionedTypedef345;
+typedef int MultiVersionedTypedef345Notes;
+typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_NEW")));
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..7231eb4
--- /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 -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..ee33ff7
--- /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 -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/module-cache.m b/test/APINotes/module-cache.m
new file mode 100644
index 0000000..19d6a27
--- /dev/null
+++ b/test/APINotes/module-cache.m
@@ -0,0 +1,100 @@
+// RUN: rm -rf %t
+
+// Set up directories
+// RUN: mkdir -p %t/APINotes
+// RUN: cp %S/Inputs/APINotes/SomeOtherKit.apinotes %t/APINotes/SomeOtherKit.apinotes
+// RUN: mkdir -p %t/Frameworks
+// RUN: cp -r %S/Inputs/Frameworks/SomeOtherKit.framework %t/Frameworks
+
+// 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  -F %t/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  -F %t/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
+
+// Add a blank line to the header to force the module to rebuild, without
+// (yet) changing API notes.
+// RUN: echo >> %t/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.h
+// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes  -F %t/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
+
+// Change the API notes file, after the module has rebuilt once.
+// 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  -F %t/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  -F %t/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  -F %t/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  -F %t/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  -F %t/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  -F %t/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..e07fc2e
--- /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 -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..65c9c2c
--- /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  -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-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..24b317c
--- /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  -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..0b3d244
--- /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  -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  -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 {{.+}} Implicit 3.0 IsReplacedByActive{{$}}
+// 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 {{.+}} Implicit 3.0 IsReplacedByActive{{$}}
+// 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..aa2f21a
--- /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  -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  -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  -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..a0f728b
--- /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  -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-multi.c b/test/APINotes/versioned-multi.c
new file mode 100644
index 0000000..48c51fd
--- /dev/null
+++ b/test/APINotes/versioned-multi.c
@@ -0,0 +1,69 @@
+// 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 -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
+
+// Build and check the various versions.
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Versioned3 -fdisable-module-hash -fapinotes-modules -fapinotes-swift-version=3 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: %clang_cc1 -ast-print %t/ModulesCache/Versioned3/VersionedKit.pcm | FileCheck -check-prefix=CHECK-VERSIONED-3 %s
+
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Versioned4 -fdisable-module-hash -fapinotes-modules -fapinotes-swift-version=4 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: %clang_cc1 -ast-print %t/ModulesCache/Versioned4/VersionedKit.pcm | FileCheck -check-prefix=CHECK-VERSIONED-4 %s
+
+// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/Versioned5 -fdisable-module-hash -fapinotes-modules -fapinotes-swift-version=5 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s
+// RUN: %clang_cc1 -ast-print %t/ModulesCache/Versioned5/VersionedKit.pcm | FileCheck -check-prefix=CHECK-VERSIONED-5 %s
+
+#import <VersionedKit/VersionedKit.h>
+
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef4;
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef4Notes __attribute__((swift_name("MultiVersionedTypedef4Notes_NEW")));
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_NEW")));
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef34;
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef34Notes __attribute__((swift_name("MultiVersionedTypedef34Notes_NEW")));
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_NEW")));
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef45;
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef45Notes __attribute__((swift_name("MultiVersionedTypedef45Notes_NEW")));
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_NEW")));
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef345;
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef345Notes __attribute__((swift_name("MultiVersionedTypedef345Notes_NEW")));
+// CHECK-UNVERSIONED: typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_NEW")));
+
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef4 __attribute__((swift_name("MultiVersionedTypedef4_4")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef4Notes __attribute__((swift_name("MultiVersionedTypedef4Notes_4")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_4")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef34 __attribute__((swift_name("MultiVersionedTypedef34_3")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef34Notes __attribute__((swift_name("MultiVersionedTypedef34Notes_3")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_3")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef45 __attribute__((swift_name("MultiVersionedTypedef45_4")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef45Notes __attribute__((swift_name("MultiVersionedTypedef45Notes_4")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_4")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef345 __attribute__((swift_name("MultiVersionedTypedef345_3")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef345Notes __attribute__((swift_name("MultiVersionedTypedef345Notes_3")));
+// CHECK-VERSIONED-3: typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_3")));
+
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef4 __attribute__((swift_name("MultiVersionedTypedef4_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef4Notes __attribute__((swift_name("MultiVersionedTypedef4Notes_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef34 __attribute__((swift_name("MultiVersionedTypedef34_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef34Notes __attribute__((swift_name("MultiVersionedTypedef34Notes_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef45 __attribute__((swift_name("MultiVersionedTypedef45_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef45Notes __attribute__((swift_name("MultiVersionedTypedef45Notes_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef345 __attribute__((swift_name("MultiVersionedTypedef345_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef345Notes __attribute__((swift_name("MultiVersionedTypedef345Notes_4")));
+// CHECK-VERSIONED-4: typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_4")));
+
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef4;
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef4Notes __attribute__((swift_name("MultiVersionedTypedef4Notes_NEW")));
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_NEW")));
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef34;
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef34Notes __attribute__((swift_name("MultiVersionedTypedef34Notes_NEW")));
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_NEW")));
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef45 __attribute__((swift_name("MultiVersionedTypedef45_5")));
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef45Notes __attribute__((swift_name("MultiVersionedTypedef45Notes_5")));
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_5")));
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef345 __attribute__((swift_name("MultiVersionedTypedef345_5")));
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef345Notes __attribute__((swift_name("MultiVersionedTypedef345Notes_5")));
+// CHECK-VERSIONED-5: typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_5")));
diff --git a/test/APINotes/versioned.m b/test/APINotes/versioned.m
new file mode 100644
index 0000000..e7ec2eb
--- /dev/null
+++ b/test/APINotes/versioned.m
@@ -0,0 +1,187 @@
+// 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  -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  -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-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-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 3.0 IsReplacedByActive{{$}}
+// 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 unversionedRenameDUMP
+// CHECK-DUMP: in VersionedKit unversionedRenameDUMP
+// CHECK-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 0 IsReplacedByActive{{$}}
+// CHECK-DUMP-NEXT: SwiftNameAttr {{.+}} "unversionedRename_HEADER()"
+// CHECK-DUMP-NEXT: SwiftNameAttr {{.+}} "unversionedRename_NOTES()"
+// 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 3.0 {{[0-9]+}} IsReplacedByActive{{$}}
+// 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 3.0 IsReplacedByActive{{$}}
+// 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-LABEL: Dumping Swift4RenamedDUMP
+// CHECK-DUMP: in VersionedKit Swift4RenamedDUMP
+// CHECK-VERSIONED-DUMP-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 4 {{[0-9]+}} IsReplacedByActive{{$}}
+// CHECK-VERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} "SpecialSwift4Name"
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftVersionedAttr {{.+}} Implicit 4{{$}}
+// CHECK-UNVERSIONED-DUMP-NEXT: SwiftNameAttr {{.+}} Implicit "SpecialSwift4Name"
+// 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: void privateFunc() __attribute__((swift_private));
+
+// CHECK-UNVERSIONED: typedef double MyDoubleWrapper __attribute__((swift_wrapper("struct")));
+
+// 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-VERSIONED: void privateFunc();
+
+// CHECK-VERSIONED: typedef double MyDoubleWrapper;
+
+// CHECK-VERSIONED:      enum MyErrorCode {
+// CHECK-VERSIONED-NEXT:     MyErrorCodeFailed = 1
+// CHECK-VERSIONED-NEXT: };
+
+// CHECK-VERSIONED-NOT: __attribute__((swift_bridge("MyValueType")))
+// CHECK-VERSIONED: @interface MyReferenceType
+
+// 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..8d5c0fb
--- /dev/null
+++ b/test/APINotes/yaml-convert-diags.c
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fsyntax-only -fapinotes  %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..a7b370a
--- /dev/null
+++ b/test/APINotes/yaml-parse-diags.c
@@ -0,0 +1,6 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fsyntax-only -fapinotes  %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/Analysis/misc-ps.m b/test/Analysis/misc-ps.m
index 9a75cfd..c610a7d 100644
--- a/test/Analysis/misc-ps.m
+++ b/test/Analysis/misc-ps.m
@@ -1086,7 +1086,7 @@
 }
 
 void test_enum_cases_positive(enum Cases C) {
-  switch (C) { // expected-warning{{enumeration value 'C4' not handled in switch}}
+  switch (C) { // expected-warning{{enumeration value 'C4' not handled in switch}} expected-note {{add missing switch cases}}
   case C1:
   case C2:
   case C3:
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/CMakeLists.txt b/test/CMakeLists.txt
index fa926c5..a375695 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -46,10 +46,11 @@
   c-index-test diagtool
   clang-tblgen
   clang-offload-bundler
+  clang-refactor-test
   clang-import-test
   clang-rename
   )
-  
+
 if(CLANG_ENABLE_STATIC_ANALYZER)
   list(APPEND CLANG_TEST_DEPS
     clang-check
diff --git a/test/CodeGen/2004-02-20-Builtins.c b/test/CodeGen/2004-02-20-Builtins.c
index 9be0523..13f9701 100644
--- a/test/CodeGen/2004-02-20-Builtins.c
+++ b/test/CodeGen/2004-02-20-Builtins.c
@@ -1,5 +1,8 @@
-// RUN: %clang_cc1  %s -emit-llvm -o - | not grep builtin
+// RUN: %clang_cc1  %s -emit-llvm -o - | FileCheck %s
 double sqrt(double x);
+
+// CHECK-LABEL: @zsqrtxxx
+// CHECK-NOT: builtin
 void zsqrtxxx(float num) {
    num = sqrt(num);
 }
diff --git a/test/CodeGen/2009-10-20-GlobalDebug.c b/test/CodeGen/2009-10-20-GlobalDebug.c
index 0d7c759..c8c247f 100644
--- a/test/CodeGen/2009-10-20-GlobalDebug.c
+++ b/test/CodeGen/2009-10-20-GlobalDebug.c
@@ -10,11 +10,11 @@
   return 0;
 }
 
-// CHECK: [[L]] = !DIGlobalVariableExpression(var: [[LV:.*]])
+// CHECK: [[L]] = !DIGlobalVariableExpression(var: [[LV:.*]], expr: !DIExpression())
 // CHECK: [[LV]] = distinct !DIGlobalVariable(name: "localstatic"
 // CHECK-NOT:                                 linkageName:
 // CHECK-SAME:                                line: 9,
-// CHECK: [[G]] = !DIGlobalVariableExpression(var: [[GV:.*]])
+// CHECK: [[G]] = !DIGlobalVariableExpression(var: [[GV:.*]], expr: !DIExpression())
 // CHECK: [[GV]] = distinct !DIGlobalVariable(name: "global"
 // CHECK-NOT:                                 linkageName:
 // CHECK-SAME:                                line: 7,
diff --git a/test/CodeGen/2010-08-10-DbgConstant.c b/test/CodeGen/2010-08-10-DbgConstant.c
index 68947ed..ad9d566 100644
--- a/test/CodeGen/2010-08-10-DbgConstant.c
+++ b/test/CodeGen/2010-08-10-DbgConstant.c
@@ -1,6 +1,5 @@
 // RUN: %clang_cc1 -S -emit-llvm -debug-info-kind=limited  %s -o - | FileCheck %s
-// CHECK: !DIGlobalVariableExpression(var: [[VAR:.*]], expr: [[EXPR:![0-9]+]])
-// CHECK: [[EXPR]] = !DIExpression(DW_OP_constu, 201, DW_OP_stack_value)
+// CHECK: !DIGlobalVariableExpression(var: [[VAR:.*]], expr: !DIExpression(DW_OP_constu, 201, DW_OP_stack_value))
 
 static const unsigned int ro = 201;
 void bar(int);
diff --git a/test/CodeGen/debug-info-global-constant.c b/test/CodeGen/debug-info-global-constant.c
index 4175f24..8cb7f44 100644
--- a/test/CodeGen/debug-info-global-constant.c
+++ b/test/CodeGen/debug-info-global-constant.c
@@ -5,11 +5,10 @@
 // exactly once.
 
 // CHECK: @i = internal constant i32 1, align 4, !dbg ![[I:[0-9]+]]
-// CHECK: ![[I]] = !DIGlobalVariableExpression(var: ![[VAR:.*]], expr: ![[EXPR:[0-9]+]])
+// CHECK: ![[I]] = !DIGlobalVariableExpression(var: ![[VAR:.*]], expr: !DIExpression(DW_OP_constu, 1, DW_OP_stack_value))
 // CHECK: ![[VAR]] = distinct !DIGlobalVariable(name: "i",
 // CHECK: !DICompileUnit({{.*}}globals: ![[GLOBALS:[0-9]+]])
 // CHECK: ![[GLOBALS]] = !{![[I]]}
-// CHECK: ![[EXPR]] = !DIExpression(DW_OP_constu, 1, DW_OP_stack_value)
 static const int i = 1;
 
 void g(const int *, int);
diff --git a/test/CodeGen/debug-info-lto.c b/test/CodeGen/debug-info-lto.c
new file mode 100644
index 0000000..5dab0a1
--- /dev/null
+++ b/test/CodeGen/debug-info-lto.c
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -flto -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+// RUN: %clang_cc1 -flto=thin -emit-llvm -debug-info-kind=standalone %s -o - | FileCheck %s
+// The "o" in LTO stands for optimization!
+// CHECK: !DICompileUnit({{.*}} isOptimized: true
diff --git a/test/CodeGen/debug-info-static-const-fp.c b/test/CodeGen/debug-info-static-const-fp.c
index 4dfe057..1b1da09 100644
--- a/test/CodeGen/debug-info-static-const-fp.c
+++ b/test/CodeGen/debug-info-static-const-fp.c
@@ -33,22 +33,19 @@
   return hVal + fVal + dVal + ldVal;
 }
 
-// CHECK: !DIGlobalVariableExpression(var: [[HVAL:.*]], expr: [[HEXPR:.*]])
+// CHECK: !DIGlobalVariableExpression(var: [[HVAL:.*]], expr: !DIExpression(DW_OP_constu, 16502, DW_OP_stack_value))
 // CHECK: [[HVAL]] = distinct !DIGlobalVariable(name: "hVal",
 // CHECK-SAME:                                  isLocal: true, isDefinition: true
-// CHECK: [[HEXPR]] = !DIExpression(DW_OP_constu, 16502, DW_OP_stack_value)
 
-// CHECK: !DIGlobalVariableExpression(var: [[FVAL:.*]], expr: [[FEXPR:.*]])
+// CHECK: !DIGlobalVariableExpression(var: [[FVAL:.*]], expr: !DIExpression(DW_OP_constu, 3238681178, DW_OP_stack_value))
 // CHECK: [[FVAL]] = distinct !DIGlobalVariable(name: "fVal",
 // CHECK-SAME:                                  isLocal: true, isDefinition: true
-// CHECK: [[FEXPR]] = !DIExpression(DW_OP_constu, 3238681178, DW_OP_stack_value)
 
-// CHECK: !DIGlobalVariableExpression(var: [[DVAL:.*]], expr: [[DEXPR:.*]])
+// CHECK: !DIGlobalVariableExpression(var: [[DVAL:.*]], expr: !DIExpression(DW_OP_constu, 4658387303597904457, DW_OP_stack_value))
 // CHECK: [[DVAL]] = distinct !DIGlobalVariable(name: "dVal",
 // CHECK-SAME:                                  isLocal: true, isDefinition: true
-// CHECK: [[DEXPR]] = !DIExpression(DW_OP_constu, 4658387303597904457, DW_OP_stack_value)
 
 // CHECK-LDlg-DAG: [[LDVAL:.*]] = distinct !DIGlobalVariable(name: "ldVal", {{.*}}, isLocal: true, isDefinition: true)
-// CHECK-LDlg-DAG: !DIGlobalVariableExpression(var: [[LDVAL]])
+// CHECK-LDlg-DAG: !DIGlobalVariableExpression(var: [[LDVAL]], expr: !DIExpression())
 // CHECK-LDsm-DAG: [[LDVAL:.*]] = distinct !DIGlobalVariable(name: "ldVal", {{.*}}, isLocal: true, isDefinition: true)
 // CHECK-LDsm-DAG: !DIGlobalVariableExpression(var: [[LDVAL]], expr:
diff --git a/test/CodeGen/debug-info-static.c b/test/CodeGen/debug-info-static.c
index 016f1e6..d6ade2a 100644
--- a/test/CodeGen/debug-info-static.c
+++ b/test/CodeGen/debug-info-static.c
@@ -2,7 +2,7 @@
 
 // CHECK: @f.xyzzy = internal global i32 0, align 4, !dbg [[XYZZY:![0-9]+]]
 
-// CHECK: [[XYZZY]] = !DIGlobalVariableExpression(var: [[VAR:.*]])
+// CHECK: [[XYZZY]] = !DIGlobalVariableExpression(var: [[VAR:.*]], expr: !DIExpression())
 // CHECK: [[VAR]] = distinct !DIGlobalVariable
 void f(void)
 {
diff --git a/test/CodeGen/debug-info-vla.c b/test/CodeGen/debug-info-vla.c
index 3b69773..7928ca7 100644
--- a/test/CodeGen/debug-info-vla.c
+++ b/test/CodeGen/debug-info-vla.c
@@ -3,8 +3,7 @@
 void testVLAwithSize(int s)
 {
 // CHECK: dbg.declare
-// CHECK: dbg.declare({{.*}}, metadata ![[VAR:.*]], metadata ![[EXPR:.*]])
-// CHECK: ![[EXPR]] = !DIExpression()
+// CHECK: dbg.declare({{.*}}, metadata ![[VAR:.*]], metadata !DIExpression())
 // CHECK: ![[VAR]] = !DILocalVariable(name: "vla",{{.*}} line: [[@LINE+1]]
   int vla[s];
   int i;
diff --git a/test/CodeGen/fp16vec-ops.c b/test/CodeGen/fp16vec-ops.c
new file mode 100644
index 0000000..a99be41
--- /dev/null
+++ b/test/CodeGen/fp16vec-ops.c
@@ -0,0 +1,162 @@
+// REQUIRES: arm-registered-target
+// RUN: %clang_cc1 -triple arm64-apple-ios9 -emit-llvm -o - -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=CHECK
+// RUN: %clang_cc1 -triple armv7-apple-ios9 -emit-llvm -o - -fallow-half-arguments-and-returns %s | FileCheck %s --check-prefix=CHECK
+
+typedef __fp16 half4 __attribute__ ((vector_size (8)));
+typedef short short4 __attribute__ ((vector_size (8)));
+
+half4 hv0, hv1;
+short4 sv0;
+
+// CHECK-LABEL: testFP16Vec0
+// CHECK: %[[V0:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV:.*]] = fpext <4 x half> %[[V0]] to <4 x float>
+// CHECK: %[[V1:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV1:.*]] = fpext <4 x half> %[[V1]] to <4 x float>
+// CHECK: %[[ADD:.*]] = fadd <4 x float> %[[CONV]], %[[CONV1]]
+// CHECK: %[[CONV2:.*]] = fptrunc <4 x float> %[[ADD]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV2]], <4 x half>* @hv0, align 8
+// CHECK: %[[V2:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV3:.*]] = fpext <4 x half> %[[V2]] to <4 x float>
+// CHECK: %[[V3:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV4:.*]] = fpext <4 x half> %[[V3]] to <4 x float>
+// CHECK: %[[SUB:.*]] = fsub <4 x float> %[[CONV3]], %[[CONV4]]
+// CHECK: %[[CONV5:.*]] = fptrunc <4 x float> %[[SUB]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV5]], <4 x half>* @hv0, align 8
+// CHECK: %[[V4:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV6:.*]] = fpext <4 x half> %[[V4]] to <4 x float>
+// CHECK: %[[V5:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV7:.*]] = fpext <4 x half> %[[V5]] to <4 x float>
+// CHECK: %[[MUL:.*]] = fmul <4 x float> %[[CONV6]], %[[CONV7]]
+// CHECK: %[[CONV8:.*]] = fptrunc <4 x float> %[[MUL]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV8]], <4 x half>* @hv0, align 8
+// CHECK: %[[V6:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV9:.*]] = fpext <4 x half> %[[V6]] to <4 x float>
+// CHECK: %[[V7:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV10:.*]] = fpext <4 x half> %[[V7]] to <4 x float>
+// CHECK: %[[DIV:.*]] = fdiv <4 x float> %[[CONV9]], %[[CONV10]]
+// CHECK: %[[CONV11:.*]] = fptrunc <4 x float> %[[DIV]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV11]], <4 x half>* @hv0, align 8
+
+void testFP16Vec0() {
+  hv0 = hv0 + hv1;
+  hv0 = hv0 - hv1;
+  hv0 = hv0 * hv1;
+  hv0 = hv0 / hv1;
+}
+
+// CHECK-LABEL: testFP16Vec1
+// CHECK: %[[V0:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV:.*]] = fpext <4 x half> %[[V0]] to <4 x float>
+// CHECK: %[[V1:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV1:.*]] = fpext <4 x half> %[[V1]] to <4 x float>
+// CHECK: %[[ADD:.*]] = fadd <4 x float> %[[CONV1]], %[[CONV]]
+// CHECK: %[[CONV2:.*]] = fptrunc <4 x float> %[[ADD]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV2]], <4 x half>* @hv0, align 8
+// CHECK: %[[V2:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV3:.*]] = fpext <4 x half> %[[V2]] to <4 x float>
+// CHECK: %[[V3:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV4:.*]] = fpext <4 x half> %[[V3]] to <4 x float>
+// CHECK: %[[SUB:.*]] = fsub <4 x float> %[[CONV4]], %[[CONV3]]
+// CHECK: %[[CONV5:.*]] = fptrunc <4 x float> %[[SUB]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV5]], <4 x half>* @hv0, align 8
+// CHECK: %[[V4:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV6:.*]] = fpext <4 x half> %[[V4]] to <4 x float>
+// CHECK: %[[V5:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV7:.*]] = fpext <4 x half> %[[V5]] to <4 x float>
+// CHECK: %[[MUL:.*]] = fmul <4 x float> %[[CONV7]], %[[CONV6]]
+// CHECK: %[[CONV8:.*]] = fptrunc <4 x float> %[[MUL]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV8]], <4 x half>* @hv0, align 8
+// CHECK: %[[V6:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV9:.*]] = fpext <4 x half> %[[V6]] to <4 x float>
+// CHECK: %[[V7:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV10:.*]] = fpext <4 x half> %[[V7]] to <4 x float>
+// CHECK: %[[DIV:.*]] = fdiv <4 x float> %[[CONV10]], %[[CONV9]]
+// CHECK: %[[CONV11:.*]] = fptrunc <4 x float> %[[DIV]] to <4 x half>
+// CHECK: store <4 x half> %[[CONV11]], <4 x half>* @hv0, align 8
+
+void testFP16Vec1() {
+  hv0 += hv1;
+  hv0 -= hv1;
+  hv0 *= hv1;
+  hv0 /= hv1;
+}
+
+// CHECK-LABEL: testFP16Vec2
+// CHECK: %[[CADDR:.*]] = alloca i32, align 4
+// CHECK: store i32 %[[C:.*]], i32* %[[CADDR]], align 4
+// CHECK: %[[V0:.*]] = load i32, i32* %[[CADDR]], align 4
+// CHECK: %[[TOBOOL:.*]] = icmp ne i32 %[[V0]], 0
+// CHECK: br i1 %[[TOBOOL]], label %{{.*}}, label %{{.*}}
+//
+// CHECK: %[[V1:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: br label %{{.*}}
+//
+// CHECK: %[[V2:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: br label %{{.*}}
+//
+// CHECK: %[[COND:.*]] = phi <4 x half> [ %[[V1]], %{{.*}} ], [ %[[V2]], %{{.*}} ]
+// CHECK: store <4 x half> %[[COND]], <4 x half>* @hv0, align 8
+
+void testFP16Vec2(int c) {
+  hv0 = c ? hv0 : hv1;
+}
+
+// CHECK-LABEL: testFP16Vec3
+// CHECK: %[[V0:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV:.*]] = fpext <4 x half> %[[V0]] to <4 x float>
+// CHECK: %[[V1:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV1:.*]] = fpext <4 x half> %[[V1]] to <4 x float>
+// CHECK: %[[CMP:.*]] = fcmp oeq <4 x float> %[[CONV]], %[[CONV1]]
+// CHECK: %[[SEXT:.*]] = sext <4 x i1> %[[CMP]] to <4 x i32>
+// CHECK: %[[CONV2:.*]] = trunc <4 x i32> %[[SEXT]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV2]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V2:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV3:.*]] = fpext <4 x half> %[[V2]] to <4 x float>
+// CHECK: %[[V3:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV4:.*]] = fpext <4 x half> %[[V3]] to <4 x float>
+// CHECK: %[[CMP5:.*]] = fcmp une <4 x float> %[[CONV3]], %[[CONV4]]
+// CHECK: %[[SEXT6:.*]] = sext <4 x i1> %[[CMP5]] to <4 x i32>
+// CHECK: %[[CONV7:.*]] = trunc <4 x i32> %[[SEXT6]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV7]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V4:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV8:.*]] = fpext <4 x half> %[[V4]] to <4 x float>
+// CHECK: %[[V5:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV9:.*]] = fpext <4 x half> %[[V5]] to <4 x float>
+// CHECK: %[[CMP10:.*]] = fcmp olt <4 x float> %[[CONV8]], %[[CONV9]]
+// CHECK: %[[SEXT11:.*]] = sext <4 x i1> %[[CMP10]] to <4 x i32>
+// CHECK: %[[CONV12:.*]] = trunc <4 x i32> %[[SEXT11]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV12]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V6:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV13:.*]] = fpext <4 x half> %[[V6]] to <4 x float>
+// CHECK: %[[V7:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV14:.*]] = fpext <4 x half> %[[V7]] to <4 x float>
+// CHECK: %[[CMP15:.*]] = fcmp ogt <4 x float> %[[CONV13]], %[[CONV14]]
+// CHECK: %[[SEXT16:.*]] = sext <4 x i1> %[[CMP15]] to <4 x i32>
+// CHECK: %[[CONV17:.*]] = trunc <4 x i32> %[[SEXT16]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV17]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V8:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV18:.*]] = fpext <4 x half> %[[V8]] to <4 x float>
+// CHECK: %[[V9:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV19:.*]] = fpext <4 x half> %[[V9]] to <4 x float>
+// CHECK: %[[CMP20:.*]] = fcmp ole <4 x float> %[[CONV18]], %[[CONV19]]
+// CHECK: %[[SEXT21:.*]] = sext <4 x i1> %[[CMP20]] to <4 x i32>
+// CHECK: %[[CONV22:.*]] = trunc <4 x i32> %[[SEXT21]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV22]], <4 x i16>* @sv0, align 8
+// CHECK: %[[V10:.*]] = load <4 x half>, <4 x half>* @hv0, align 8
+// CHECK: %[[CONV23:.*]] = fpext <4 x half> %[[V10]] to <4 x float>
+// CHECK: %[[V11:.*]] = load <4 x half>, <4 x half>* @hv1, align 8
+// CHECK: %[[CONV24:.*]] = fpext <4 x half> %[[V11]] to <4 x float>
+// CHECK: %[[CMP25:.*]] = fcmp oge <4 x float> %[[CONV23]], %[[CONV24]]
+// CHECK: %[[SEXT26:.*]] = sext <4 x i1> %[[CMP25]] to <4 x i32>
+// CHECK: %[[CONV27:.*]] = trunc <4 x i32> %[[SEXT26]] to <4 x i16>
+// CHECK: store <4 x i16> %[[CONV27]], <4 x i16>* @sv0, align 8
+
+void testFP16Vec3() {
+  sv0 = hv0 == hv1;
+  sv0 = hv0 != hv1;
+  sv0 = hv0 < hv1;
+  sv0 = hv0 > hv1;
+  sv0 = hv0 <= hv1;
+  sv0 = hv0 >= hv1;
+}
diff --git a/test/CodeGen/mangle-blocks.c b/test/CodeGen/mangle-blocks.c
index e8de92d..4ea5a55 100644
--- a/test/CodeGen/mangle-blocks.c
+++ b/test/CodeGen/mangle-blocks.c
@@ -12,12 +12,12 @@
 }
 
 // CHECK: @__func__.__mangle_block_invoke_2 = private unnamed_addr constant [22 x i8] c"mangle_block_invoke_2\00", align 1
-// CHECK: @.str = private unnamed_addr constant {{.*}}, align 1
-// CHECK: @.str.1 = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
+// CHECK: @.str{{.*}} = private unnamed_addr constant {{.*}}, align 1
+// CHECK: @.str[[STR1:.*]] = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
 
 // CHECK: define internal void @__mangle_block_invoke(i8* %.block_descriptor)
 
 // CHECK: define internal void @__mangle_block_invoke_2(i8* %.block_descriptor){{.*}}{
-// CHECK:   call void @__assert_rtn(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @__func__.__mangle_block_invoke_2, i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 9, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i32 0, i32 0))
+// CHECK:   call void @__assert_rtn(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @__func__.__mangle_block_invoke_2, i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 9, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str[[STR1]], i32 0, i32 0))
 // CHECK: }
 
diff --git a/test/CodeGen/ubsan-builtin-checks.c b/test/CodeGen/ubsan-builtin-checks.c
new file mode 100644
index 0000000..9733b0e
--- /dev/null
+++ b/test/CodeGen/ubsan-builtin-checks.c
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -w -emit-llvm -o - %s -fsanitize=builtin | FileCheck %s
+// RUN: %clang_cc1 -triple arm64-none-linux-gnu -w -emit-llvm -o - %s -fsanitize=builtin | FileCheck %s --check-prefix=NOT-UB
+
+// NOT-UB-NOT: __ubsan_handle_invalid_builtin
+
+// CHECK: define void @check_ctz
+void check_ctz(int n) {
+  // CHECK: [[NOT_ZERO:%.*]] = icmp ne i32 [[N:%.*]], 0, !nosanitize
+  // CHECK-NEXT: br i1 [[NOT_ZERO]]
+  //
+  // Handler block:
+  // CHECK: call void @__ubsan_handle_invalid_builtin
+  // CHECK-NEXT: unreachable
+  //
+  // Continuation block:
+  // CHECK: call i32 @llvm.cttz.i32(i32 [[N]], i1 true)
+  __builtin_ctz(n);
+
+  // CHECK: call void @__ubsan_handle_invalid_builtin
+  __builtin_ctzl(n);
+
+  // CHECK: call void @__ubsan_handle_invalid_builtin
+  __builtin_ctzll(n);
+}
+
+// CHECK: define void @check_clz
+void check_clz(int n) {
+  // CHECK: [[NOT_ZERO:%.*]] = icmp ne i32 [[N:%.*]], 0, !nosanitize
+  // CHECK-NEXT: br i1 [[NOT_ZERO]]
+  //
+  // Handler block:
+  // CHECK: call void @__ubsan_handle_invalid_builtin
+  // CHECK-NEXT: unreachable
+  //
+  // Continuation block:
+  // CHECK: call i32 @llvm.ctlz.i32(i32 [[N]], i1 true)
+  __builtin_clz(n);
+
+  // CHECK: call void @__ubsan_handle_invalid_builtin
+  __builtin_clzl(n);
+
+  // CHECK: call void @__ubsan_handle_invalid_builtin
+  __builtin_clzll(n);
+}
diff --git a/test/CodeGen/unsigned-overflow-minimal.c b/test/CodeGen/unsigned-overflow-minimal.c
new file mode 100644
index 0000000..d4b8966
--- /dev/null
+++ b/test/CodeGen/unsigned-overflow-minimal.c
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=unsigned-integer-overflow -fsanitize-minimal-runtime %s -emit-llvm -o - | FileCheck %s
+
+unsigned long li, lj, lk;
+
+// CHECK-LABEL: define void @testlongadd()
+void testlongadd() {
+  // CHECK: call void @__ubsan_handle_add_overflow_minimal_abort()
+  li = lj + lk;
+}
+
+// CHECK-LABEL: define void @testlongsub()
+void testlongsub() {
+  // CHECK: call void @__ubsan_handle_sub_overflow_minimal_abort()
+  li = lj - lk;
+}
+
+// CHECK-LABEL: define void @testlongmul()
+void testlongmul() {
+  // CHECK: call void @__ubsan_handle_mul_overflow_minimal_abort()
+  li = lj * lk;
+}
diff --git a/test/CodeGenCXX/atomic-inline.cpp b/test/CodeGenCXX/atomic-inline.cpp
new file mode 100644
index 0000000..fe72758
--- /dev/null
+++ b/test/CodeGenCXX/atomic-inline.cpp
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - -triple=x86_64-linux-gnu -target-cpu core2 | FileCheck %s --check-prefix=CORE2
+// Check the atomic code generation for cpu targets w/wo cx16 support.
+
+struct alignas(8) AM8 {
+  int f1, f2;
+};
+AM8 m8;
+AM8 load8() {
+  AM8 am;
+  // CHECK-LABEL: @_Z5load8v
+  // CHECK: load atomic i64, {{.*}} monotonic
+  // CORE2-LABEL: @_Z5load8v
+  // CORE2: load atomic i64, {{.*}} monotonic
+  __atomic_load(&m8, &am, 0);
+  return am;
+}
+
+AM8 s8;
+void store8() {
+  // CHECK-LABEL: @_Z6store8v
+  // CHECK: store atomic i64 {{.*}} monotonic
+  // CORE2-LABEL: @_Z6store8v
+  // CORE2: store atomic i64 {{.*}} monotonic
+  __atomic_store(&m8, &s8, 0);
+}
+
+bool cmpxchg8() {
+  AM8 am;
+  // CHECK-LABEL: @_Z8cmpxchg8v
+  // CHECK: cmpxchg i64* {{.*}} monotonic
+  // CORE2-LABEL: @_Z8cmpxchg8v
+  // CORE2: cmpxchg i64* {{.*}} monotonic
+  return __atomic_compare_exchange(&m8, &s8, &am, 0, 0, 0);
+}
+
+struct alignas(16) AM16 {
+  long f1, f2;
+};
+
+AM16 m16;
+AM16 load16() {
+  AM16 am;
+  // CHECK-LABEL: @_Z6load16v
+  // CHECK: call void @__atomic_load
+  // CORE2-LABEL: @_Z6load16v
+  // CORE2: load atomic i128, {{.*}} monotonic
+  __atomic_load(&m16, &am, 0);
+  return am;
+}
+
+AM16 s16;
+void store16() {
+  // CHECK-LABEL: @_Z7store16v
+  // CHECK: call void @__atomic_store
+  // CORE2-LABEL: @_Z7store16v
+  // CORE2: store atomic i128 {{.*}} monotonic
+  __atomic_store(&m16, &s16, 0);
+}
+
+bool cmpxchg16() {
+  AM16 am;
+  // CHECK-LABEL: @_Z9cmpxchg16v
+  // CHECK: call zeroext i1 @__atomic_compare_exchange
+  // CORE2-LABEL: @_Z9cmpxchg16v
+  // CORE2: cmpxchg i128* {{.*}} monotonic
+  return __atomic_compare_exchange(&m16, &s16, &am, 0, 0, 0);
+}
+
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index d58853c..aa3da10 100644
--- a/test/CodeGenCXX/catch-undef-behavior.cpp
+++ b/test/CodeGenCXX/catch-undef-behavior.cpp
@@ -16,6 +16,10 @@
 // Check that type mismatch handler is not modified by ASan.
 // CHECK-ASAN: private unnamed_addr global { { [{{.*}} x i8]*, i32, i32 }, { i16, i16, [4 x i8] }*, i8*, i8 } { {{.*}}, { i16, i16, [4 x i8] }* [[TYPE_DESCR]], {{.*}} }
 
+// CHECK: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+// CHECK-X86: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+// CHECK-X32: [[IndirectRTTI_ZTIFvPFviEE:@.+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*)
+
 struct T : S {};
 
 // CHECK-LABEL: @_Z17reference_binding
@@ -395,23 +399,30 @@
   // CHECK-NEXT: br i1 [[AND]]
 }
 
-// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
-// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
-// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }>
+//
+// CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 trunc (i64 sub (i64 ptrtoint (i8** {{.*}} to i64), i64 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i64)) to i32) }>
+// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }>
+// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i32 }> <{ i32 846595819, i32 sub (i32 ptrtoint (i8** [[IndirectRTTI_ZTIFvPFviEE]] to i32), i32 ptrtoint (void (void (i32)*)* @_Z22indirect_function_callPFviE to i32)) }>
 void indirect_function_call(void (*p)(int)) {
-  // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>*
+  // CHECK: [[PTR:%.+]] = bitcast void (i32)* {{.*}} to <{ i32, i32 }>*
 
   // Signature check
-  // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 0
+  // CHECK-NEXT: [[SIGPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 0
   // CHECK-NEXT: [[SIG:%.+]] = load i32, i32* [[SIGPTR]]
-  // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 1413876459
+  // CHECK-NEXT: [[SIGCMP:%.+]] = icmp eq i32 [[SIG]], 846595819
   // CHECK-NEXT: br i1 [[SIGCMP]]
 
   // RTTI pointer check
-  // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 1
-  // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[RTTIPTR]]
+  // CHECK: [[RTTIPTR:%.+]] = getelementptr <{ i32, i32 }>, <{ i32, i32 }>* [[PTR]], i32 0, i32 1
+  // CHECK-NEXT: [[RTTIEncIntTrunc:%.+]] = load i32, i32* [[RTTIPTR]]
+  // CHECK-NEXT: [[RTTIEncInt:%.+]] = sext i32 [[RTTIEncIntTrunc]] to i64
+  // CHECK-NEXT: [[FuncAddrInt:%.+]] = ptrtoint void (i32)* {{.*}} to i64
+  // CHECK-NEXT: [[IndirectGVInt:%.+]] = add i64 [[RTTIEncInt]], [[FuncAddrInt]]
+  // CHECK-NEXT: [[IndirectGV:%.+]] = inttoptr i64 [[IndirectGVInt]] to i8**
+  // CHECK-NEXT: [[RTTI:%.+]] = load i8*, i8** [[IndirectGV]], align 8
   // CHECK-NEXT: [[RTTICMP:%.+]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*)
   // CHECK-NEXT: br i1 [[RTTICMP]]
+
   p(42);
 }
 
@@ -454,7 +465,7 @@
   void this_align_lambda_2();
 };
 void ThisAlign::this_align_lambda() {
-  // CHECK-LABEL: define {{.*}}@"_ZZN9ThisAlign17this_align_lambdaEvENK3$_0clEv"
+  // CHECK-LABEL: define internal %struct.ThisAlign* @"_ZZN9ThisAlign17this_align_lambdaEvENK3$_0clEv"
   // CHECK-SAME: (%{{.*}}* %[[this:[^)]*]])
   // CHECK: %[[this_addr:.*]] = alloca
   // CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]],
@@ -555,7 +566,7 @@
 }
 
 void ThisAlign::this_align_lambda_2() {
-  // CHECK-LABEL: define {{.*}}@"_ZZN9ThisAlign19this_align_lambda_2EvENK3$_1clEv"
+  // CHECK-LABEL: define internal void @"_ZZN9ThisAlign19this_align_lambda_2EvENK3$_1clEv"
   // CHECK-SAME: (%{{.*}}* %[[this:[^)]*]])
   // CHECK: %[[this_addr:.*]] = alloca
   // CHECK: store %{{.*}}* %[[this]], %{{.*}}** %[[this_addr]],
diff --git a/test/CodeGenCXX/clang-abi-compat.cpp b/test/CodeGenCXX/clang-abi-compat.cpp
deleted file mode 100644
index 409c721..0000000
--- a/test/CodeGenCXX/clang-abi-compat.cpp
+++ /dev/null
@@ -1,19 +0,0 @@
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.0 %s -emit-llvm -o - | FileCheck --check-prefix=PRE39 --check-prefix=PRE5 %s
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.8 %s -emit-llvm -o - | FileCheck --check-prefix=PRE39 --check-prefix=PRE5 %s
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=3.9 %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=PRE5 %s
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=4.0 %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=PRE5 %s
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=5 %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=V5 %s
-// RUN: %clang_cc1 -std=c++17 -triple x86_64-linux-gnu -fclang-abi-compat=latest %s -emit-llvm -o - | FileCheck --check-prefix=V39 --check-prefix=V5 %s
-
-typedef __attribute__((vector_size(8))) long long v1xi64;
-void clang39(v1xi64) {}
-// PRE39: @_Z7clang39Dv1_x(i64
-// V39: @_Z7clang39Dv1_x(double
-
-struct A {
-  A(const A&) = default;
-  A(A&&);
-};
-void clang5(A) {}
-// PRE5: @_Z6clang51A()
-// V5: @_Z6clang51A(%{{.*}}*
diff --git a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
index e3708e2..8e47a0d 100644
--- a/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
+++ b/test/CodeGenCXX/debug-info-inheriting-constructor.cpp
@@ -13,7 +13,7 @@
 // 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-SAME: metadata ![[THIS:[0-9]+]], metadata !DIExpression()), !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"
diff --git a/test/CodeGenCXX/debug-info-inlined.cpp b/test/CodeGenCXX/debug-info-inlined.cpp
index 9969ef7..53e2cc9 100644
--- a/test/CodeGenCXX/debug-info-inlined.cpp
+++ b/test/CodeGenCXX/debug-info-inlined.cpp
@@ -1,45 +1,29 @@
 // RUN: %clang_cc1 -emit-llvm -triple i686-pc-windows-msvc19.0.24213 -gcodeview -debug-info-kind=limited -std=c++14 %s -o - | FileCheck %s
 // PR33997.
-struct already_AddRefed {
-  ~already_AddRefed();
+struct WithDtor {
+  ~WithDtor();
 };
-struct RefPtr {
-  operator int *();
+struct Base {
+  Base(WithDtor);
 };
-struct ServoCssRulesStrong {
-  already_AddRefed Consume();
+class Forward : Base {
+  using Base::Base;
 };
-struct GroupRule {
-  GroupRule(already_AddRefed);
+class A : Forward {
+  A();
 };
-class ConditionRule : GroupRule {
-  using GroupRule::GroupRule;
+class B : Forward {
+  B();
 };
-class CSSMediaRule : ConditionRule {
-  using ConditionRule::ConditionRule;
-};
-class CSSMozDocumentRule : ConditionRule {
-  using ConditionRule::ConditionRule;
-};
-class ServoDocumentRule : CSSMozDocumentRule {
-  ServoDocumentRule(RefPtr);
-};
-class ServoMediaRule : CSSMediaRule {
-  ServoMediaRule(RefPtr);
-};
-ServoCssRulesStrong Servo_MediaRule_GetRules(int *);
-ServoCssRulesStrong Servo_DocumentRule_GetRules(int *);
-ServoDocumentRule::ServoDocumentRule(RefPtr aRawRule)
-    : CSSMozDocumentRule(Servo_DocumentRule_GetRules(aRawRule).Consume()) {}
+A::A() : Forward(WithDtor()) {}
 
-ServoMediaRule::ServoMediaRule(RefPtr aRawRule)
-    : CSSMediaRule(Servo_MediaRule_GetRules(aRawRule).Consume()) {}
+B::B() : Forward(WithDtor()) {}
 
-// CHECK: define{{.*}}ServoMediaRule
+// CHECK: define{{.*}}A
 // CHECK-NOT: {{ ret }}
-// CHECK: store %class.ConditionRule* %
-// CHECK-SAME: %class.ConditionRule** %
+// CHECK: store %class.Forward* %
+// CHECK-SAME: %class.Forward** %
 // CHECK-SAME: !dbg ![[INL:[0-9]+]]
 
-// CHECK: ![[INL]] = !DILocation(line: 16, scope: ![[SP:[0-9]+]], inlinedAt:
-// CHECK: ![[SP]] = distinct !DISubprogram(name: "GroupRule", {{.*}}isDefinition: true
+// CHECK: ![[INL]] = !DILocation(line: 10, scope: ![[SP:[0-9]+]], inlinedAt:
+// CHECK: ![[SP]] = distinct !DISubprogram(name: "Base", {{.*}}isDefinition: true
diff --git a/test/CodeGenCXX/debug-info-static-member.cpp b/test/CodeGenCXX/debug-info-static-member.cpp
index c777ccb..3537754 100644
--- a/test/CodeGenCXX/debug-info-static-member.cpp
+++ b/test/CodeGenCXX/debug-info-static-member.cpp
@@ -32,7 +32,7 @@
 // why the definition of "a" comes before the declarations while
 // "b" and "c" come after.
 
-// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]])
+// CHECK: [[A]] = !DIGlobalVariableExpression(var: [[AV:.*]], expr: !DIExpression())
 // CHECK: [[AV]] = distinct !DIGlobalVariable(name: "a",
 // CHECK-SAME:                                declaration: ![[DECL_A:[0-9]+]])
 //
@@ -45,7 +45,7 @@
 // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var"
 
 int C::a = 4;
-// CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]])
+// CHECK: [[B]] = !DIGlobalVariableExpression(var: [[BV:.*]], expr: !DIExpression())
 // CHECK: [[BV]] = distinct !DIGlobalVariable(name: "b",
 // CHECK-SAME:                                declaration: ![[DECL_B:[0-9]+]])
 // CHECK: ![[DECL_B]] = !DIDerivedType(tag: DW_TAG_member, name: "b"
@@ -93,7 +93,7 @@
 // CHECK-SAME:           flags: DIFlagPublic | DIFlagStaticMember)
 
 int C::b = 2;
-// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]])
+// CHECK: [[C]] = !DIGlobalVariableExpression(var: [[CV:.*]], expr: !DIExpression())
 // CHECK: [[CV]] = distinct !DIGlobalVariable(name: "c", {{.*}} declaration: ![[DECL_C]])
 int C::c = 1;
 
diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp
index 2b84074..a6aa1a0 100644
--- a/test/CodeGenCXX/debug-info-template-member.cpp
+++ b/test/CodeGenCXX/debug-info-template-member.cpp
@@ -19,7 +19,7 @@
 }
 
 // The compile unit pulls in the global variables first.
-// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]])
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:.*]], expr: !DIExpression())
 // CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x",
 // CHECK-SAME:                                type: ![[OUTER_FOO_INNER_ID:[0-9]+]]
 
diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp
index 54fac0b..0c34145 100644
--- a/test/CodeGenCXX/debug-info-template.cpp
+++ b/test/CodeGenCXX/debug-info-template.cpp
@@ -25,7 +25,7 @@
 int glb;
 void func();
 
-// CHECK: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]])
+// CHECK: [[TCI]] = !DIGlobalVariableExpression(var: [[TCIV:.*]], expr: !DIExpression())
 // CHECK: [[TCIV]] = distinct !DIGlobalVariable(name: "tci",
 // CHECK-SAME:                                  type: ![[TCNESTED:[0-9]+]]
 // CHECK: ![[TCNESTED]] ={{.*}}!DICompositeType(tag: DW_TAG_structure_type, name: "nested",
@@ -84,7 +84,7 @@
 // CHECK: [[TCARG7_3]] = !DITemplateValueParameter(type: [[INT]], value: i32 3)
   3>::nested tci;
 
-// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]])
+// CHECK: [[TCN]] = !DIGlobalVariableExpression(var: [[TCNV:.*]], expr: !DIExpression())
 // CHECK: [[TCNV]] = distinct !DIGlobalVariable(name: "tcn"
 // CHECK-SAME:                                  type: ![[TCNT:[0-9]+]]
 TC
@@ -125,7 +125,7 @@
 struct NN {
 };
 
-// CHECK: [[NN]] = !DIGlobalVariableExpression(var: [[NNV:.*]])
+// CHECK: [[NN]] = !DIGlobalVariableExpression(var: [[NNV:.*]], expr: !DIExpression())
 // CHECK: [[NNV]] = distinct !DIGlobalVariable(name: "nn"
 // CHECK-SAME:                                 type: ![[NNT:[0-9]+]]
 
diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp
index 2b86150..6d6d0c7 100644
--- a/test/CodeGenCXX/debug-info.cpp
+++ b/test/CodeGenCXX/debug-info.cpp
@@ -4,11 +4,11 @@
 // CHECK: @_ZN6pr96081xE = global [3 x i8]* null, align 8, !dbg [[X:![0-9]+]]
 
 // CHECK: define void @_ZN7pr147634funcENS_3fooE
-// CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[F:[0-9]+]], metadata ![[EXPR:[0-9]+]])
+// CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[F:[0-9]+]], metadata !DIExpression())
 
 // !llvm.dbg.cu pulls in globals and their types first.
 // CHECK-NOT: !DIGlobalVariable(name: "c"
-// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:!.*]])
+// CHECK: [[X]] = !DIGlobalVariableExpression(var: [[XV:!.*]], expr: !DIExpression())
 // CHECK: [[XV]] = distinct !DIGlobalVariable(name: "x", linkageName: "_ZN6pr96081xE"
 // CHECK-SAME:                                type: [[INCARRAYPTR:![0-9]*]]
 // CHECK: [[INCARRAYPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[INCARRAY:![0-9]+]]
@@ -21,7 +21,6 @@
 
 // CHECK: ![[INCTYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "incomplete"
 // CHECK-SAME:                                   DIFlagFwdDecl
-// CHECK: ![[EXPR]] = !DIExpression()
 
 template<typename T> struct Identity {
   typedef T Type;
diff --git a/test/CodeGenCXX/inline-dllexport-member.cpp b/test/CodeGenCXX/inline-dllexport-member.cpp
index 66ef459..a98f560 100644
--- a/test/CodeGenCXX/inline-dllexport-member.cpp
+++ b/test/CodeGenCXX/inline-dllexport-member.cpp
@@ -7,7 +7,7 @@
   static const unsigned int ui = 0;
 };
 
-// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]])
+// CHECK: [[UI]] = !DIGlobalVariableExpression(var: [[UIV:.*]], expr: !DIExpression())
 // CHECK: [[UIV]] = distinct !DIGlobalVariable(name: "ui", linkageName: "\01?ui@s@@2IB", scope: ![[SCOPE:[0-9]+]],
 // CHECK: ![[SCOPE]] = distinct !DICompileUnit(
 
diff --git a/test/CodeGenCXX/member-expr-references-variable.cpp b/test/CodeGenCXX/member-expr-references-variable.cpp
new file mode 100644
index 0000000..8c1dded
--- /dev/null
+++ b/test/CodeGenCXX/member-expr-references-variable.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -std=c++11 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct Agg { const char * x; const char * y; constexpr Agg() : x(0), y(0) {} };
+
+struct Struct {
+   constexpr static const char *name = "foo";
+
+   constexpr static __complex float complexValue = 42.0;
+
+   static constexpr const Agg &agg = Agg();
+
+   Struct();
+   Struct(int x);
+};
+
+void use(int n, const char *c);
+
+Struct *getPtr();
+
+// CHECK: @[[STR:.*]] = private unnamed_addr constant [4 x i8] c"foo\00", align 1
+
+void scalarStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+  use(1, Struct::name);
+// CHECK: call void @_Z3useiPKc(i32 1, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  Struct s;
+  use(2, s.name);
+// CHECK: call void @_Z3useiPKc(i32 2, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  use(3, ptr->name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  use(4, ref.name);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  use(5, Struct(2).name);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: call void @_Z3useiPKc(i32 5, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+  use(6, getPtr()->name);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: call void @_Z3useiPKc(i32 6, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[STR]], i32 0, i32 0))
+}
+
+void use(int n, __complex float v);
+
+void complexStaticVariableInMemberExpr(Struct *ptr, Struct &ref) {
+  use(1, Struct::complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce0:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce0]].{{.*}}, align 4
+// CHECK: %[[cast0:.*]] = bitcast { float, float }* %[[coerce0]] to <2 x float>*
+// CHECK: %[[vector0:.*]] = load <2 x float>, <2 x float>* %[[cast0]], align 4
+// CHECK: call void @_Z3useiCf(i32 1, <2 x float> %[[vector0]])
+  Struct s;
+  use(2, s.complexValue);
+// CHECK: store float 4.200000e+01, float* %[[coerce1:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce1]].{{.*}}, align 4
+// CHECK: %[[cast1:.*]] = bitcast { float, float }* %[[coerce1]] to <2 x float>*
+// CHECK: %[[vector1:.*]] = load <2 x float>, <2 x float>* %[[cast1]], align 4
+// CHECK: call void @_Z3useiCf(i32 2, <2 x float> %[[vector1]])
+  use(3, ptr->complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce2:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce2]].{{.*}}, align 4
+// CHECK: %[[cast2:.*]] = bitcast { float, float }* %[[coerce2]] to <2 x float>*
+// CHECK: %[[vector2:.*]] = load <2 x float>, <2 x float>* %[[cast2]], align 4
+// CHECK: call void @_Z3useiCf(i32 3, <2 x float> %[[vector2]])
+  use(4, ref.complexValue);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: store float 4.200000e+01, float* %[[coerce3:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce3]].{{.*}}, align 4
+// CHECK: %[[cast3:.*]] = bitcast { float, float }* %[[coerce3]] to <2 x float>*
+// CHECK: %[[vector3:.*]] = load <2 x float>, <2 x float>* %[[cast3]], align 4
+// CHECK: call void @_Z3useiCf(i32 4, <2 x float> %[[vector3]])
+  use(5, Struct(2).complexValue);
+// CHECK: call void @_ZN6StructC1Ei(%struct.Struct* %{{.*}}, i32 2)
+// CHECK: store float 4.200000e+01, float* %[[coerce4:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce4]].{{.*}}, align 4
+// CHECK: %[[cast4:.*]] = bitcast { float, float }* %[[coerce4]] to <2 x float>*
+// CHECK: %[[vector4:.*]] = load <2 x float>, <2 x float>* %[[cast4]], align 4
+// CHECK: call void @_Z3useiCf(i32 5, <2 x float> %[[vector4]])
+  use(6, getPtr()->complexValue);
+// CHECK: call %struct.Struct* @_Z6getPtrv()
+// CHECK: store float 4.200000e+01, float* %[[coerce5:.*]].{{.*}}, align 4
+// CHECK: store float 0.000000e+00, float* %[[coerce5]].{{.*}}, align 4
+// CHECK: %[[cast5:.*]] = bitcast { float, float }* %[[coerce5]] to <2 x float>*
+// CHECK: %[[vector5:.*]] = load <2 x float>, <2 x float>* %[[cast5]], align 4
+// CHECK: call void @_Z3useiCf(i32 6, <2 x float> %[[vector5]])
+}
+
+void aggregateRefInMemberExpr(Struct *ptr, Struct &ref) {
+  use(1, Struct::agg.x);
+// CHECK: %[[value0:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 1, i8* %[[value0]])
+  Struct s;
+  use(2, s.agg.x);
+// CHECK: %[[value1:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 2, i8* %[[value1]])
+  use(3, ptr->agg.x);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: %[[value2:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 3, i8* %[[value2]])
+  use(4, ref.agg.x);
+// CHECK: load %struct.Struct*, %struct.Struct** %{{.*}}, align 8
+// CHECK: %[[value3:.*]] = load i8*, i8** getelementptr inbounds (%struct.Agg, %struct.Agg* @_ZGRN6Struct3aggE_, i32 0, i32 0), align 8
+// CHECK: call void @_Z3useiPKc(i32 4, i8* %[[value3]])
+}
diff --git a/test/CodeGenCXX/ubsan-devirtualized-calls.cpp b/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
index bc8861a..3de4e37 100644
--- a/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
+++ b/test/CodeGenCXX/ubsan-devirtualized-calls.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple %itanium_abi_triple -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s
 
 struct Base1 {
   virtual void f1() {}
@@ -64,6 +64,11 @@
   // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED3]] {{.*}}, i{{[0-9]+}} %[[P1]]
 
   static_cast<Base1 *>(badp)->f1(); //< No devirt, test 'badp isa Base1'.
+  // We were able to skip the null check on the first type check becuase 'p'
+  // is backed by an alloca. We can't skip the second null check because 'badp'
+  // is a (bitcast (load ...)).
+  // CHECK: call void @__ubsan_handle_type_mismatch
+  //
   // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Base1* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
   // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_BASE1]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
 }
@@ -76,6 +81,8 @@
   // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_1]] {{.*}}, i{{[0-9]+}} %[[P1]]
 
   static_cast<Base1 *>(badp)->f1(); //< Devirt Base1::f1 to Derived4::f1.
+  // CHECK: call void @__ubsan_handle_type_mismatch
+  //
   // CHECK: %[[BADP1:[0-9]+]] = ptrtoint %struct.Derived4* {{%[0-9]+}} to i{{[0-9]+}}, !nosanitize
   // CHECK-NEXT: call void @__ubsan_handle_dynamic_type_cache{{[_a-z]*}}({{.*}} [[UBSAN_TI_DERIVED4_2]] {{.*}}, i{{[0-9]+}} %[[BADP1]]
 }
diff --git a/test/CodeGenCXX/ubsan-type-checks.cpp b/test/CodeGenCXX/ubsan-type-checks.cpp
index 786d049..e53ab24 100644
--- a/test/CodeGenCXX/ubsan-type-checks.cpp
+++ b/test/CodeGenCXX/ubsan-type-checks.cpp
@@ -1,6 +1,8 @@
 // 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
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null,vptr | FileCheck %s -check-prefixes=VPTR
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=vptr | FileCheck %s -check-prefixes=VPTR_NO_NULL
 
 struct A {
   // COMMON-LABEL: define linkonce_odr void @_ZN1A10do_nothingEv
@@ -24,13 +26,60 @@
     // NULL: icmp ne %struct.B* %{{.*}}, null, !nosanitize
 
     // OBJSIZE-NOT: call i64 @llvm.objectsize
+    // OBJSIZE: ret void
   }
 };
 
-void force_irgen() {
+struct Animal {
+  virtual const char *speak() = 0;
+};
+
+struct Cat : Animal {
+  const char *speak() override { return "meow"; }
+};
+
+struct Dog : Animal {
+  const char *speak() override { return "woof"; }
+};
+
+// VPTR-LABEL: define void @_Z12invalid_castP3Cat
+void invalid_cast(Cat *cat = nullptr) {
+  // If -fsanitize=null is available, we'll reuse its check:
+  //
+  // VPTR: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null
+  // VPTR-NEXT: br i1 [[ICMP]]
+  // VPTR: call void @__ubsan_handle_type_mismatch
+  // VPTR-NOT: icmp ne %struct.Dog* {{.*}}, null
+  // VPTR: br i1 [[ICMP]]
+  // VPTR: call void @__ubsan_handle_dynamic_type_cache_miss
+  //
+  // Fall back to the vptr sanitizer's null check when -fsanitize=null isn't
+  // available.
+  //
+  // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch
+  // VPTR_NO_NULL: [[ICMP:%.*]] = icmp ne %struct.Dog* {{.*}}, null
+  // VPTR_NO_NULL-NEXT: br i1 [[ICMP]]
+  // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss
+  auto *badDog = reinterpret_cast<Dog *>(cat);
+  badDog->speak();
+}
+
+// VPTR_NO_NULL-LABEL: define void @_Z13invalid_cast2v
+void invalid_cast2() {
+  // We've got a pointer to an alloca, so there's no run-time null check needed.
+  // VPTR_NO_NULL-NOT: call void @__ubsan_handle_type_mismatch
+  // VPTR_NO_NULL: call void @__ubsan_handle_dynamic_type_cache_miss
+  Cat cat;
+  cat.speak();
+}
+
+int main() {
   A a;
   a.do_nothing();
 
   B b;
   b.do_nothing();
+
+  invalid_cast();
+  return 0;
 }
diff --git a/test/CodeGenCXX/ubsan-vtable-checks.cpp b/test/CodeGenCXX/ubsan-vtable-checks.cpp
index e684ae9..5e17913 100644
--- a/test/CodeGenCXX/ubsan-vtable-checks.cpp
+++ b/test/CodeGenCXX/ubsan-vtable-checks.cpp
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=ITANIUM
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NULL --check-prefix=MSABI
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=ITANIUM
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=MSABI
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=ITANIUM
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows -emit-llvm -fsanitize=null,vptr %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VPTR --check-prefix=MSABI
 struct T {
   virtual ~T() {}
   virtual int v() { return 1; }
diff --git a/test/CodeGenCXX/uncopyable-args.cpp b/test/CodeGenCXX/uncopyable-args.cpp
index 66d67e4..307a5cf 100644
--- a/test/CodeGenCXX/uncopyable-args.cpp
+++ b/test/CodeGenCXX/uncopyable-args.cpp
@@ -1,8 +1,5 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=NEWABI
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-scei-ps4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=18 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-18
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=19 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-19
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s | FileCheck %s -check-prefix=WIN64
 
 namespace trivial {
 // Trivial structs should be passed directly.
@@ -55,13 +52,12 @@
 void bar() {
   foo({});
 }
-// CHECK-LABEL: define void @_ZN9move_ctor3barEv()
-// CHECK: call void @_Z{{.*}}C1Ev(
-// CHECK-NOT: call
-// NEWABI: call void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* %{{.*}})
-// OLDABI: call void @_ZN9move_ctor3fooENS_1AE(i8* %{{.*}})
-// NEWABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"*)
-// OLDABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(i8*)
+// FIXME: The copy ctor is implicitly deleted.
+// CHECK-DISABLED-LABEL: define void @_ZN9move_ctor3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED-NOT: call
+// CHECK-DISABLED: call void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"*)
 
 // WIN64-LABEL: declare void @"\01?foo@move_ctor@@YAXUA@1@@Z"(%"struct.move_ctor::A"*)
 }
@@ -77,13 +73,12 @@
 void bar() {
   foo({});
 }
-// CHECK-LABEL: define void @_ZN11all_deleted3barEv()
-// CHECK: call void @_Z{{.*}}C1Ev(
-// CHECK-NOT: call
-// NEWABI: call void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* %{{.*}})
-// OLDABI: call void @_ZN11all_deleted3fooENS_1AE(i8* %{{.*}})
-// NEWABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*)
-// OLDABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(i8*)
+// FIXME: The copy ctor is deleted.
+// CHECK-DISABLED-LABEL: define void @_ZN11all_deleted3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED-NOT: call
+// CHECK-DISABLED: call void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*)
 
 // WIN64-LABEL: declare void @"\01?foo@all_deleted@@YAXUA@1@@Z"(%"struct.all_deleted::A"*)
 }
@@ -98,17 +93,14 @@
 void bar() {
   foo({});
 }
-// CHECK-LABEL: define void @_ZN18implicitly_deleted3barEv()
-// CHECK: call void @_Z{{.*}}C1Ev(
-// CHECK-NOT: call
-// NEWABI: call void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* %{{.*}})
-// OLDABI: call void @_ZN18implicitly_deleted3fooENS_1AE(i8* %{{.*}})
-// NEWABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*)
-// OLDABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(i8*)
+// FIXME: The copy and move ctors are implicitly deleted.
+// CHECK-DISABLED-LABEL: define void @_ZN18implicitly_deleted3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED-NOT: call
+// CHECK-DISABLED: call void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*)
 
-// In MSVC 2013, the copy ctor is not deleted by a move assignment. In MSVC 2015, it is.
-// WIN64-18-LABEL: declare void @"\01?foo@implicitly_deleted@@YAXUA@1@@Z"(i64
-// WIN64-19-LABEL: declare void @"\01?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"*)
+// WIN64-LABEL: declare void @"\01?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"*)
 }
 
 namespace one_deleted {
@@ -121,13 +113,12 @@
 void bar() {
   foo({});
 }
-// CHECK-LABEL: define void @_ZN11one_deleted3barEv()
-// CHECK: call void @_Z{{.*}}C1Ev(
-// CHECK-NOT: call
-// NEWABI: call void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* %{{.*}})
-// OLDABI: call void @_ZN11one_deleted3fooENS_1AE(i8* %{{.*}})
-// NEWABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*)
-// OLDABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(i8*)
+// FIXME: The copy constructor is implicitly deleted.
+// CHECK-DISABLED-LABEL: define void @_ZN11one_deleted3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED-NOT: call
+// CHECK-DISABLED: call void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*)
 
 // WIN64-LABEL: declare void @"\01?foo@one_deleted@@YAXUA@1@@Z"(%"struct.one_deleted::A"*)
 }
@@ -204,12 +195,12 @@
 void bar() {
   foo({});
 }
-// CHECK-LABEL: define void @_ZN14two_copy_ctors3barEv()
-// CHECK: call void @_Z{{.*}}C1Ev(
-// NEWABI: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* %{{.*}})
-// OLDABI: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* byval
-// NEWABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*)
-// OLDABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* byval
+// FIXME: This class has a non-trivial copy ctor and a trivial copy ctor.  It's
+// not clear whether we should pass by address or in registers.
+// CHECK-DISABLED-LABEL: define void @_ZN14two_copy_ctors3barEv()
+// CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
+// CHECK-DISABLED: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* %{{.*}})
+// CHECK-DISABLED-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*)
 
 // WIN64-LABEL: declare void @"\01?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"*)
 }
@@ -221,8 +212,6 @@
   void *p;
 };
 void *foo(A a) { return a.p; }
-// NEWABI-LABEL: define i8* @_ZN15definition_only3fooENS_1AE(%"struct.definition_only::A"*
-// OLDABI-LABEL: define i8* @_ZN15definition_only3fooENS_1AE(i8*
 // WIN64-LABEL: define i8* @"\01?foo@definition_only@@YAPEAXUA@1@@Z"(%"struct.definition_only::A"*
 }
 
@@ -237,8 +226,6 @@
   B b;
 };
 void *foo(A a) { return a.b.p; }
-// NEWABI-LABEL: define i8* @_ZN17deleted_by_member3fooENS_1AE(%"struct.deleted_by_member::A"*
-// OLDABI-LABEL: define i8* @_ZN17deleted_by_member3fooENS_1AE(i8*
 // WIN64-LABEL: define i8* @"\01?foo@deleted_by_member@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member::A"*
 }
 
@@ -252,8 +239,6 @@
   A();
 };
 void *foo(A a) { return a.p; }
-// NEWABI-LABEL: define i8* @_ZN15deleted_by_base3fooENS_1AE(%"struct.deleted_by_base::A"*
-// OLDABI-LABEL: define i8* @_ZN15deleted_by_base3fooENS_1AE(i8*
 // WIN64-LABEL: define i8* @"\01?foo@deleted_by_base@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base::A"*
 }
 
@@ -268,8 +253,6 @@
   B b;
 };
 void *foo(A a) { return a.b.p; }
-// NEWABI-LABEL: define i8* @_ZN22deleted_by_member_copy3fooENS_1AE(%"struct.deleted_by_member_copy::A"*
-// OLDABI-LABEL: define i8* @_ZN22deleted_by_member_copy3fooENS_1AE(i8*
 // WIN64-LABEL: define i8* @"\01?foo@deleted_by_member_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_member_copy::A"*
 }
 
@@ -283,8 +266,6 @@
   A();
 };
 void *foo(A a) { return a.p; }
-// NEWABI-LABEL: define i8* @_ZN20deleted_by_base_copy3fooENS_1AE(%"struct.deleted_by_base_copy::A"*
-// OLDABI-LABEL: define i8* @_ZN20deleted_by_base_copy3fooENS_1AE(i8*
 // WIN64-LABEL: define i8* @"\01?foo@deleted_by_base_copy@@YAPEAXUA@1@@Z"(%"struct.deleted_by_base_copy::A"*
 }
 
@@ -294,77 +275,6 @@
   A(const A &o) = delete;
   void *p;
 };
-// NEWABI-LABEL: define i8* @_ZN15explicit_delete3fooENS_1AE(%"struct.explicit_delete::A"*
-// OLDABI-LABEL: define i8* @_ZN15explicit_delete3fooENS_1AE(i8*
 // WIN64-LABEL: define i8* @"\01?foo@explicit_delete@@YAPEAXUA@1@@Z"(%"struct.explicit_delete::A"*
 void *foo(A a) { return a.p; }
 }
-
-namespace implicitly_deleted_copy_ctor {
-struct A {
-  // No move ctor due to copy assignment.
-  A &operator=(const A&);
-  // Deleted copy ctor due to rvalue ref member.
-  int &&ref;
-};
-// NEWABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(%"struct.implicitly_deleted_copy_ctor::A"*
-// OLDABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(i32*
-// WIN64-LABEL: define {{.*}} @"\01?foo@implicitly_deleted_copy_ctor@@YAAEAHUA@1@@Z"(%"struct.implicitly_deleted_copy_ctor::A"*
-int &foo(A a) { return a.ref; }
-
-struct B {
-  // Passed direct: has non-deleted trivial copy ctor.
-  B &operator=(const B&);
-  int &ref;
-};
-int &foo(B b) { return b.ref; }
-// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1BE(i32*
-// WIN64-LABEL: define {{.*}} @"\01?foo@implicitly_deleted_copy_ctor@@YAAEAHUB@1@@Z"(i64
-
-struct X { X(const X&); };
-struct Y { Y(const Y&) = default; };
-
-union C {
-  C &operator=(const C&);
-  // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
-  X x;
-  int n;
-};
-int foo(C c) { return c.n; }
-// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1CE(%"union.implicitly_deleted_copy_ctor::C"*
-// WIN64-LABEL: define {{.*}} @"\01?foo@implicitly_deleted_copy_ctor@@YAHTC@1@@Z"(%"union.implicitly_deleted_copy_ctor::C"*
-
-struct D {
-  D &operator=(const D&);
-  // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.
-  union {
-    X x;
-    int n;
-  };
-};
-int foo(D d) { return d.n; }
-// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1DE(%"struct.implicitly_deleted_copy_ctor::D"*
-// WIN64-LABEL: define {{.*}} @"\01?foo@implicitly_deleted_copy_ctor@@YAHUD@1@@Z"(%"struct.implicitly_deleted_copy_ctor::D"*
-
-union E {
-  // Passed direct: has non-deleted trivial copy ctor.
-  E &operator=(const E&);
-  Y y;
-  int n;
-};
-int foo(E e) { return e.n; }
-// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1EE(i32
-// WIN64-LABEL: define {{.*}} @"\01?foo@implicitly_deleted_copy_ctor@@YAHTE@1@@Z"(i32
-
-struct F {
-  // Passed direct: has non-deleted trivial copy ctor.
-  F &operator=(const F&);
-  union {
-    Y y;
-    int n;
-  };
-};
-int foo(F f) { return f.n; }
-// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1FE(i32
-// WIN64-LABEL: define {{.*}} @"\01?foo@implicitly_deleted_copy_ctor@@YAHUF@1@@Z"(i32
-}
diff --git a/test/CodeGenObjC/arc-bridged-cast.m b/test/CodeGenObjC/arc-bridged-cast.m
index 97a45c5..93f5d7c 100644
--- a/test/CodeGenObjC/arc-bridged-cast.m
+++ b/test/CodeGenObjC/arc-bridged-cast.m
@@ -97,3 +97,10 @@
   // CHECK-NEXT: ret void
 }
 
+// CHECK-LABEL: define %struct.__CFString* @bridge_of_paren_expr()
+CFStringRef bridge_of_paren_expr() {
+  // CHECK-NOT: call i8* @objc_retainAutoreleasedReturnValue(
+  // CHECK-NOT: call void @objc_release(
+  CFStringRef r = (__bridge CFStringRef)(CreateNSString());
+  return r;
+}
diff --git a/test/CodeGenObjC/arc.m b/test/CodeGenObjC/arc.m
index d34156e..9223d8e 100644
--- a/test/CodeGenObjC/arc.m
+++ b/test/CodeGenObjC/arc.m
@@ -7,30 +7,30 @@
 // RUN: %clang_cc1 -fobjc-runtime=macosx-10.7.0 -triple x86_64-apple-darwin11 -Wno-objc-root-class -Wno-incompatible-pointer-types -Wno-arc-unsafe-retained-assign -emit-llvm -fblocks -fobjc-arc -fobjc-runtime-has-weak -o - %s | FileCheck -check-prefix=ARC-NATIVE %s
 
 // ARC-ALIEN: declare extern_weak void @objc_storeStrong(i8**, i8*)
-// ARC-ALIEN: declare extern_weak i8* @objc_retain(i8* returned)
-// ARC-ALIEN: declare extern_weak i8* @objc_autoreleaseReturnValue(i8* returned)
+// ARC-ALIEN: declare extern_weak i8* @objc_retain(i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_autoreleaseReturnValue(i8*)
 // ARC-ALIEN: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB:#[0-9]+]]
 // ARC-ALIEN: declare extern_weak void @objc_release(i8*)
-// ARC-ALIEN: declare extern_weak i8* @objc_retainAutoreleasedReturnValue(i8* returned)
+// ARC-ALIEN: declare extern_weak i8* @objc_retainAutoreleasedReturnValue(i8*)
 // ARC-ALIEN: declare extern_weak i8* @objc_initWeak(i8**, i8*)
 // ARC-ALIEN: declare extern_weak i8* @objc_storeWeak(i8**, i8*)
 // ARC-ALIEN: declare extern_weak i8* @objc_loadWeakRetained(i8**)
 // ARC-ALIEN: declare extern_weak void @objc_destroyWeak(i8**)
-// declare extern_weak i8* @objc_autorelease(i8*)
-// ARC-ALIEN: declare extern_weak i8* @objc_retainAutorelease(i8* returned)
+// ARC-ALIEN: declare extern_weak i8* @objc_autorelease(i8*)
+// ARC-ALIEN: declare extern_weak i8* @objc_retainAutorelease(i8*)
 
 // ARC-NATIVE: declare void @objc_storeStrong(i8**, i8*)
-// ARC-NATIVE: declare i8* @objc_retain(i8* returned) [[NLB:#[0-9]+]]
-// ARC-NATIVE: declare i8* @objc_autoreleaseReturnValue(i8* returned)
+// ARC-NATIVE: declare i8* @objc_retain(i8*) [[NLB:#[0-9]+]]
+// ARC-NATIVE: declare i8* @objc_autoreleaseReturnValue(i8*)
 // ARC-NATIVE: declare i8* @objc_msgSend(i8*, i8*, ...) [[NLB]]
 // ARC-NATIVE: declare void @objc_release(i8*) [[NLB]]
-// ARC-NATIVE: declare i8* @objc_retainAutoreleasedReturnValue(i8* returned)
+// ARC-NATIVE: declare i8* @objc_retainAutoreleasedReturnValue(i8*)
 // ARC-NATIVE: declare i8* @objc_initWeak(i8**, i8*)
 // ARC-NATIVE: declare i8* @objc_storeWeak(i8**, i8*)
 // ARC-NATIVE: declare i8* @objc_loadWeakRetained(i8**)
 // ARC-NATIVE: declare void @objc_destroyWeak(i8**)
-// declare i8* @objc_autorelease(i8*)
-// ARC-NATIVE: declare i8* @objc_retainAutorelease(i8* returned)
+// ARC-NATIVE: declare i8* @objc_autorelease(i8*)
+// ARC-NATIVE: declare i8* @objc_retainAutorelease(i8*)
 
 // CHECK-LABEL: define void @test0
 void test0(id x) {
@@ -1504,9 +1504,7 @@
 // CHECK:      [[SELF:%.*]] = alloca [[TEST69:%.*]]*, align 8
 // CHECK:      [[T0:%.*]] = load [[TEST69]]*, [[TEST69]]** [[SELF]], align 8
 // CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST69]]* [[T0]] to i8*
-// CHECK-NEXT: [[RETAIN:%.*]] = call i8* @objc_retain(i8* [[T1]])
-// CHECK-NEXT: [[AUTORELEASE:%.*]] = tail call i8* @objc_autoreleaseReturnValue(i8* [[RETAIN]])
-// CHECK-NEXT: ret i8* [[AUTORELEASE]]
+// CHECK-NEXT: ret i8* [[T1]]
 
 // rdar://problem/10907547
 void test70(id i) {
diff --git a/test/CodeGenObjC/debug-info-block-captured-self.m b/test/CodeGenObjC/debug-info-block-captured-self.m
index e142a0b..302a011 100644
--- a/test/CodeGenObjC/debug-info-block-captured-self.m
+++ b/test/CodeGenObjC/debug-info-block-captured-self.m
@@ -56,7 +56,7 @@
 // CHECK-NEXT:   [[DBGADDR:%.*]] = alloca [[BLOCK_T:<{.*}>]]*, align 8
 // CHECK:        store i8* [[BLOCK_DESC:%.*]], i8** %[[MEM1]], align 8
 // CHECK:        %[[TMP0:.*]] = load i8*, i8** %[[MEM1]]
-// CHECK:        call void @llvm.dbg.value(metadata i8* %[[TMP0]], i64 0, metadata ![[BDMD:[0-9]+]], metadata !{{.*}})
+// CHECK:        call void @llvm.dbg.value(metadata i8* %[[TMP0]], metadata ![[BDMD:[0-9]+]], metadata !{{.*}})
 // CHECK:        call void @llvm.dbg.declare(metadata i8* [[BLOCK_DESC]], metadata ![[BDMD:[0-9]+]], metadata !{{.*}})
 // CHECK:        store [[BLOCK_T]]* {{%.*}}, [[BLOCK_T]]** [[DBGADDR]], align 8
 // CHECK:        call void @llvm.dbg.declare(metadata [[BLOCK_T]]** [[DBGADDR]], metadata ![[SELF:.*]], metadata !{{.*}})
diff --git a/test/CodeGenObjC/local-static-block.m b/test/CodeGenObjC/local-static-block.m
index 73c670f..67ede63 100644
--- a/test/CodeGenObjC/local-static-block.m
+++ b/test/CodeGenObjC/local-static-block.m
@@ -46,6 +46,17 @@
  }
 }
 
+void FUNC2() {
+  static void (^const block1)(int) = ^(int a){
+    if (a--)
+      block1(a);
+  };
+}
+
+// CHECK-LABEL-LP64: define void @FUNC2(
+// CHECK: define internal void @_block_invoke{{.*}}(
+// CHECK: call void %{{.*}}(i8* bitcast ({ i8**, i32, i32, i8*, %struct.__block_descriptor* }* @__block_literal_global{{.*}} to i8*), i32 %{{.*}})
+
 void FUNC1()
 {
  static  NSArray *(^ArrayRecurs)(NSArray *addresses, unsigned long level) = ^(NSArray *addresses, unsigned long level) {
diff --git a/test/CodeGenObjC/mangle-blocks.m b/test/CodeGenObjC/mangle-blocks.m
index 4cc3204..73522cd 100644
--- a/test/CodeGenObjC/mangle-blocks.m
+++ b/test/CodeGenObjC/mangle-blocks.m
@@ -18,11 +18,11 @@
 @end
 
 // CHECK: @"__func__.__14-[Test mangle]_block_invoke_2" = private unnamed_addr constant [30 x i8] c"-[Test mangle]_block_invoke_2\00", align 1
-// CHECK: @.str = private unnamed_addr constant {{.*}}, align 1
-// CHECK: @.str.1 = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
+// CHECK: @.str{{.*}} = private unnamed_addr constant {{.*}}, align 1
+// CHECK: @.str[[STR1:.*]] = private unnamed_addr constant [7 x i8] c"mangle\00", align 1
 
 // CHECK: define internal void @"__14-[Test mangle]_block_invoke"(i8* %.block_descriptor)
 
 // CHECK: define internal void @"__14-[Test mangle]_block_invoke_2"(i8* %.block_descriptor){{.*}}{
-// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 14, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i32 0, i32 0))
+// CHECK: call void @__assert_rtn(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @"__func__.__14-[Test mangle]_block_invoke_2", i32 0, i32 0), i8* getelementptr inbounds {{.*}}, i32 14, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str[[STR1]], i32 0, i32 0))
 // CHECK: }
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
index d3b2869..4d46b40 100644
--- a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
@@ -1,131 +1,128 @@
 // RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa -mcpu=fiji -o - %s | FileCheck %s
 // RUN: %clang -cl-std=CL2.0 -emit-llvm -g -O0 -S -target amdgcn-amd-amdhsa-opencl -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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR0]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR1]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR2]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR3]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR4]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR5]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR6]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR7]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR8]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR9]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR10]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR11]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR12]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR13]], expr: !DIExpression())
 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]])
+// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FILEVAR14]], expr: !DIExpression())
 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]+}}
+    // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[KERNELARG0]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+    // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[KERNELARG1]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+    // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[KERNELARG2]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR0]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR1]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR2]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR3]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR4]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
   int *FuncVar4 = Tmp1;
 
   // CHECK-DAG: ![[FUNCVAR5:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
-  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR5]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR5]], expr: !DIExpression())
   global int *constant FuncVar5 = 0;
   // CHECK-DAG: ![[FUNCVAR6:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
-  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR6]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR6]], expr: !DIExpression())
   constant int *constant FuncVar6 = 0;
   // CHECK-DAG: ![[FUNCVAR7:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
-  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR7]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR7]], expr: !DIExpression())
   local int *constant FuncVar7 = 0;
   // CHECK-DAG: ![[FUNCVAR8:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
-  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR8]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR8]], expr: !DIExpression())
   private int *constant FuncVar8 = 0;
   // CHECK-DAG: ![[FUNCVAR9:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
-  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR9]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR9]], expr: !DIExpression())
   int *constant FuncVar9 = 0;
 
   // 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]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
   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]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR11]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
   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]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR12]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
   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]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR13]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
   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]])
+  // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR14]], expr: !DIExpression(DW_OP_constu, 2, DW_OP_swap, DW_OP_xderef))
   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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR15]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR16]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR17]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR18]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !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]+}}
+  // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR19]], metadata !DIExpression(DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef)), !dbg !{{[0-9]+}}
   int *private FuncVar19 = Tmp1;
 }
diff --git a/test/CoverageMapping/deferred-region.cpp b/test/CoverageMapping/deferred-region.cpp
new file mode 100644
index 0000000..743b635
--- /dev/null
+++ b/test/CoverageMapping/deferred-region.cpp
@@ -0,0 +1,173 @@
+// RUN: %clang_cc1 -std=c++11 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fexceptions -fcxx-exceptions -emit-llvm-only -triple %itanium_abi_triple -main-file-name deferred-region.cpp %s | FileCheck %s
+
+#define IF if
+#define STMT(S) S
+
+// CHECK-LABEL: _Z3fooi:
+void foo(int x) {
+  if (x == 0) {
+    return;
+  } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:2 = (#0 - #1)
+
+}
+
+// CHECK-NEXT: _Z4foooi:
+void fooo(int x) {
+  if (x == 0) {
+    return;
+  } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:3 = (#0 - #1)
+
+  if (x == 1) {
+    return;
+  } // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE+2]]:2 = ((#0 - #1) - #2)
+
+}
+
+// CHECK-LABEL: _Z3bazv:
+void baz() { // CHECK: [[@LINE]]:12 -> [[@LINE+2]]:2
+  return;    // CHECK-NOT: File
+}
+
+// CHECK-LABEL: _Z3mazv:
+void maz() {
+  if (true)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11 -> 36:3 = (#0 - #1)
+
+  return; // CHECK-NOT: Gap
+}
+
+// CHECK-LABEL: _Z3bari:
+void bar(int x) {
+  IF (x)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+
+  IF (!x)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = ((#0 - #1) - #2)
+
+  foo(x);
+}
+
+// CHECK-LABEL: _Z4quuxi:
+// Deferred regions are not emitted within macro expansions.
+void quux(int x) {
+  STMT(
+  if (x == 0)
+    return;)
+
+  // CHECK-NOT: [[@LINE-2]]:{{.*}} -> [[@LINE+2]]
+
+  if (x == 1)
+    STMT(return;)
+
+  // CHECK-NOT: [[@LINE-2]]:{{.*}} -> [[@LINE+3]]
+
+  STMT(
+  if (x == 2)
+    return;
+
+  // CHECK-NOT: [[@LINE-2]]:{{.*}} -> [[@LINE+2]]
+
+  if (x == 3)
+    return;
+  )
+}
+
+// CHECK-LABEL: _Z8weird_ifv:
+void weird_if() {
+  int i = 0;
+
+  if (false)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+
+  if (false)
+    i++;
+
+  if (i + 100 > 0) { // CHECK: [[@LINE]]:20 -> [[@LINE+6]]:4 = #3
+    if (false)       // CHECK: [[@LINE+1]]:7 -> [[@LINE+1]]:13 = #4
+      return;        // CHECK: Gap,File 0, [[@LINE]]:13 -> [[@LINE+2]]:5 = (#3 - #4)
+                     // CHECK: [[@LINE+1]]:5 -> [[@LINE+3]]:4 = (#3 - #4)
+    return;          // CHECK: Gap,File 0, [[@LINE]]:5 -> [[@LINE+4]]:3 = ((#0 - #1) - #3)
+
+  }
+
+  if (false)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+1]]:2
+}
+
+// CHECK-LABEL: _Z8for_loopv:
+void for_loop() {
+  if (false)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+
+  for (int i = 0; i < 10; ++i) {
+    if (i % 2 == 0)
+      continue; // CHECK: Gap,File 0, [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
+
+    if (i % 5 == 0)
+      break; // CHECK: Gap,File 0, [[@LINE]]:12 -> [[@LINE+2]]:5 = ((#2 - #3) - #4)
+
+    int x = i; // CHECK: [[@LINE]]:5 -> [[@LINE+3]]:4 = ((#2 - #3) - #4)
+    return; // CHECK-NOT: [[@LINE]]:11 -> [[@LINE+2]]
+
+  }
+}
+
+struct Error {};
+
+// CHECK-LABEL: _Z10while_loopv:
+void while_loop() {
+  if (false)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11 -> [[@LINE+2]]:3 = (#0 - #1)
+
+  int x = 0;
+  while (++x < 10) {
+    if (x == 1)
+      continue; // CHECK: Gap,File 0, [[@LINE]]:15 -> [[@LINE+2]]:5 = (#2 - #3)
+
+    while (++x < 4) {
+      if (x == 3)
+        break; // CHECK: Gap,File 0, [[@LINE]]:14 -> [[@LINE+2]]:7 = (#4 - #5)
+
+      while (++x < 5) {}
+    }
+
+    if (x == 0)
+      throw Error(); // CHECK: Gap,File 0, [[@LINE]]:20 -> [[@LINE+2]]:5 = ((#2 - #3) - #7)
+
+    while (++x < 9) {
+      if (x == 0)
+        break; // CHECK-NOT: [[@LINE]]:14 -> [[@LINE+2]]
+
+    }
+  }
+}
+
+// CHECK-LABEL: _Z5gotosv:
+void gotos() {
+  if (false)
+    goto out; // CHECK: Gap,File 0, [[@LINE]]:13 -> [[@LINE+2]]:3 = (#0 - #1)
+
+  return; // CHECK: [[@LINE]]:3 -> [[@LINE+4]]:2 = (#0 - #1)
+
+out:
+	return; // CHECK: Gap,File 0, [[@LINE]]:8 -> [[@LINE+1]]:2 = 0
+}
+
+int main() {
+  foo(0);
+  foo(1);
+  fooo(0);
+  fooo(1);
+  baz();
+  bar(0);
+  bar(1);
+  quux(0);
+  quux(1);
+  quux(2);
+  quux(3);
+  weird_if();
+  for_loop();
+  while_loop();
+  gotos();
+  return 0;
+}
diff --git a/test/CoverageMapping/label.cpp b/test/CoverageMapping/label.cpp
index 1c5111a6..aec5e4f 100644
--- a/test/CoverageMapping/label.cpp
+++ b/test/CoverageMapping/label.cpp
@@ -14,19 +14,22 @@
       int m = 2;
     } else
       goto x;                // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = (#1 - #2)
-    int k = 3;               // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+1]]:4 = #3
-  }
-  static int j = 0;          // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:2 = ((#0 + #3) - #1)
+    int k = 3;               // CHECK-NEXT: File 0, [[@LINE-1]]:13 -> [[@LINE]]:5 = #3
+  }                          // CHECK-NEXT: File 0, [[@LINE-1]]:5 -> [[@LINE]]:4 = #3
+  static int j = 0;          // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:2 = ((#0 + #3) - #1)
   ++j;
   if(j == 1)                 // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:12 = ((#0 + #3) - #1)
     goto x;                  // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #4
+                             // CHECK-NEXT: File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:2 = (((#0 + #3) - #1) - #4)
 }
 
                              // CHECK-NEXT: test1
 void test1(int x) {          // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2 = #0
   if(x == 0)                 // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:12 = #0
     goto a;                  // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
-  goto b;                    // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:9 = (#0 - #1)
+                             // CHECK-NEXT: File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = (#0 - #1)
+  goto b;                    // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+5]]:2 = (#0 - #1)
+                             // CHECK-NEXT: File 0, [[@LINE-1]]:3 -> [[@LINE+4]]:2 = #3
 a:                           // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+3]]:2 = #2
 b:                           // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+2]]:2 = #3
   x = x + 1;
@@ -36,9 +39,11 @@
 void test2(int x) {          // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2 = #0
   if(x == 0)                 // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE]]:12 = #0
     goto a;                  // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
-                             // CHECK-NEXT: File 0, [[@LINE+2]]:8 -> [[@LINE+2]]:25 = (#0 - #1)
+                             // CHECK-NEXT: File 0, [[@LINE-1]]:11 -> [[@LINE+3]]:8 = #0
+                             // CHECK-NEXT: File 0, [[@LINE+2]]:8 -> [[@LINE+3]]:11 = (#0 - #1)
                              // CHECK-NEXT: File 0, [[@LINE+1]]:11 -> [[@LINE+1]]:17 = (#0 - #1)
-  else if(x == 1) goto b;    // CHECK-NEXT: File 0, [[@LINE]]:19 -> [[@LINE]]:25 = #2
+  else if(x == 1)            // CHECK-NEXT: File 0, [[@LINE+1]]:5 -> [[@LINE+1]]:11 = #2
+    goto b;                  // CHECK-NEXT: File 0, [[@LINE]]:11 -> [[@LINE+1]]:1 = #3
 a:                           // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+3]]:2 = #3
 b:                           // CHECK-NEXT: File 0, [[@LINE]]:1 -> [[@LINE+2]]:2 = #4
   x = x + 1;
@@ -47,11 +52,13 @@
                              // CHECK-NEXT: main
 int main() {                 // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
   int j = 0;
-  for(int i = 0; i < 10; ++i) { // CHECK: File 0, [[@LINE]]:31 -> [[@LINE+11]]:4 = #1
-  a:                         // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+10]]:4 = #2
+  for(int i = 0; i < 10; ++i) { // CHECK: File 0, [[@LINE]]:31 -> [[@LINE+13]]:4 = #1
+  a:                         // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+12]]:4 = #2
     if(i < 3)                // CHECK-NEXT: File 0, [[@LINE]]:8 -> [[@LINE]]:13 = #2
       goto e;                // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = #3
-    goto c;                  // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = (#2 - #3)
+                             // CHECK-NEXT: File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:5 = (#2 - #3)
+    goto c;                  // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+8]]:4 = (#2 - #3)
+
   b:                         // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+6]]:4 = #4
     j = 2;
   c:                         // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+4]]:4 = #5
diff --git a/test/CoverageMapping/md.cpp b/test/CoverageMapping/md.cpp
index 20c696c..5f2b2d6 100644
--- a/test/CoverageMapping/md.cpp
+++ b/test/CoverageMapping/md.cpp
@@ -27,6 +27,17 @@
   #include "Inputs/md.def"
 }
 
+// CHECK: bar
+// CHECK-NEXT: File 0, [[@LINE+3]]:12 -> [[@LINE+8]]:2 = #0
+bool isVal1();
+bool isVal2();
+bool bar() {
+ #define HANDLE_MD(X) is##X() ||
+  return
+#include "Inputs/md.def"
+  0;
+}
+
 int main(int argc, const char *argv[]) {
   foo(MD::Val1);
   return 0;
diff --git a/test/CoverageMapping/moremacros.c b/test/CoverageMapping/moremacros.c
index 5666227..630b75d 100644
--- a/test/CoverageMapping/moremacros.c
+++ b/test/CoverageMapping/moremacros.c
@@ -15,7 +15,7 @@
   if (!argc) LBRAC
     return 0;
   // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #2
-  RBRAC
+  RBRAC // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE+6]]:3 = (#0 - #2)
 
   // CHECK-NEXT: File 0, [[@LINE+4]]:3 -> [[@LINE+15]]:2 = (#0 - #2)
   // CHECK-NEXT: File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:12 = (#0 - #2)
@@ -23,7 +23,7 @@
   // CHECK-NEXT: File 0, [[@LINE+1]]:19 -> [[@LINE+3]]:4 = #3
   if (!argc) LBRAC
     return 0;
-  }
+  } // CHECK-NEXT: [[@LINE]]:4 -> [[@LINE+5]]:3 = ((#0 - #2) - #3)
 
   // CHECK-NEXT: File 0, [[@LINE+3]]:3 -> [[@LINE+7]]:2 = ((#0 - #2) - #3)
   // CHECK-NEXT: File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:12 = ((#0 - #2) - #3)
@@ -31,7 +31,7 @@
   if (!argc) {
     return 0;
   // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:8 = #4
-  RBRAC
+  RBRAC // CHECK-NEXT: [[@LINE]]:8 -> [[@LINE+1]]:2 = (((#0 - #2) - #3) - #4)
 }
 
 // CHECK-NEXT: File 1, 3:15 -> 3:16 = #2
diff --git a/test/CoverageMapping/preprocessor.c b/test/CoverageMapping/preprocessor.c
index bd82b39..cce8b67 100644
--- a/test/CoverageMapping/preprocessor.c
+++ b/test/CoverageMapping/preprocessor.c
@@ -3,36 +3,69 @@
                  // CHECK: func
 void func() {    // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+5]]:2 = #0
   int i = 0;
-#ifdef MACRO     // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+2]]:2 = 0
+#ifdef MACRO     // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+3]]:1 = 0
   int x = i;
 #endif
 }
 
-#if 0
-  int g = 0;
-
-  void bar() { }
-#endif
-
                  // CHECK: main
 int main() {     // CHECK-NEXT: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
   int i = 0;
-#if 0            // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+4]]:2 = 0
+#  if 0            // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+5]]:1 = 0
   if(i == 0) {
     i = 1;
   }
-#endif
+#  endif // Mark me skipped!
 
 #if 1
                  // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
   if(i == 0) {   // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #1
     i = 1;
   }
-#else            // CHECK-NEXT: Skipped,File 0, [[@LINE]]:2 -> [[@LINE+5]]:2 = 0
+#else            // CHECK-NEXT: Skipped,File 0, [[@LINE]]:1 -> [[@LINE+6]]:1 = 0
   if(i == 1) {
     i = 0;
   }
 }
 #endif
+
+  // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+5]]:1
+#\
+  if 0
+#\
+  endif // also skipped
+
+#if 1
+  // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+4]]:1
+#\
+  elif 0
+#endif
+
+#if 1
+  // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+4]]:1
+#\
+  else
+#endif
+
+  // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+5]]:1
+#\
+  ifdef NOT_DEFINED
+#\
+  endif
+
+  // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+5]]:1
+#\
+  ifndef __FILE__
+#\
+  endif
+
+  // CHECK-NEXT: Skipped,File 0, [[@LINE+1]]:1 -> [[@LINE+7]]:1
+#\
+  ifdef NOT_DEFINED
+#\
+  \
+   \
+    endif // also skipped
+
   return 0;
 }
diff --git a/test/CoverageMapping/return.c b/test/CoverageMapping/return.c
index 1b190b0..3cc271b 100644
--- a/test/CoverageMapping/return.c
+++ b/test/CoverageMapping/return.c
@@ -13,7 +13,7 @@
   for(int i = 0; i < 10; ++i) { // CHECK-NEXT: File 0, [[@LINE]]:31 -> {{[0-9]+}}:4 = #1
                                 // CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:13 = #1
     if(i > 2) {                 // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+2]]:6 = #2
-      return;
+      return;                   // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+3]]:5 = (#1 - #2)
     }                           // CHECK-NEXT: File 0, [[@LINE+2]]:5 -> {{[0-9]+}}:4 = (#1 - #2)
                                 // CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:14 = (#1 - #2)
     if(i == 3) {                // CHECK-NEXT: File 0, [[@LINE]]:16 -> [[@LINE+2]]:6 = #3
diff --git a/test/CoverageMapping/switch.cpp b/test/CoverageMapping/switch.cpp
index 312f26c..d347e66 100644
--- a/test/CoverageMapping/switch.cpp
+++ b/test/CoverageMapping/switch.cpp
@@ -3,10 +3,10 @@
                     // CHECK: foo
 void foo(int i) {   // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+8]]:2 = #0
   switch(i) {
-  case 1:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #2
+  case 1:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:11 = #2
     return;
   case 2:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #3
-    break;
+    break;          // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+2]]:3 = #1
   }
   int x = 0;        // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:2 = #1
 }
@@ -48,23 +48,23 @@
 int main() {        // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+35]]:2 = #0
   int i = 0;
   switch(i) {
-  case 0:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+7]]:10 = #2
+  case 0:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #2
     i = 1;
     break;
   case 1:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #3
     i = 2;
     break;
   default:          // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = #4
-    break;
+    break;          // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+2]]:3 = #1
   }
   switch(i) {       // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+23]]:2 = #1
-  case 0:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+6]]:10 = #6
+  case 0:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = #6
     i = 1;
     break;
   case 1:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #7
     i = 2;
   default:          // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:10 = (#7 + #8)
-    break;
+    break;          // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+3]]:3 = #5
   }
 
   switch(i) {       // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+13]]:2 = #5
@@ -81,3 +81,32 @@
   baz();
   return 0;
 }
+
+// FIXME: End location for "case 1" shouldn't point at the end of the switch.
+                         // CHECK: fallthrough
+int fallthrough(int i) { // CHECK-NEXT: File 0, [[@LINE]]:24 -> [[@LINE+12]]:2 = #0
+  switch(i) {
+  case 1:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+8]]:10 = #2
+    i = 23;
+  case 2:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = (#2 + #3)
+    i = 11;
+    break;
+  case 3:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = #4
+  case 4:           // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = (#4 + #5)
+    i = 99;
+    break;
+  }
+}
+
+void abort(void) __attribute((noreturn));
+                   // CHECK: noret
+int noret(int x) { // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+9]]:2
+  switch (x) {
+  default:         // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:12
+    abort();
+  case 1:         // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13
+    return 5;
+  case 2:         // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:14
+    return 10;
+  }
+}
diff --git a/test/CoverageMapping/switchmacro.c b/test/CoverageMapping/switchmacro.c
index 55f93d8..8fb1b83 100644
--- a/test/CoverageMapping/switchmacro.c
+++ b/test/CoverageMapping/switchmacro.c
@@ -8,6 +8,7 @@
   default:       // CHECK-NEXT: File 0, [[@LINE]]:3 -> {{[0-9]+}}:11 = #2
     if (i == 1)  // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = #2
       return 0;  // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = #3
+                 // CHECK-NEXT: File 0, [[@LINE-1]]:15 -> [[@LINE+3]]:5 = (#2 - #3)
     // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:5 -> [[@LINE+2]]:8 = (#2 - #3) (Expanded file = 1)
     // CHECK-NEXT: File 0, [[@LINE+1]]:8 -> {{[0-9]+}}:11 = (#2 - #3)
     FOO(1);
diff --git a/test/CoverageMapping/trycatch.cpp b/test/CoverageMapping/trycatch.cpp
index 01d8fb9..37b35d3 100644
--- a/test/CoverageMapping/trycatch.cpp
+++ b/test/CoverageMapping/trycatch.cpp
@@ -18,7 +18,7 @@
                                       // CHECK-NEXT: File 0, [[@LINE+1]]:10 -> [[@LINE+2]]:27 = (#0 - #1)
   } else if(i == 8)                   // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE]]:19 = (#0 - #1)
     throw ImportantError();           // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:27 = #2
-}
+}                                     // CHECK-NEXT: File 0, [[@LINE-1]]:27 -> [[@LINE]]:2 = ((#0 - #1) - #2)
 
                                       // CHECK-NEXT: main
 int main() {                          // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+13]]:2 = #0
diff --git a/test/Driver/Inputs/resource_dir/ubsan_blacklist.txt b/test/Driver/Inputs/resource_dir/ubsan_blacklist.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test/Driver/Inputs/resource_dir/ubsan_blacklist.txt
diff --git a/test/Driver/clang-translation.c b/test/Driver/clang-translation.c
index 3b30f7a..7021f13 100644
--- a/test/Driver/clang-translation.c
+++ b/test/Driver/clang-translation.c
@@ -73,6 +73,22 @@
 // RUN: FileCheck -check-prefix=ARM64-APPLE %s
 // ARM64-APPLE: -munwind-table
 
+// RUN: %clang -target arm64-apple-ios10 -### -ffreestanding -S %s -arch arm64 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM64-FREESTANDING-APPLE %s
+//
+// RUN: %clang -target arm64-apple-ios10 -### -fno-unwind-tables -ffreestanding -S %s -arch arm64 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM64-FREESTANDING-APPLE %s
+//
+// ARM64-FREESTANDING-APPLE-NOT: -munwind-table
+
+// RUN: %clang -target arm64-apple-ios10 -### -funwind-tables -S %s -arch arm64 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM64-EXPLICIT-UWTABLE-APPLE %s
+//
+// RUN: %clang -target arm64-apple-ios10 -### -ffreestanding -funwind-tables -S %s -arch arm64 2>&1 | \
+// RUN: FileCheck -check-prefix=ARM64-EXPLICIT-UWTABLE-APPLE %s
+//
+// ARM64-EXPLICIT-UWTABLE-APPLE: -munwind-table
+
 // RUN: %clang -target arm64-apple-ios10 -fno-exceptions -### -S %s -arch arm64 2>&1 | \
 // RUN: FileCheck -check-prefix=ARM64-APPLE-EXCEP %s
 // ARM64-APPLE-EXCEP-NOT: -munwind-table
diff --git a/test/Driver/darwin-ld.c b/test/Driver/darwin-ld.c
index 36e7ee5..4358d38 100644
--- a/test/Driver/darwin-ld.c
+++ b/test/Driver/darwin-ld.c
@@ -341,3 +341,13 @@
 // RUN: %clang -target x86_64-apple-darwin12 %t.o -fsave-optimization-record -fprofile-instr-use=blah -### -o foo/bar.out 2> %t.log
 // RUN: FileCheck -check-prefix=PASS_REMARKS_WITH_HOTNESS %s < %t.log
 // PASS_REMARKS_WITH_HOTNESS: "-mllvm" "-lto-pass-remarks-output" "-mllvm" "foo/bar.out.opt.yaml" "-mllvm" "-lto-pass-remarks-with-hotness"
+
+// RUN: %clang -target x86_64-apple-ios6.0 -miphoneos-version-min=6.0 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
+// RUN: %clang -target i386-apple-darwin9 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
+// RUN: %clang -target arm64-apple-ios5.0 -miphoneos-version-min=5.0 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=LINK_PROFILE_FIRST %s < %t.log
+// LINK_PROFILE_FIRST: {{ld(.exe)?"}} "{{[^"]+}}libclang_rt.profile_{{[a-z]+}}.a"
diff --git a/test/Driver/flags.c b/test/Driver/flags.c
index 656ac41..ff60caf 100644
--- a/test/Driver/flags.c
+++ b/test/Driver/flags.c
@@ -24,6 +24,3 @@
 
 // RUN: %clang -target armv7-apple-darwin10 -### -S -mno-implicit-float -mimplicit-float %s 2>&1 | FileCheck -check-prefix=TEST8 %s
 // TEST8-NOT: "-no-implicit-float"
-
-// RUN: %clang -target x86_64-linux-gnu -### -c -fclang-abi-compat=3.2 %s 2>&1 | FileCheck -check-prefix=TEST9 %s
-// TEST9: "-fclang-abi-compat=3.2"
diff --git a/test/Driver/fsanitize-blacklist.c b/test/Driver/fsanitize-blacklist.c
index adf776f..9268bb2 100644
--- a/test/Driver/fsanitize-blacklist.c
+++ b/test/Driver/fsanitize-blacklist.c
@@ -23,6 +23,12 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-BLACKLIST --implicit-check-not=fdepfile-entry
 // CHECK-DEFAULT-BLACKLIST: -fsanitize-blacklist={{.*}}asan_blacklist.txt
 
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=integer -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=nullability -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=alignment -resource-dir=%S/Inputs/resource_dir %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DEFAULT-UBSAN-BLACKLIST --implicit-check-not=fdepfile-entry
+// CHECK-DEFAULT-UBSAN-BLACKLIST: -fsanitize-blacklist={{.*}}ubsan_blacklist.txt
+
 // Ignore -fsanitize-blacklist flag if there is no -fsanitize flag.
 // RUN: %clang -target x86_64-linux-gnu -fsanitize-blacklist=%t.good %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SANITIZE --check-prefix=DELIMITERS
 // CHECK-NO-SANITIZE-NOT: -fsanitize-blacklist
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index 0752ef6..5f749d0 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -3,18 +3,18 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined-trap -fsanitize-undefined-trap-on-error %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
 // RUN: %clang -target x86_64-linux-gnu -fsanitize-undefined-trap-on-error -fsanitize=undefined-trap %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-TRAP
-// CHECK-UNDEFINED-TRAP: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute|function),?){18}"}}
-// CHECK-UNDEFINED-TRAP: "-fsanitize-trap=alignment,array-bounds,bool,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound"
-// CHECK-UNDEFINED-TRAP2: "-fsanitize-trap=alignment,array-bounds,bool,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,unreachable,vla-bound"
+// CHECK-UNDEFINED-TRAP: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){19}"}}
+// CHECK-UNDEFINED-TRAP: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,signed-integer-overflow,unreachable,vla-bound"
+// CHECK-UNDEFINED-TRAP2: "-fsanitize-trap=alignment,array-bounds,bool,builtin,enum,float-cast-overflow,float-divide-by-zero,function,integer-divide-by-zero,nonnull-attribute,null,pointer-overflow,return,returns-nonnull-attribute,shift-base,shift-exponent,unreachable,vla-bound"
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED
-// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){19}"}}
+// CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){20}"}}
 
 // RUN: %clang -target x86_64-apple-darwin10 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-DARWIN
-// CHECK-UNDEFINED-DARWIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
+// CHECK-UNDEFINED-DARWIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){19}"}}
 
 // RUN: %clang -target i386-unknown-openbsd -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-OPENBSD
-// CHECK-UNDEFINED-OPENBSD: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
+// CHECK-UNDEFINED-OPENBSD: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
 
 // RUN: %clang -target i386-pc-win32 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32
 // RUN: %clang -target i386-pc-win32 -fsanitize=undefined -x c++ %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-WIN --check-prefix=CHECK-UNDEFINED-WIN32 --check-prefix=CHECK-UNDEFINED-WIN-CXX
@@ -23,7 +23,7 @@
 // CHECK-UNDEFINED-WIN32: "--dependent-lib={{[^"]*}}ubsan_standalone-i386.lib"
 // CHECK-UNDEFINED-WIN64: "--dependent-lib={{[^"]*}}ubsan_standalone-x86_64.lib"
 // CHECK-UNDEFINED-WIN-CXX: "--dependent-lib={{[^"]*}}ubsan_standalone_cxx{{[^"]*}}.lib"
-// CHECK-UNDEFINED-WIN-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
+// CHECK-UNDEFINED-WIN-SAME: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
 
 // RUN: %clang -target i386-pc-win32 -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-COVERAGE-WIN32
 // CHECK-COVERAGE-WIN32: "--dependent-lib={{[^"]*}}ubsan_standalone-i386.lib"
@@ -42,7 +42,7 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=address,undefined -fno-sanitize=all -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FNO-SANITIZE-ALL
 // CHECK-FNO-SANITIZE-ALL: "-fsanitize=thread"
 
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-sanitize=thread -fno-sanitize=float-cast-overflow,vptr,bool,enum %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread,undefined -fno-sanitize=thread -fno-sanitize=float-cast-overflow,vptr,bool,builtin,enum %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-UNDEFINED
 // CHECK-PARTIAL-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|array-bounds|returns-nonnull-attribute|nonnull-attribute),?){15}"}}
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=shift -fno-sanitize=shift-base %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSANITIZE-SHIFT-PARTIAL
@@ -217,7 +217,7 @@
 // RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=undefined -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
 // RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=all -fsanitize-recover=thread -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
 // RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fsanitize-recover=all -fno-sanitize-recover=undefined -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-RECOVER-UBSAN
-// CHECK-RECOVER-UBSAN: "-fsanitize-recover={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|returns-nonnull-attribute|nonnull-attribute),?){17}"}}
+// CHECK-RECOVER-UBSAN: "-fsanitize-recover={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift-base|shift-exponent|vla-bound|alignment|null|vptr|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute),?){18}"}}
 // CHECK-NO-RECOVER-UBSAN-NOT: sanitize-recover
 
 // RUN: %clang -target x86_64-linux-gnu %s -fsanitize=undefined -fno-sanitize-recover=all -fsanitize-recover=object-size,shift-base -### 2>&1 | FileCheck %s --check-prefix=CHECK-PARTIAL-RECOVER
@@ -354,10 +354,8 @@
 // CHECK-TSAN-ATOMICS-BOTH-OFF: -cc1{{.*}}tsan-instrument-atomics=0
 
 // RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-DARWIN
-// CHECK-FSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'
-
-// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-UBSAN-DARWIN
-// CHECK-FSAN-UBSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'
+// RUN: %clang -target i386-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-DARWIN
+// CHECK-FSAN-DARWIN: -cc1{{.*}}"-fsanitize=function" "-fsanitize-recover=function"
 
 // RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.8 -fsanitize=vptr %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-VPTR-DARWIN-OLD
 // CHECK-VPTR-DARWIN-OLD: unsupported option '-fsanitize=vptr' for target 'x86_64-apple-darwin10'
@@ -535,3 +533,32 @@
 // Make sure there are no *.{o,bc} or -l passed before the ASan library.
 // CHECK-ASAN-PS4-NOT: {{(\.(o|bc)"? |-l).*-lSceDbgAddressSanitizer_stub_weak}}
 // CHECK-ASAN-PS4: -lSceDbgAddressSanitizer_stub_weak
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-MINIMAL
+// CHECK-ASAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=address'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MINIMAL
+// CHECK-TSAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=thread'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-MINIMAL
+// CHECK-UBSAN-MINIMAL: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift-base|shift-exponent|unreachable|return|vla-bound|alignment|null|pointer-overflow|float-cast-overflow|array-bounds|enum|bool|builtin|returns-nonnull-attribute|nonnull-attribute|function),?){19}"}}
+// CHECK-UBSAN-MINIMAL: "-fsanitize-minimal-runtime"
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined -fsanitize=vptr -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-VPTR-MINIMAL
+// CHECK-UBSAN-VPTR-MINIMAL: error: invalid argument '-fsanitize=vptr' not allowed with '-fsanitize-minimal-runtime'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-minimal-runtime -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-UBSAN-MINIMAL
+// CHECK-ASAN-UBSAN-MINIMAL: error: invalid argument '-fsanitize-minimal-runtime' not allowed with '-fsanitize=address'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-MINIMAL
+// CHECK-CFI-MINIMAL: "-fsanitize=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
+// CHECK-CFI-MINIMAL: "-fsanitize-trap=cfi-derived-cast,cfi-icall,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
+// CHECK-CFI-MINIMAL: "-fsanitize-minimal-runtime"
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -fno-sanitize-trap=cfi-icall -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOTRAP-MINIMAL
+// CHECK-CFI-NOTRAP-MINIMAL: error: invalid argument 'fsanitize-minimal-runtime' only allowed with 'fsanitize-trap=cfi'
+
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=cfi -fno-sanitize-trap=cfi-icall -fno-sanitize=cfi-icall -flto -fvisibility=hidden -fsanitize-minimal-runtime %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-CFI-NOICALL-MINIMAL
+// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
+// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-trap=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
+// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-minimal-runtime"
diff --git a/test/Driver/fuzzer.c b/test/Driver/fuzzer.c
index 989b3b9..083f950 100644
--- a/test/Driver/fuzzer.c
+++ b/test/Driver/fuzzer.c
@@ -2,7 +2,7 @@
 
 // RUN: %clang -fsanitize=fuzzer %s -target x86_64-apple-darwin14 -### 2>&1 | FileCheck --check-prefixes=CHECK-FUZZER-LIB,CHECK-COVERAGE-FLAGS %s
 //
-// CHECK-FUZZER-LIB: libLLVMFuzzer.a
+// CHECK-FUZZER-LIB: libclang_rt.fuzzer
 // CHECK-COVERAGE: -fsanitize-coverage-trace-pc-guard
 // CHECK-COVERAGE-SAME: -fsanitize-coverage-indirect-calls
 // CHECK-COVERAGE-SAME: -fsanitize-coverage-trace-cmp
@@ -18,7 +18,12 @@
 
 // Check that we don't link in libFuzzer.a when producing a shared object.
 // RUN: %clang -fsanitize=fuzzer %s -shared -o %t.so -### 2>&1 | FileCheck --check-prefixes=CHECK-NOLIB-SO %s
-// CHECK-NOLIB-SO-NOT: libLLVMFuzzer.a
+// CHECK-NOLIB-SO-NOT: libclang_rt.libfuzzer
+
+// Check that we don't link in libFuzzer when compiling with -fsanitize=fuzzer-no-link.
+// RUN: %clang -fsanitize=fuzzer-no-link %s -target x86_64-apple-darwin14 -### 2>&1 | FileCheck --check-prefixes=CHECK-NOLIB,CHECK-COV %s
+// CHECK-NOLIB-NOT: libclang_rt.libfuzzer
+// CHECK-COV: -fsanitize-coverage-trace-pc-guard
 
 // RUN: %clang -fsanitize=fuzzer -fsanitize-coverage=trace-pc %s -### 2>&1 | FileCheck --check-prefixes=CHECK-MSG %s
 // CHECK-MSG-NOT: argument unused during compilation
diff --git a/test/Driver/nostdlibxx.cpp b/test/Driver/nostdlibxx.cpp
new file mode 100644
index 0000000..02bd62d
--- /dev/null
+++ b/test/Driver/nostdlibxx.cpp
@@ -0,0 +1,8 @@
+// RUN: %clangxx -target i686-pc-linux-gnu -### -nostdlib++ %s 2> %t
+// RUN: FileCheck < %t %s
+
+// We should still have -lm and the C standard libraries, but not -lstdc++.
+
+// CHECK-NOT: -lstdc++
+// CHECK-NOT: -lc++
+// CHECK: -lm
diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c
index efdd124..2de6957 100644
--- a/test/Driver/sanitizer-ld.c
+++ b/test/Driver/sanitizer-ld.c
@@ -234,6 +234,21 @@
 // CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan
 // CHECK-UBSAN-LINUX-CXX: "-lpthread"
 
+// RUN: %clang -fsanitize=undefined -fsanitize-minimal-runtime %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-MINIMAL-LINUX %s
+// CHECK-UBSAN-MINIMAL-LINUX: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-MINIMAL-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan_minimal-i386.a" "-no-whole-archive"
+// CHECK-UBSAN-MINIMAL-LINUX: "-lpthread"
+
+// RUN: %clang -fsanitize=undefined -fsanitize-minimal-runtime %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-apple-darwin -fuse-ld=ld \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-MINIMAL-DARWIN %s
+// CHECK-UBSAN-MINIMAL-DARWIN: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-MINIMAL-DARWIN: "{{.*}}libclang_rt.ubsan_minimal_osx_dynamic.dylib"
+
 // RUN: %clang -fsanitize=address,undefined %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
diff --git a/test/Driver/stack-protector.c b/test/Driver/stack-protector.c
index 6769b65..a3e40b5 100644
--- a/test/Driver/stack-protector.c
+++ b/test/Driver/stack-protector.c
@@ -36,27 +36,20 @@
 // Test default stack protector values for Darwin platforms
 
 // RUN: %clang -target armv7k-apple-watchos2.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_WATCHOS
+// RUN: %clang -ffreestanding -target armv7k-apple-watchos2.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_WATCHOS
 // SSP_WATCHOS: "-stack-protector" "1"
 // RUN: %clang -target arm64-apple-ios8.0.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_IOS
+// RUN: %clang -ffreestanding -target arm64-apple-ios8.0.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_IOS
 // SSP_IOS: "-stack-protector" "1"
 // RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX
+// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX
 // SSP_MACOSX: "-stack-protector" "1"
 // RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.5 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_10_5
+// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.5 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_10_5
 // SSP_MACOSX_10_5: "-stack-protector" "1"
 // RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.5 -mkernel -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_KERNEL
 // SSP_MACOSX_KERNEL-NOT: "-stack-protector"
 // RUN: %clang -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_10_6_KERNEL
+// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_MACOSX_10_6_KERNEL
 // SSP_MACOSX_10_6_KERNEL: "-stack-protector" "1"
 
-// Test default stack protector values for Darwin platforms with -ffreestanding
-
-// RUN: %clang -ffreestanding -target armv7k-apple-watchos2.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_WATCHOS
-// SSP_FREE_WATCHOS-NOT: "-stack-protector"
-// RUN: %clang -ffreestanding -target arm64-apple-ios8.0.0 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_IOS
-// SSP_FREE_IOS-NOT: "-stack-protector"
-// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_MACOSX
-// SSP_FREE_MACOSX-NOT: "-stack-protector"
-// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.5 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_MACOSX_10_5
-// SSP_FREE_MACOSX_10_5-NOT: "-stack-protector"
-// RUN: %clang -ffreestanding -target x86_64-apple-darwin10 -mmacosx-version-min=10.6 -### %s 2>&1 | FileCheck %s -check-prefix=SSP_FREE_MACOSX_10_6_KERNEL
-// SSP_FREE_MACOSX_10_6_KERNEL-NOT: "-stack-protector"
diff --git a/test/FixIt/fixit-availability.c b/test/FixIt/fixit-availability.c
index 038dee0..4b3c8a4 100644
--- a/test/FixIt/fixit-availability.c
+++ b/test/FixIt/fixit-availability.c
@@ -8,3 +8,11 @@
 // 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  }"
 }
+
+__attribute__((availability(macos, introduced=10.12)))
+struct New { };
+
+struct NoFixit {
+  struct New field;
+};
+// CHECK-NOT: API_AVAILABLE
diff --git a/test/FixIt/fixit-availability.mm b/test/FixIt/fixit-availability.mm
index d044a73..a566082 100644
--- a/test/FixIt/fixit-availability.mm
+++ b/test/FixIt/fixit-availability.mm
@@ -108,4 +108,43 @@
 // CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:24-[[@LINE-2]]:24}:"\n    } else {\n        // Fallback on earlier versions\n    }"
   anotherFunction(y);
   anotherFunction(x);
+
+  if (@available(macOS 10.1, *)) {
+    int z = function();
+    (void)z;
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:5-[[@LINE-2]]:5}:"if (@available(macOS 10.12, *)) {\n        "
+// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:13-[[@LINE-2]]:13}:"\n    } else {\n        // Fallback on earlier versions\n    }"
+    anotherFunction(x);
+  }
 }
+
+#define API_AVAILABLE(X) __attribute__((availability(macos, introduced=10.12))) // dummy macro
+
+API_AVAILABLE(macos(10.12))
+@interface NewClass
+@end
+
+@interface OldButOfferFixit
+@property(copy) NewClass *prop;
+// CHECK: fix-it:{{.*}}:{[[@LINE-2]]:1-[[@LINE-2]]:1}:"API_AVAILABLE(macos(10.12))\n"
+
+- (NewClass *)fixitMe;
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:22-[[@LINE-1]]:22}:" API_AVAILABLE(macos(10.12))"
+@end
+
+void oldButOfferFixitFn(NewClass *) {
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:1-[[@LINE-1]]:1}:"API_AVAILABLE(macos(10.12))\n"
+}
+
+template<typename T>
+struct OldButOfferFixitTag {
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:7-[[@LINE-1]]:7}:" API_AVAILABLE(macos(10.12))"
+  NewClass *x;
+};
+
+// Avoid a fixit for declarations that already have an attribute:
+__attribute__((availability(macos, introduced=10.11)))
+@interface WithoutFixit
+@property(copy) NewClass *prop;
+// CHECK-NOT: API_AVAILABLE
+@end
diff --git a/test/FixIt/fixit-fill-in-missing-switch-cases.cpp b/test/FixIt/fixit-fill-in-missing-switch-cases.cpp
new file mode 100644
index 0000000..20b948f
--- /dev/null
+++ b/test/FixIt/fixit-fill-in-missing-switch-cases.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fdiagnostics-parseable-fixits -std=c++11 %s 2>&1 | FileCheck %s
+
+enum Color {
+  Black,
+  Blue,
+  White,
+  Gold
+};
+
+void fillInCases(Color c) {
+  switch (c) {
+  case Black:
+    break;
+  }
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"case Blue:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n"
+  switch (c) {
+  }
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n"
+}
+
+enum class NoDenseMap: long long {
+  Baddie = 0x7fffffffffffffffLL,
+  BigBaddie = -0x7fffffffffffffffLL-1
+};
+
+void fillInAllCases(NoDenseMap v) {
+  switch (v) {
+  }
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"case NoDenseMap::Baddie:\n<#code#>\nbreak;\ncase NoDenseMap::BigBaddie:\n<#code#>\nbreak;\n"
+}
+
diff --git a/test/FixIt/fixit-fill-in-protocol-requirements.m b/test/FixIt/fixit-fill-in-protocol-requirements.m
new file mode 100644
index 0000000..642a70c
--- /dev/null
+++ b/test/FixIt/fixit-fill-in-protocol-requirements.m
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -triple=x86_64-apple-macos10.10 -verify -Wno-objc-root-class -serialize-diagnostic-file /dev/null %s
+// RUN: %clang_cc1 -triple=x86_64-apple-macos10.10 -fdiagnostics-parseable-fixits -serialize-diagnostic-file /dev/null %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple=x86_64-apple-macos10.12 -fdiagnostics-parseable-fixits -serialize-diagnostic-file /dev/null %s 2>&1 | FileCheck --check-prefix=AVAILABLE %s
+
+@protocol P1
+
+- (void)p2Method;
+
+@end
+
+@protocol P2 <P1>
+
+- (void)p1Method;
+
+@end
+
+@interface I <P2>
+
+@end
+
+@implementation I // expected-warning {{warning: class 'I' does not conform to protocols 'P2' and 'P1'}} expected-note {{add stubs for missing protocol requirements}}
+
+@end
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:1-[[@LINE-1]]:1}:"- (void)p2Method { \n  <#code#>\n}\n\n- (void)p1Method { \n  <#code#>\n}\n\n"
+
+@protocol P3
+
++ (void)p3ClassMethod;
+
+@end
+
+@interface I (Category) <P3> // expected-warning {{warning: category 'Category' does not conform to protocols 'P3'}} expected-note {{add stubs for missing protocol requirements}}
+
+@end
+
+@implementation I (Category)
+
+@end
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:1-[[@LINE-1]]:1}:"+ (void)p3ClassMethod { \n  <#code#>\n}\n\n"
+
+@protocol P4
+
+- (void)anotherMethod;
+
+@end
+
+@interface ThreeProtocols <P2, P1, P3> // expected-warning {{class 'ThreeProtocols' does not conform to protocols 'P2', 'P1' and 'P3'}} expected-note {{add stubs for missing protocol requirements}}
+@end
+@implementation ThreeProtocols
+@end
+
+@interface FourProtocols <P2, P3, P4> // expected-warning {{class 'ThreeProtocols' does not conform to protocols 'P2', 'P1', 'P3', ...}} expected-note {{add stubs for missing protocol requirements}}
+@end
+@implementation FourProtocols
+@end
+
+// Unavailable methods
+@protocol TakeAvailabilityIntoAccount
+
+- (void)unavailableMethod __attribute__((availability(macos,unavailable)));
++ (void)notYetAvailableMethod __attribute__((availability(macos,introduced=10.11)));
+- (void)availableMethod;
+- (void)deprecatedMethod __attribute__((availability(macos,introduced=10.0, deprecated=10.6)));
+
+@end
+
+@interface ImplementsAllAvailable <TakeAvailabilityIntoAccount>
+@end
+
+@implementation ImplementsAllAvailable // No warning!
+
+- (void)availableMethod { }
+- (void)deprecatedMethod { }
+
+@end
+
+@interface FixitJustAvailable <TakeAvailabilityIntoAccount>
+@end
+
+@implementation FixitJustAvailable // expected-warning {{class 'FixitJustAvailable' does not conform to protocol 'TakeAvailabilityIntoAccount'}} expected-note {{add stubs for missing protocol requirements}}
+
+@end
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:1-[[@LINE-1]]:1}:"- (void)availableMethod { \n  <#code#>\n}\n\n- (void)deprecatedMethod { \n  <#code#>\n}\n\n"
+// AVAILABLE: fix-it:{{.*}}:{[[@LINE-2]]:1-[[@LINE-2]]:1}:"- (void)availableMethod { \n  <#code#>\n}\n\n- (void)deprecatedMethod { \n  <#code#>\n}\n\n+ (void)notYetAvailableMethod { \n  <#code#>\n}\n\n"
diff --git a/test/FixIt/fixit-fill-in-switch-crash.cpp b/test/FixIt/fixit-fill-in-switch-crash.cpp
new file mode 100644
index 0000000..635fe81
--- /dev/null
+++ b/test/FixIt/fixit-fill-in-switch-crash.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify -std=c++11 %s
+// RUN: not %clang_cc1 -fdiagnostics-parseable-fixits -std=c++11 %s 2>&1 | FileCheck %s
+
+enum Color {
+  Black, Red
+};
+
+void dontCrashOnEmptySubStmt(Color c) { // expected-note {{to match this '{'}}
+  switch (c) { // expected-note {{to match this '{'}} \
+               // expected-warning {{enumeration value 'Red' not handled in switch}} \
+               // expected-note {{add missing switch cases}}
+  case Black: // CHECK: fix-it:{{.*}}:{[[@LINE+3]]:10-[[@LINE+3]]:10}:"case Red:\n<#code#>\nbreak;\n"
+  // expected-error@+2 {{expected expression}}
+  // expected-error@+1 2 {{expected '}'}}
+  case //
diff --git a/test/Frontend/clang-abi-compat.cpp b/test/Frontend/clang-abi-compat.cpp
deleted file mode 100644
index 7ee9464..0000000
--- a/test/Frontend/clang-abi-compat.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-// RUN: not %clang_cc1 -fclang-abi-compat=banana %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
-// RUN: not %clang_cc1 -fclang-abi-compat=2.9 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
-// RUN: not %clang_cc1 -fclang-abi-compat=8 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
-// RUN: not %clang_cc1 -fclang-abi-compat=3.10 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
-// RUN: not %clang_cc1 -fclang-abi-compat=4.1 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
-// RUN: not %clang_cc1 -fclang-abi-compat=04 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
-// RUN: not %clang_cc1 -fclang-abi-compat=4. %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
-// RUN: not %clang_cc1 -fclang-abi-compat=4.00 %s -fsyntax-only 2>&1 | FileCheck --check-prefix=INVALID %s
-// INVALID: error: invalid value '{{.*}}' in '-fclang-abi-compat={{.*}}'
-//
-// RUN: %clang_cc1 -fclang-abi-compat=3.0 %s -fsyntax-only
-// RUN: %clang_cc1 -fclang-abi-compat=3.9 %s -fsyntax-only
-// RUN: %clang_cc1 -fclang-abi-compat=4 %s -fsyntax-only
-// RUN: %clang_cc1 -fclang-abi-compat=4.0 %s -fsyntax-only
-// RUN: %clang_cc1 -fclang-abi-compat=latest %s -fsyntax-only
diff --git a/test/Index/Core/index-dependent-source.cpp b/test/Index/Core/index-dependent-source.cpp
index 59c6286..2e11133 100644
--- a/test/Index/Core/index-dependent-source.cpp
+++ b/test/Index/Core/index-dependent-source.cpp
@@ -158,3 +158,69 @@
 // Shouldn't crash!
   t.lookup;
 }
+
+template <typename T>
+struct UsingA {
+// CHECK: [[@LINE+1]]:15 | type-alias/C | Type | c:index-dependent-source.cpp@ST>1#T@UsingA@T@Type | <no-cgname> | Def,RelChild | rel: 1
+  typedef int Type;
+// CHECK: [[@LINE+1]]:15 | static-method/C++ | func | c:@ST>1#T@UsingA@F@func#S | <no-cgname> | Decl,RelChild | rel: 1
+  static void func();
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator() | c:@ST>1#T@UsingA@F@operator()#I# | <no-cgname> | Decl,RelChild | rel: 1
+  void operator()(int);
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | operator+ | c:@ST>1#T@UsingA@F@operator+#&1>@ST>1#T@UsingA1t0.0# | <no-cgname> | Decl,RelChild | rel: 1
+  void operator+(const UsingA &);
+};
+
+template <typename T>
+struct OtherUsing {};
+
+template <typename T>
+struct UsingB : public UsingA<T> {
+// CHECK: [[@LINE+2]]:40 | type-alias/C | TypeB | c:index-dependent-source.cpp@ST>1#T@UsingB@T@TypeB | <no-cgname> | Def,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:20 | struct(Gen)/C++ | OtherUsing | c:@ST>1#T@OtherUsing | <no-cgname> | Ref,RelCont | rel: 1
+  typedef typename OtherUsing<T>::Type TypeB;
+// CHECK: [[@LINE+2]]:29 | using/using-typename(Gen)/C++ | Type | c:index-dependent-source.cpp@ST>1#T@UsingB@UUT@UsingA<T>::Type | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:18 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
+  using typename UsingA<T>::Type;
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | func | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::func | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingA<T>::func;
+
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | operator() | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::operator() | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingA<T>::operator();
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | operator+ | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::operator+ | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingA | c:@ST>1#T@UsingA | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingA<T>::operator+;
+};
+
+template <typename T>
+struct UsingC : public UsingB<T> {
+  static void test() {
+// CHECK: [[@LINE+2]]:25 | type-alias/C | TypeB | c:index-dependent-source.cpp@ST>1#T@UsingB@T@TypeB | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1
+    typename UsingB<T>::TypeB value1;
+// CHECK: [[@LINE+2]]:25 | using/using-typename(Gen)/C++ | Type | c:index-dependent-source.cpp@ST>1#T@UsingB@UUT@UsingA<T>::Type | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:14 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1
+    typename UsingB<T>::Type value2;
+// CHECK: [[@LINE+2]]:16 | using/using-value(Gen)/C++ | func | c:index-dependent-source.cpp@ST>1#T@UsingB@UUV@UsingA<T>::func | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+// CHECK: [[@LINE+1]]:5 | struct(Gen)/C++ | UsingB | c:@ST>1#T@UsingB | <no-cgname> | Ref,RelCont | rel: 1
+    UsingB<T>::func();
+  }
+};
+
+template <typename T>
+struct UsingD {
+// CHECK: [[@LINE+1]]:8 | instance-method/C++ | foo | c:@ST>1#T@UsingD@F@foo#t0.0# | <no-cgname> | Decl,RelChild | rel: 1
+  void foo(T);
+};
+
+template <typename T, typename U>
+struct UsingE : public UsingD<T>, public UsingD<U> {
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | foo | c:index-dependent-source.cpp@ST>2#T#T@UsingE@UUV@UsingD<T>::foo | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingD<T>::foo;
+// CHECK: [[@LINE+2]]:20 | using/using-value(Gen)/C++ | foo | c:index-dependent-source.cpp@ST>2#T#T@UsingE@UUV@UsingD<U>::foo | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE+1]]:9 | struct(Gen)/C++ | UsingD | c:@ST>1#T@UsingD | <no-cgname> | Ref,RelCont | rel: 1
+  using UsingD<U>::foo;
+};
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index 4864d6c..f9c88d5 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -497,6 +497,19 @@
 
 }
 
+template<typename T>
+struct Guided { T t; };
+// CHECK: [[@LINE-1]]:8 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Def | rel: 0
+// CHECK-NEXT: [[@LINE-2]]:19 | field/C++ | t | c:@ST>1#T@Guided@FI@t | <no-cgname> | Def,RelChild | rel: 1
+// CHECK-NEXT: RelChild | Guided | c:@ST>1#T@Guided
+Guided(double) -> Guided<float>;
+// CHECK: [[@LINE-1]]:19 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Ref | rel: 0
+// CHECK-NEXT: [[@LINE-2]]:1 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Ref | rel: 0
+auto guided = Guided{1.0};
+// CHECK: [[@LINE-1]]:6 | variable/C | guided | c:@guided | _guided | Def | rel: 0
+// CHECK-NEXT: [[@LINE-2]]:15 | struct(Gen)/C++ | Guided | c:@ST>1#T@Guided | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | guided | c:@guided
+
 namespace rd33122110 {
 
 struct Outer {
diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m
index 1333caf..2931e66 100644
--- a/test/Index/Core/index-source.m
+++ b/test/Index/Core/index-source.m
@@ -389,6 +389,15 @@
 @interface ClassReceivers
 
 @property(class) int p1;
+// CHECK: [[@LINE-1]]:22 | class-method/acc-get/ObjC | p1 | c:objc(cs)ClassReceivers(cm)p1 | +[ClassReceivers p1] | Decl,Dyn,Impl,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | ClassReceivers | c:objc(cs)ClassReceivers
+// CHECK-NEXT: RelAcc | p1 | c:objc(cs)ClassReceivers(cpy)p1
+// CHECK: [[@LINE-4]]:22 | class-method/acc-set/ObjC | setP1: | c:objc(cs)ClassReceivers(cm)setP1: | +[ClassReceivers setP1:] | Decl,Dyn,Impl,RelChild,RelAcc | rel: 2
+// CHECK-NEXT: RelChild | ClassReceivers | c:objc(cs)ClassReceivers
+// CHECK-NEXT: RelAcc | p1 | c:objc(cs)ClassReceivers(cpy)p1
+// CHECK: [[@LINE-7]]:22 | instance-property/ObjC | p1 | c:objc(cs)ClassReceivers(cpy)p1 | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK-NEXT: RelChild | ClassReceivers | c:objc(cs)ClassReceivers
+
 + (int)implicit;
 + (void)setImplicit:(int)x;
 
@@ -399,13 +408,13 @@
 // 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: [[@LINE-4]]:18 | class-method/acc-set/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: [[@LINE-4]]:24 | class-method/acc-get/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;
diff --git a/test/Index/Store/Inputs/head.h b/test/Index/Store/Inputs/head.h
new file mode 100644
index 0000000..6ac174d
--- /dev/null
+++ b/test/Index/Store/Inputs/head.h
@@ -0,0 +1,3 @@
+
+extern void test1_func(void);
+extern void test2_func(void);
diff --git a/test/Index/Store/Inputs/json.c.json b/test/Index/Store/Inputs/json.c.json
new file mode 100644
index 0000000..498022d
--- /dev/null
+++ b/test/Index/Store/Inputs/json.c.json
@@ -0,0 +1,151 @@
+{
+  "files": [
+    "/test1.o",
+    "/Inputs/test1.c",
+    "/Inputs/head.h",
+    "/test2.o",
+    "/Inputs/test2.c",
+    "/test3.o",
+    "/Inputs/test3.cpp"
+  ],
+  "symbols": [
+    {
+      "kind": "function",
+      "lang": "C",
+      "usr": "c:@F@test1_func",
+      "name": "test1_func",
+      "codegen": "_test1_func",
+      "roles": "Decl,Def"
+    },
+    {
+      "kind": "function",
+      "lang": "C",
+      "usr": "c:@F@test2_func",
+      "name": "test2_func",
+      "codegen": "_test2_func",
+      "roles": "Decl,Def"
+    },
+    {
+      "kind": "class",
+      "lang": "C++",
+      "usr": "c:@S@Base",
+      "name": "Base",
+      "roles": "Def,Ref,RelBase,RelCont"
+    },
+    {
+      "kind": "class",
+      "lang": "C++",
+      "usr": "c:@S@Sub",
+      "name": "Sub",
+      "roles": "Def",
+      "rel-roles": "RelBase,RelCont"
+    }
+  ],
+  "records": [
+    {
+      "occurrences": [
+        {
+          "symbol": 0,
+          "line": 3,
+          "col": 6,
+          "roles": "Def"
+        }
+      ]
+    },
+    {
+      "occurrences": [
+        {
+          "symbol": 0,
+          "line": 2,
+          "col": 13,
+          "roles": "Decl"
+        },
+        {
+          "symbol": 1,
+          "line": 3,
+          "col": 13,
+          "roles": "Decl"
+        }
+      ]
+    },
+    {
+      "occurrences": [
+        {
+          "symbol": 1,
+          "line": 3,
+          "col": 6,
+          "roles": "Def"
+        }
+      ]
+    },
+    {
+      "occurrences": [
+        {
+          "symbol": 2,
+          "line": 1,
+          "col": 7,
+          "roles": "Def"
+        },
+        {
+          "symbol": 3,
+          "line": 2,
+          "col": 7,
+          "roles": "Def"
+        },
+        {
+          "symbol": 2,
+          "line": 2,
+          "col": 20,
+          "roles": "Ref,RelBase,RelCont",
+          "relations": [
+            {
+              "symbol": 3,
+              "rel-roles": "RelBase,RelCont"
+            }
+          ]
+
+        }
+      ]
+    }
+  ],
+  "units": [
+    {
+      "triple": "x86_64-apple-macosx10.7.0",
+      "out-file": 0,
+      "sources": [
+        {
+          "file": 1,
+          "records": [0]
+        },
+        {
+          "file": 2,
+          "records": [1]
+        }
+      ]
+    },
+    {
+      "triple": "x86_64-apple-macosx10.7.0",
+      "out-file": 3,
+      "sources": [
+        {
+          "file": 4,
+          "records": [2]
+        },
+        {
+          "file": 2,
+          "records": [1]
+        }
+      ]
+    },
+    {
+      "triple": "x86_64-apple-macosx10.7.0",
+      "out-file": 5,
+      "sources": [
+        {
+          "file": 6,
+          "records": [3]
+        }
+      ]
+    }
+  ]
+}
diff --git a/test/Index/Store/Inputs/module/ModDep.h b/test/Index/Store/Inputs/module/ModDep.h
new file mode 100644
index 0000000..e96ef54
--- /dev/null
+++ b/test/Index/Store/Inputs/module/ModDep.h
@@ -0,0 +1,3 @@
+#include "ModTop.h"
+
+void ModDep_func(ModTopStruct s);
diff --git a/test/Index/Store/Inputs/module/ModSystem.h b/test/Index/Store/Inputs/module/ModSystem.h
new file mode 100644
index 0000000..0419f97
--- /dev/null
+++ b/test/Index/Store/Inputs/module/ModSystem.h
@@ -0,0 +1,4 @@
+
+typedef struct {} ModSystemStruct;
+
+void ModSystem_func(void);
diff --git a/test/Index/Store/Inputs/module/ModTop.h b/test/Index/Store/Inputs/module/ModTop.h
new file mode 100644
index 0000000..60c5686
--- /dev/null
+++ b/test/Index/Store/Inputs/module/ModTop.h
@@ -0,0 +1,4 @@
+
+typedef struct {} ModTopStruct;
+
+void ModTop_func(void);
diff --git a/test/Index/Store/Inputs/module/ModTopSub1.h b/test/Index/Store/Inputs/module/ModTopSub1.h
new file mode 100644
index 0000000..e1e3cf3
--- /dev/null
+++ b/test/Index/Store/Inputs/module/ModTopSub1.h
@@ -0,0 +1 @@
+void ModTopSub1_func(void);
diff --git a/test/Index/Store/Inputs/module/ModTopSub2.h b/test/Index/Store/Inputs/module/ModTopSub2.h
new file mode 100644
index 0000000..39d37f1
--- /dev/null
+++ b/test/Index/Store/Inputs/module/ModTopSub2.h
@@ -0,0 +1 @@
+// This header has no symbols, intended to show up as file dependency.
diff --git a/test/Index/Store/Inputs/module/module.modulemap b/test/Index/Store/Inputs/module/module.modulemap
new file mode 100644
index 0000000..ada2f38
--- /dev/null
+++ b/test/Index/Store/Inputs/module/module.modulemap
@@ -0,0 +1,12 @@
+module ModTop {
+  header "ModTop.h"
+  export *
+  module Sub1 {
+    header "ModTopSub1.h"
+  }
+  module Sub2 {
+    header "ModTopSub2.h"
+  }
+}
+module ModDep { header "ModDep.h" export * }
+module ModSystem [system] { header "ModSystem.h" export * }
diff --git a/test/Index/Store/Inputs/overlay.yaml b/test/Index/Store/Inputs/overlay.yaml
new file mode 100644
index 0000000..7b55b30
--- /dev/null
+++ b/test/Index/Store/Inputs/overlay.yaml
@@ -0,0 +1,6 @@
+{
+  'version': 0,
+  'roots': [{ 'type': 'file', 'name': 'OUT_DIR/using-overlay.h',
+             'external-contents': 'INPUT_DIR/using-overlay.h'
+           }]
+}
diff --git a/test/Index/Store/Inputs/print-unit.h b/test/Index/Store/Inputs/print-unit.h
new file mode 100644
index 0000000..62039c4
--- /dev/null
+++ b/test/Index/Store/Inputs/print-unit.h
@@ -0,0 +1,2 @@
+#include "head.h"
+#include "using-overlay.h"
diff --git a/test/Index/Store/Inputs/sys/another.h b/test/Index/Store/Inputs/sys/another.h
new file mode 100644
index 0000000..555b99b
--- /dev/null
+++ b/test/Index/Store/Inputs/sys/another.h
@@ -0,0 +1,2 @@
+
+extern void sys_another_func(void);
diff --git a/test/Index/Store/Inputs/sys/syshead.h b/test/Index/Store/Inputs/sys/syshead.h
new file mode 100644
index 0000000..8941fd6
--- /dev/null
+++ b/test/Index/Store/Inputs/sys/syshead.h
@@ -0,0 +1,4 @@
+
+#include "another.h"
+
+extern void sys_test1_func(void);
diff --git a/test/Index/Store/Inputs/test1.c b/test/Index/Store/Inputs/test1.c
new file mode 100644
index 0000000..505711d
--- /dev/null
+++ b/test/Index/Store/Inputs/test1.c
@@ -0,0 +1,3 @@
+#include "head.h"
+
+void test1_func(void) {}
diff --git a/test/Index/Store/Inputs/test2.c b/test/Index/Store/Inputs/test2.c
new file mode 100644
index 0000000..333b8ae
--- /dev/null
+++ b/test/Index/Store/Inputs/test2.c
@@ -0,0 +1,3 @@
+#include "head.h"
+
+void test2_func(void) {}
diff --git a/test/Index/Store/Inputs/test3.cpp b/test/Index/Store/Inputs/test3.cpp
new file mode 100644
index 0000000..06334a1
--- /dev/null
+++ b/test/Index/Store/Inputs/test3.cpp
@@ -0,0 +1,2 @@
+class Base {};
+class Sub : public Base {};
diff --git a/test/Index/Store/Inputs/using-overlay.h b/test/Index/Store/Inputs/using-overlay.h
new file mode 100644
index 0000000..bb361c3
--- /dev/null
+++ b/test/Index/Store/Inputs/using-overlay.h
@@ -0,0 +1 @@
+void using_overlay(void);
diff --git a/test/Index/Store/assembly-invocation.c b/test/Index/Store/assembly-invocation.c
new file mode 100644
index 0000000..ab9c197
--- /dev/null
+++ b/test/Index/Store/assembly-invocation.c
@@ -0,0 +1,3 @@
+// Make sure it doesn't crash.
+// RUN: %clang -target x86_64-apple-macosx10.7 -S %s -o %t.s
+// RUN: env CLANG_PROJECT_INDEX_PATH=%t.idx %clang -target x86_64-apple-macosx10.7 -c %t.s -o %t.o
diff --git a/test/Index/Store/external-source-symbol-hash.m b/test/Index/Store/external-source-symbol-hash.m
new file mode 100644
index 0000000..243616d
--- /dev/null
+++ b/test/Index/Store/external-source-symbol-hash.m
@@ -0,0 +1,47 @@
+// RUN: rm -rf %t.idx
+// RUN: %clang_cc1 %s -index-store-path %t.idx -D USE_EXTERNAL
+// RUN: c-index-test core -print-record %t.idx | FileCheck %s
+// RUN: %clang_cc1 %s -index-store-path %t.idx
+// RUN: find %t.idx/*/records -name "external-source-symbol-hash*" | count 2
+
+#ifdef USE_EXTERNAL
+#  define EXT_DECL(mod_name) __attribute__((external_source_symbol(language="Swift", defined_in=mod_name)))
+#else
+#  define EXT_DECL(mod_name)
+#endif
+
+#define NS_ENUM(_name, _type) enum _name:_type _name; enum _name : _type
+
+// Forward declarations should pick up the attribute from later decls
+@protocol P1;
+// CHECK: [[@LINE-1]]:11 | protocol/Swift | c:@M@some_module@objc(pl)P1 | Ref | rel: 0
+@class I2;
+// CHECK: [[@LINE-1]]:8 | class/Swift | c:@M@other_module@objc(cs)I2 | Ref | rel: 0
+enum E3: int;
+// CHECK: [[@LINE-1]]:6 | enum/Swift | c:@M@third_module@E@E3 | Ref | rel: 0
+
+void test(id<P1> first, I2 *second, enum E3 third) {}
+// CHECK: [[@LINE-1]]:14 | protocol/Swift | c:@M@some_module@objc(pl)P1 | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:25 | class/Swift | c:@M@other_module@objc(cs)I2 | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:42 | enum/Swift | c:@M@third_module@E@E3 | Ref,RelCont | rel: 1
+
+EXT_DECL("some_module")
+@protocol P1
+// CHECK: [[@LINE-1]]:11 | protocol/Swift | c:@M@some_module@objc(pl)P1 | Decl | rel: 0
+-(void)method;
+// CHECK: [[@LINE-1]]:8 | instance-method/Swift | c:@M@some_module@objc(pl)P1(im)method | Decl,Dyn,RelChild | rel: 1
+@end
+
+EXT_DECL("other_module")
+@interface I2
+// CHECK: [[@LINE-1]]:12 | class/Swift | c:@M@other_module@objc(cs)I2 | Decl | rel: 0
+-(void)method;
+// CHECK: [[@LINE-1]]:8 | instance-method/Swift | c:@M@other_module@objc(cs)I2(im)method | Decl,Dyn,RelChild | rel: 1
+@end
+
+
+typedef NS_ENUM(E3, int) {
+// CHECK: [[@LINE-1]]:17 | enum/Swift | c:@M@third_module@E@E3 | Def | rel: 0
+  firstCase = 1,
+  // CHECK: [[@LINE-1]]:3 | enumerator/Swift | c:@M@third_module@E@E3@firstCase | Def,RelChild | rel: 1
+} EXT_DECL("third_module");
diff --git a/test/Index/Store/handle-prebuilt-module.m b/test/Index/Store/handle-prebuilt-module.m
new file mode 100644
index 0000000..f6a0c42
--- /dev/null
+++ b/test/Index/Store/handle-prebuilt-module.m
@@ -0,0 +1,25 @@
+// XFAIL: linux
+
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.7 -fsyntax-only %s -o %t.o -index-store-path %t/idx1 -fmodules -fmodules-cache-path=%t/mcp -I %S/Inputs/module -Rindex-store 2> %t.err1
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.7 -fsyntax-only %s -o %t.o -index-store-path %t/idx2 -fmodules -fmodules-cache-path=%t/mcp -I %S/Inputs/module -Rindex-store 2> %t.err2
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.7 -fsyntax-only %s -o %t.o -index-store-path %t/idx2 -fmodules -fmodules-cache-path=%t/mcp -I %S/Inputs/module -Rindex-store 2> %t.err3
+// RUN: FileCheck -input-file=%t.err1 -check-prefix=CREATING_MODULES %s -allow-empty
+// RUN: FileCheck -input-file=%t.err2 -check-prefix=CREATING_INDEX_DATA_FROM_MODULE_FILES %s
+// RUN: FileCheck -input-file=%t.err3 -check-prefix=EXISTING_INDEX_DATA_FROM_MODULE_FILES %s -allow-empty
+// RUN: c-index-test core -print-unit %t/idx1 > %t/all-units1.txt
+// RUN: c-index-test core -print-unit %t/idx2 > %t/all-units2.txt
+// RUN: c-index-test core -print-record %t/idx1 > %t/all-records1.txt
+// RUN: c-index-test core -print-record %t/idx2 > %t/all-records2.txt
+// RUN: diff -u %t/all-units1.txt %t/all-units2.txt
+// RUN: diff -u %t/all-records1.txt %t/all-records2.txt
+
+@import ModDep;
+
+// CREATING_MODULES-NOT: remark:
+
+// CREATING_INDEX_DATA_FROM_MODULE_FILES: remark: producing index data for module file {{.*}}ModDep{{.*}}.pcm
+// CREATING_INDEX_DATA_FROM_MODULE_FILES: remark: producing index data for module file {{.*}}ModTop{{.*}}.pcm
+
+// EXISTING_INDEX_DATA_FROM_MODULE_FILES-NOT: remark:
diff --git a/test/Index/Store/json-with-module.m b/test/Index/Store/json-with-module.m
new file mode 100644
index 0000000..1ef6969
--- /dev/null
+++ b/test/Index/Store/json-with-module.m
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t.idx %t.mcp
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.7 -c %s -o %t.o -index-store-path %t.idx -fmodules -fmodules-cache-path=%t.mcp -Xclang -fdisable-module-hash -I %S/Inputs/module
+// RUN: c-index-test core -aggregate-json %t.idx -o %t.json
+// RUN: sed -e "s:%S::g" -e "s:%T::g" %t.json > %t.final.json
+// RUN: diff -u %s.json %t.final.json
+
+// XFAIL: linux
+
+@import ModDep;
diff --git a/test/Index/Store/json-with-module.m.json b/test/Index/Store/json-with-module.m.json
new file mode 100644
index 0000000..5c9bf3a
--- /dev/null
+++ b/test/Index/Store/json-with-module.m.json
@@ -0,0 +1,151 @@
+{
+  "files": [
+    "/json-with-module.m.tmp.mcp/ModDep.pcm",
+    "/json-with-module.m.tmp.mcp/ModTop.pcm",
+    "/Inputs/module/ModDep.h",
+    "/Inputs/module/ModTop.h",
+    "/Inputs/module/ModTopSub1.h",
+    "/Inputs/module/ModTopSub2.h",
+    "/json-with-module.m.tmp.o",
+    "/json-with-module.m",
+    "/Inputs/module/module.modulemap"
+  ],
+  "symbols": [
+    {
+      "kind": "function",
+      "lang": "C",
+      "usr": "c:@F@ModDep_func",
+      "name": "ModDep_func",
+      "roles": "Decl",
+      "rel-roles": "RelCont"
+    },
+    {
+      "kind": "type-alias",
+      "lang": "C",
+      "usr": "c:@T@ModTopStruct",
+      "name": "ModTopStruct",
+      "roles": "Def,Ref,RelCont"
+    },
+    {
+      "kind": "struct",
+      "lang": "C",
+      "usr": "c:@SA@ModTopStruct",
+      "name": "",
+      "roles": "Def"
+    },
+    {
+      "kind": "function",
+      "lang": "C",
+      "usr": "c:@F@ModTop_func",
+      "name": "ModTop_func",
+      "roles": "Decl"
+    },
+    {
+      "kind": "function",
+      "lang": "C",
+      "usr": "c:@F@ModTopSub1_func",
+      "name": "ModTopSub1_func",
+      "roles": "Decl"
+    }
+  ],
+  "records": [
+    {
+      "occurrences": [
+        {
+          "symbol": 0,
+          "line": 3,
+          "col": 6,
+          "roles": "Decl"
+        },
+        {
+          "symbol": 1,
+          "line": 3,
+          "col": 18,
+          "roles": "Ref,RelCont",
+          "relations": [
+            {
+              "symbol": 0,
+              "rel-roles": "RelCont"
+            }
+          ]
+
+        }
+      ]
+    },
+    {
+      "occurrences": [
+        {
+          "symbol": 2,
+          "line": 2,
+          "col": 9,
+          "roles": "Def"
+        },
+        {
+          "symbol": 1,
+          "line": 2,
+          "col": 19,
+          "roles": "Def"
+        },
+        {
+          "symbol": 3,
+          "line": 4,
+          "col": 6,
+          "roles": "Decl"
+        }
+      ]
+    },
+    {
+      "occurrences": [
+        {
+          "symbol": 4,
+          "line": 1,
+          "col": 6,
+          "roles": "Decl"
+        }
+      ]
+    }
+  ],
+  "units": [
+    {
+      "triple": "x86_64-apple-macosx10.7.0",
+      "out-file": 0,
+      "unit-dependencies": [1],
+      "sources": [
+        {
+          "file": 2,
+          "records": [0]
+        }
+      ]
+    },
+    {
+      "triple": "x86_64-apple-macosx10.7.0",
+      "out-file": 1,
+      "sources": [
+        {
+          "file": 3,
+          "records": [1]
+        },
+        {
+          "file": 4,
+          "records": [2]
+        },
+        {
+          "file": 5
+        }
+      ]
+    },
+    {
+      "triple": "x86_64-apple-macosx10.7.0",
+      "out-file": 6,
+      "unit-dependencies": [0],
+      "sources": [
+        {
+          "file": 7
+        },
+        {
+          "file": 8
+        }
+      ]
+    }
+  ]
+}
diff --git a/test/Index/Store/json-with-pch.c b/test/Index/Store/json-with-pch.c
new file mode 100644
index 0000000..9ffe80f
--- /dev/null
+++ b/test/Index/Store/json-with-pch.c
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t.idx
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.7 -x c-header %S/Inputs/head.h -o %t.h.pch -index-store-path %t.idx
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.7 -c %s -o %t.o -index-store-path %t.idx -include %t.h -Werror
+// RUN: c-index-test core -aggregate-json %t.idx -o %t.json
+// RUN: sed -e "s:%S::g" -e "s:%T::g" %t.json > %t.final.json
+// RUN: diff -u %s.json %t.final.json
+// XFAIL: linux
+int main() {
+  test1_func();
+}
diff --git a/test/Index/Store/json-with-pch.c.json b/test/Index/Store/json-with-pch.c.json
new file mode 100644
index 0000000..605f33e
--- /dev/null
+++ b/test/Index/Store/json-with-pch.c.json
@@ -0,0 +1,96 @@
+{
+  "files": [
+    "/json-with-pch.c.tmp.h.pch",
+    "/Inputs/head.h",
+    "/json-with-pch.c.tmp.o",
+    "/json-with-pch.c"
+  ],
+  "symbols": [
+    {
+      "kind": "function",
+      "lang": "C",
+      "usr": "c:@F@test1_func",
+      "name": "test1_func",
+      "roles": "Decl,Ref,Call,RelCall,RelCont"
+    },
+    {
+      "kind": "function",
+      "lang": "C",
+      "usr": "c:@F@test2_func",
+      "name": "test2_func",
+      "roles": "Decl"
+    },
+    {
+      "kind": "function",
+      "lang": "C",
+      "usr": "c:@F@main",
+      "name": "main",
+      "roles": "Def",
+      "rel-roles": "RelCall,RelCont"
+    }
+  ],
+  "records": [
+    {
+      "occurrences": [
+        {
+          "symbol": 0,
+          "line": 2,
+          "col": 13,
+          "roles": "Decl"
+        },
+        {
+          "symbol": 1,
+          "line": 3,
+          "col": 13,
+          "roles": "Decl"
+        }
+      ]
+    },
+    {
+      "occurrences": [
+        {
+          "symbol": 2,
+          "line": 8,
+          "col": 5,
+          "roles": "Def"
+        },
+        {
+          "symbol": 0,
+          "line": 9,
+          "col": 3,
+          "roles": "Ref,Call,RelCall,RelCont",
+          "relations": [
+            {
+              "symbol": 2,
+              "rel-roles": "RelCall,RelCont"
+            }
+          ]
+
+        }
+      ]
+    }
+  ],
+  "units": [
+    {
+      "triple": "x86_64-apple-macosx10.7.0",
+      "out-file": 0,
+      "sources": [
+        {
+          "file": 1,
+          "records": [0]
+        }
+      ]
+    },
+    {
+      "triple": "x86_64-apple-macosx10.7.0",
+      "out-file": 2,
+      "unit-dependencies": [0],
+      "sources": [
+        {
+          "file": 3,
+          "records": [1]
+        }
+      ]
+    }
+  ]
+}
diff --git a/test/Index/Store/json.c b/test/Index/Store/json.c
new file mode 100644
index 0000000..c4ea965
--- /dev/null
+++ b/test/Index/Store/json.c
@@ -0,0 +1,10 @@
+// RUN: rm -rf %t.idx
+// RUN: mkdir -p %t.o
+// RUN: env CLANG_PROJECT_INDEX_PATH=%t.idx %clang -target x86_64-apple-macosx10.7 -arch x86_64 -mmacosx-version-min=10.7 -c %S/Inputs/test1.c -o %t.o/test1.o
+// RUN: env CLANG_PROJECT_INDEX_PATH=%t.idx %clang -target x86_64-apple-macosx10.7 -arch x86_64 -mmacosx-version-min=10.7 -c %S/Inputs/test2.c -o %t.o/test2.o
+// RUN: env CLANG_PROJECT_INDEX_PATH=%t.idx %clang -target x86_64-apple-macosx10.7 -arch x86_64 -mmacosx-version-min=10.7 -c %S/Inputs/test3.cpp -o %t.o/test3.o
+// RUN: c-index-test core -aggregate-json %t.idx -o %t.json
+// RUN: sed -e "s:%S::g" -e "s:%t.o::g" %t.json > %t.final.json
+// RUN: diff -u %S/Inputs/json.c.json %t.final.json
+
+// XFAIL: linux
diff --git a/test/Index/Store/print-record.mm b/test/Index/Store/print-record.mm
new file mode 100644
index 0000000..ce24983
--- /dev/null
+++ b/test/Index/Store/print-record.mm
@@ -0,0 +1,28 @@
+// RUN: rm -rf %t.idx
+// RUN: %clang_cc1 %s -index-store-path %t.idx
+// RUN: c-index-test core -print-record %t.idx | FileCheck %s
+
+// XFAIL: linux
+
+@class MyCls;
+
+@interface MyCls
+@end
+
+// CHECK: [[@LINE+2]]:6 | function/C | c:@F@foo#*$objc(cs)MyCls# | Decl | rel: 0
+// CHECK: [[@LINE+1]]:10 | class/ObjC | c:objc(cs)MyCls | Ref,RelCont | rel: 1
+void foo(MyCls *p);
+
+
+// RANGE-NOT: before_range
+void before_range();
+
+// RANGE: [[@LINE+1]]:6 | function/C | c:@F@in_range1# | Decl
+void in_range1();
+// RANGE: [[@LINE+1]]:6 | function/C | c:@F@in_range2# | Decl
+void in_range2();
+
+// RANGE-NOT: after_range
+void after_range();
+
+// RUN: c-index-test core -print-record %t.idx -filepath %s:21:23 | FileCheck -check-prefix=RANGE %s
diff --git a/test/Index/Store/print-unit.c b/test/Index/Store/print-unit.c
new file mode 100644
index 0000000..19254a1
--- /dev/null
+++ b/test/Index/Store/print-unit.c
@@ -0,0 +1,39 @@
+// XFAIL: linux
+
+#include "print-unit.h"
+#include "syshead.h"
+
+void foo(int i);
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -I %S/Inputs -isystem %S/Inputs/sys -index-store-path %t/idx %s -triple x86_64-apple-macosx10.8
+// RUN: c-index-test core -print-unit %t/idx | FileCheck %s
+// RUN: %clang_cc1 -I %S/Inputs -isystem %S/Inputs/sys -index-store-path %t/idx_opt1 %s -triple x86_64-apple-macosx10.8 -O2
+// RUN: c-index-test core -print-unit %t/idx_opt1 | FileCheck %s -check-prefix=OPT
+// RUN: %clang_cc1 -I %S/Inputs -isystem %S/Inputs/sys -index-store-path %t/idx_opt2 %s -triple x86_64-apple-macosx10.8 -Os
+// RUN: c-index-test core -print-unit %t/idx_opt2 | FileCheck %s -check-prefix=OPT
+
+// CHECK: print-unit.c.o
+// CHECK: provider: clang-
+// CHECK: is-system: 0
+// CHECK: has-main: 1
+// CHECK: main-path: {{.*}}/print-unit.c
+// CHECK: out-file: {{.*}}/print-unit.c.o
+// CHECK: target: x86_64-apple-macosx10.8
+// CHECK: is-debug: 1
+// CHECK: DEPEND START
+// CHECK: Record | user | {{.*}}/print-unit.c | print-unit.c-
+// CHECK: Record | user | {{.*}}/Inputs/head.h | head.h-
+// CHECK: Record | user | {{.*}}/Inputs/using-overlay.h | using-overlay.h-
+// CHECK: Record | system | {{.*}}/Inputs/sys/syshead.h | syshead.h-
+// CHECK: Record | system | {{.*}}/Inputs/sys/another.h | another.h-
+// CHECK: File | user | {{.*}}/Inputs/print-unit.h | | {{[0-9]*$}}
+// CHECK: DEPEND END (6)
+// CHECK: INCLUDE START
+// CHECK: {{.*}}/print-unit.c:3 | {{.*}}/Inputs/print-unit.h
+// CHECK: {{.*}}/print-unit.c:4 | {{.*}}/Inputs/sys/syshead.h
+// CHECK: {{.*}}/Inputs/print-unit.h:1 | {{.*}}/Inputs/head.h
+// CHECK: {{.*}}/Inputs/print-unit.h:2 | {{.*}}/Inputs/using-overlay.h
+// CHECK: INCLUDE END (4)
+
+// OPT: is-debug: 0
diff --git a/test/Index/Store/print-units-with-modules.m b/test/Index/Store/print-units-with-modules.m
new file mode 100644
index 0000000..cedfe2c
--- /dev/null
+++ b/test/Index/Store/print-units-with-modules.m
@@ -0,0 +1,59 @@
+// RUN: rm -rf %t.idx %t.mcp
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.7 -c %s -o %t.o -index-store-path %t.idx -fmodules -fmodules-cache-path=%t.mcp -Xclang -fdisable-module-hash -I %S/Inputs/module
+// RUN: c-index-test core -print-unit %t.idx | FileCheck %s
+
+// XFAIL: linux
+
+@import ModDep;
+@import ModSystem;
+
+// CHECK: ModDep.pcm
+// CHECK: provider: clang-
+// CHECK: is-system: 0
+// CHECK: is-module: 1
+// CHECK: module-name: ModDep
+// CHECK: has-main: 0
+// CHECK: main-path: {{$}}
+// CHECK: out-file: {{.*}}/ModDep.pcm
+// CHECK: DEPEND START
+// CHECK: Unit | user | ModTop | {{.*}}/ModTop.pcm | ModTop.pcm
+// CHECK: Record | user | ModDep | {{.*}}/Inputs/module/ModDep.h | ModDep.h
+// CHECK: DEPEND END (2)
+
+// CHECK: ModSystem.pcm
+// CHECK: is-system: 1
+// CHECK: is-module: 1
+// CHECK: module-name: ModSystem
+// CHECK: has-main: 0
+// CHECK: main-path: {{$}}
+// CHECK: out-file: {{.*}}/ModSystem.pcm
+// CHECK: DEPEND START
+// CHECK: Record | system | ModSystem | {{.*}}/Inputs/module/ModSystem.h | ModSystem.h
+// CHECK: DEPEND END (1)
+
+// CHECK: ModTop.pcm
+// CHECK: is-system: 0
+// CHECK: is-module: 1
+// CHECK: module-name: ModTop
+// CHECK: has-main: 0
+// CHECK: main-path: {{$}}
+// CHECK: out-file: {{.*}}/ModTop.pcm
+// CHECK: DEPEND START
+// CHECK: Record | user | ModTop | {{.*}}/Inputs/module/ModTop.h | ModTop.h
+// CHECK: Record | user | ModTop.Sub1 | {{.*}}/Inputs/module/ModTopSub1.h | ModTopSub1.h
+// CHECK: File | user | ModTop.Sub2 | {{.*}}/Inputs/module/ModTopSub2.h | | {{[0-9]*$}}
+// CHECK: DEPEND END (3)
+
+// CHECK: print-units-with-modules.m.tmp.o
+// CHECK: is-system: 0
+// CHECK: is-module: 0
+// CHECK: module-name: <none>
+// CHECK: has-main: 1
+// CHECK: main-path: {{.*}}/print-units-with-modules.m
+// CHECK: out-file: {{.*}}/print-units-with-modules.m.tmp.o
+// CHECK: DEPEND START
+// CHECK: Unit | user | ModDep | {{.*}}/ModDep.pcm | ModDep.pcm
+// CHECK: Unit | system | ModSystem | {{.*}}/ModSystem.pcm | ModSystem.pcm
+// CHECK: File | user | {{.*}}/print-units-with-modules.m | | {{[0-9]*$}}
+// CHECK: File | user | {{.*}}/Inputs/module/module.modulemap | | {{[0-9]*$}}
+// CHECK: DEPEND END (4)
diff --git a/test/Index/Store/print-units-with-pch.c b/test/Index/Store/print-units-with-pch.c
new file mode 100644
index 0000000..1e533a2
--- /dev/null
+++ b/test/Index/Store/print-units-with-pch.c
@@ -0,0 +1,29 @@
+// RUN: rm -rf %t.idx
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.7 -x c-header %S/Inputs/head.h -o %t.h.pch -index-store-path %t.idx
+// RUN: %clang -arch x86_64 -mmacosx-version-min=10.7 -c %s -o %t.o -index-store-path %t.idx -include %t.h -Werror
+// RUN: c-index-test core -print-unit %t.idx | FileCheck %s
+
+// XFAIL: linux
+
+int main() {
+  test1_func();
+}
+
+// CHECK: print-units-with-pch.c.tmp.h.pch
+// CHECK: is-system: 0
+// CHECK: has-main: 0
+// CHECK: main-path: {{$}}
+// CHECK: out-file: {{.*}}/print-units-with-pch.c.tmp.h.pch
+// CHECK: DEPEND START
+// CHECK: Record | user | {{.*}}/Inputs/head.h | head.h
+// CHECK: DEPEND END (1)
+
+// CHECK: print-units-with-pch.c.tmp.o
+// CHECK: is-system: 0
+// CHECK: has-main: 1
+// CHECK: main-path: {{.*}}/print-units-with-pch.c
+// CHECK: out-file: {{.*}}/print-units-with-pch.c.tmp.o
+// CHECK: DEPEND START
+// CHECK: Unit | user | {{.*}}/print-units-with-pch.c.tmp.h.pch | print-units-with-pch.c.tmp.h.pch
+// CHECK: Record | user | {{.*}}/print-units-with-pch.c | print-units-with-pch.c
+// CHECK: DEPEND END (2)
diff --git a/test/Index/Store/record-hash-crash-invalid-name.cpp b/test/Index/Store/record-hash-crash-invalid-name.cpp
new file mode 100644
index 0000000..4479789
--- /dev/null
+++ b/test/Index/Store/record-hash-crash-invalid-name.cpp
@@ -0,0 +1,17 @@
+// Makes sure it doesn't crash.
+
+// XFAIL: linux
+
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 %s -index-store-path %t/idx -std=c++14
+// RUN: c-index-test core -print-record %t/idx | FileCheck %s
+
+namespace rdar32474406 {
+void foo();
+typedef void (*Func_t)();
+// CHECK: [[@LINE+4]]:1 | type-alias/C | c:record-hash-crash-invalid-name.cpp@N@rdar32474406@T@Func_t | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | c:@N@rdar32474406
+// CHECK: [[@LINE+2]]:14 | function/C | c:@N@rdar32474406@F@foo# | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | c:@N@rdar32474406
+Func_t[] = { foo }; // invalid decomposition
+}
diff --git a/test/Index/Store/record-hash-crash.cpp b/test/Index/Store/record-hash-crash.cpp
new file mode 100644
index 0000000..3d71ac9
--- /dev/null
+++ b/test/Index/Store/record-hash-crash.cpp
@@ -0,0 +1,31 @@
+// Makes sure it doesn't crash.
+
+// XFAIL: linux
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 %s -index-store-path %t/idx -std=c++14
+// RUN: c-index-test core -print-record %t/idx | FileCheck %s
+
+namespace crash1 {
+// CHECK: [[@LINE+1]]:6 | function/C
+auto getit() { return []() {}; }
+}
+
+namespace crash2 {
+// CHECK: [[@LINE+2]]:7 | class(Gen)/C++ | c:@N@crash2@ST>1#T@Foo | Ref,RelCont | rel: 1
+template <typename T>
+class Foo; // canonical decl
+
+// CHECK: [[@LINE+2]]:7 | class(Gen)/C++ | c:@N@crash2@ST>1#T@Foo | Def,RelChild | rel: 1
+template <typename T>
+class Foo {};
+
+// CHECK: [[@LINE+2]]:8 | struct(Gen)/C++ | c:@N@crash2@ST>1#t>1#pT@Wrapper | Def,RelChild | rel: 1
+template <template <typename... ARGS> class TYPE>
+struct Wrapper {};
+
+// CHECK: [[@LINE+3]]:8 | struct(Gen,TS)/C++ | c:@N@crash2@S@Wrapper>#@N@crash2@ST>1#T@Foo | Def,RelChild,RelSpecialization | rel: 2
+// CHECK:	RelSpecialization | c:@N@crash2@ST>1#t>1#pT@Wrapper
+template <>
+struct Wrapper<Foo> {};
+}
diff --git a/test/Index/Store/record-hash-using.cpp b/test/Index/Store/record-hash-using.cpp
new file mode 100644
index 0000000..c8285d5e
--- /dev/null
+++ b/test/Index/Store/record-hash-using.cpp
@@ -0,0 +1,46 @@
+// XFAIL: linux
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 %s -std=c++11 -index-store-path %t/idx -DTYPE1=A -DTYPE2=A -DTYPE3=T -DTYPE4=T
+// RUN: %clang_cc1 %s -std=c++11 -index-store-path %t/idx -DTYPE1=B -DTYPE2=A -DTYPE3=T -DTYPE4=T
+// RUN: %clang_cc1 %s -std=c++11 -index-store-path %t/idx -DTYPE1=A -DTYPE2=B -DTYPE3=T -DTYPE4=T
+// RUN: %clang_cc1 %s -std=c++11 -index-store-path %t/idx -DTYPE1=B -DTYPE2=B -DTYPE3=T -DTYPE4=T
+// RUN: find %t/idx/*/records -name "record-hash*" | count 4
+//
+// RUN: rm -rf %t
+// RUN: %clang_cc1 %s -std=c++11 -index-store-path %t/idx -DTYPE1=A -DTYPE2=A -DTYPE3=T -DTYPE4=T
+// RUN: %clang_cc1 %s -std=c++11 -index-store-path %t/idx -DTYPE1=A -DTYPE2=A -DTYPE3=U -DTYPE4=T
+// RUN: %clang_cc1 %s -std=c++11 -index-store-path %t/idx -DTYPE1=A -DTYPE2=A -DTYPE3=T -DTYPE4=U
+// RUN: %clang_cc1 %s -std=c++11 -index-store-path %t/idx -DTYPE1=A -DTYPE2=A -DTYPE3=U -DTYPE4=U
+// RUN: find %t/idx/*/records -name "record-hash*" | count 4
+
+template<typename T>
+struct A {
+  typedef int X;
+  void foo();
+};
+
+template<typename T>
+struct B : public A<T> {
+  typedef float X;
+  void foo(int);
+};
+
+template<typename T>
+struct C : public B<T> {
+// This should result in different records, due to the different types.
+  using TYPE1<T>::X;
+  using TYPE2<T>::foo;
+};
+
+template <typename T>
+struct D {
+  typedef T X;
+  void foo(T);
+};
+template <typename T, typename U>
+struct E : public D<T>, public D<U> {
+// This should result in different records, due to the different template parameter.
+  using D<TYPE3>::X;
+  using D<TYPE4>::foo;
+};
diff --git a/test/Index/Store/record-hash.cpp b/test/Index/Store/record-hash.cpp
new file mode 100644
index 0000000..21a4dc4
--- /dev/null
+++ b/test/Index/Store/record-hash.cpp
@@ -0,0 +1,12 @@
+// XFAIL: linux
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 %s -index-store-path %t/idx -D THE_TYPE=long
+// RUN: %clang_cc1 %s -index-store-path %t/idx -D THE_TYPE=char
+// RUN: find %t/idx/*/records -name "record-hash*" | count 2
+
+template<typename T>
+class TC {};
+
+// This should result in different records, due to the different template parameter type.
+void some_func(TC<THE_TYPE>);
diff --git a/test/Index/Store/relative-out-path.c b/test/Index/Store/relative-out-path.c
new file mode 100644
index 0000000..1d47ea0
--- /dev/null
+++ b/test/Index/Store/relative-out-path.c
@@ -0,0 +1,19 @@
+// Needs 'find'.
+// REQUIRES: shell
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: %clang %s -index-store-path %t/idx1 -c -o %t/outfile.o
+// RUN: cd %t
+// RUN: %clang %s -index-store-path %t/idx2 -c -o outfile.o
+// RUN: cd ..
+// RUN: %clang %s -index-store-path %t/idx3 -fsyntax-only -o outfile.o -working-directory=%t
+// RUN: diff -r -u %t/idx2 %t/idx3
+
+// RUN: find %t/idx1 -name '*outfile.o*' > %t/hashes.txt
+// RUN: find %t/idx3 -name '*outfile.o*' >> %t/hashes.txt
+// RUN: FileCheck %s --input-file=%t/hashes.txt
+// CHECK:      outfile.o[[OUT_HASH:.*$]]
+// CHECK-NEXT: outfile.o[[OUT_HASH]]
+
+void foo();
diff --git a/test/Index/Store/syntax-only.c b/test/Index/Store/syntax-only.c
new file mode 100644
index 0000000..53d22bc
--- /dev/null
+++ b/test/Index/Store/syntax-only.c
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t.idx
+// RUN: %clang -fsyntax-only %s -index-store-path %t.idx -o %T/syntax-only.c.myoutfile
+// RUN: c-index-test core -print-unit %t.idx | FileCheck %s -check-prefix=CHECK-UNIT
+// RUN: c-index-test core -print-record %t.idx | FileCheck %s -check-prefix=CHECK-RECORD
+
+// XFAIL: linux
+
+// CHECK-UNIT: out-file: {{.*}}/syntax-only.c.myoutfile
+// CHECK-RECORD: function/C | foo | c:@F@foo
+
+void foo();
diff --git a/test/Index/Store/unit-with-vfs.c b/test/Index/Store/unit-with-vfs.c
new file mode 100644
index 0000000..cbed626
--- /dev/null
+++ b/test/Index/Store/unit-with-vfs.c
@@ -0,0 +1,12 @@
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/overlay.yaml > %t.yaml
+// REQUIRES: shell
+
+#include "using-overlay.h"
+
+// RUN: rm -rf %t.idx
+// RUN: %clang_cc1 %s -index-store-path %t.idx -I %t -ivfsoverlay %t.yaml
+// RUN: c-index-test core -print-unit %t.idx | FileCheck %s
+
+// XFAIL: linux
+
+// CHECK: Record | user | {{.*}}test/Index/Store/Inputs/using-overlay.h
diff --git a/test/Index/Store/unit-workdir-prefix.c b/test/Index/Store/unit-workdir-prefix.c
new file mode 100644
index 0000000..e7a3a71
--- /dev/null
+++ b/test/Index/Store/unit-workdir-prefix.c
@@ -0,0 +1,30 @@
+// XFAIL: linux
+
+#include "header.h"
+
+void foo(void) {
+  bar();
+}
+
+// RUN: rm -rf %t
+// RUN: mkdir -p %t/Directory
+// RUN: mkdir -p %t/Directory.surprise
+// RUN: mkdir -p %t/sdk
+// RUN: mkdir -p %t/sdk_other
+// RUN: echo "void bar(void);" > %t/sdk_other/header.h
+// RUN: cp %s %t/Directory.surprise/main.c
+//
+// RUN: %clang_cc1 -isystem %t/sdk_other -isysroot %t/sdk -index-store-path %t/idx %t/Directory.surprise/main.c -triple x86_64-apple-macosx10.8 -working-directory %t/Directory
+// RUN: c-index-test core -print-unit %t/idx | FileCheck %s
+
+// CHECK: main.c.o
+// CHECK: provider: clang-
+// CHECK: is-system: 0
+// CHECK: has-main: 1
+// CHECK: main-path: {{.*}}Directory.surprise{{/|\\}}main.c
+// CHECK: out-file: {{.*}}Directory.surprise{{/|\\}}main.c.o
+// CHECK: target: x86_64-apple-macosx10.8
+// CHECK: is-debug: 1
+// CHECK: DEPEND START
+// CHECK: Record | user | {{.*}}Directory.surprise{{/|\\}}main.c | main.c-
+// CHECK: Record | system | {{.*}}sdk_other{{/|\\}}header.h | header.h-
diff --git a/test/Index/Store/using-libstdcpp-arc.mm b/test/Index/Store/using-libstdcpp-arc.mm
new file mode 100644
index 0000000..9738c86
--- /dev/null
+++ b/test/Index/Store/using-libstdcpp-arc.mm
@@ -0,0 +1,10 @@
+// Test to make sure we don't crash, rdar://30816887.
+
+// RUN: rm -rf %t.idx
+// RUN: %clang_cc1 %s -index-store-path %t.idx -fobjc-arc -fobjc-arc-cxxlib=libstdc++
+// RUN: c-index-test core -print-record %t.idx | FileCheck %s
+
+// XFAIL: linux
+
+// CHECK: [[@LINE+1]]:6 | function/C
+void test1(void);
diff --git a/test/Index/comment-to-html-xml-conversion-with-original-literals.cpp b/test/Index/comment-to-html-xml-conversion-with-original-literals.cpp
new file mode 100644
index 0000000..26ca223
--- /dev/null
+++ b/test/Index/comment-to-html-xml-conversion-with-original-literals.cpp
@@ -0,0 +1,26 @@
+// RUN: c-index-test -test-load-source all -comments-xml-schema=%S/../../bindings/xml/comment-xml-schema.rng %s -std=c++11 | FileCheck %s
+
+constexpr int value(float f) { return int(f); }
+
+enum MyEnum {
+hexadecimal = 0x10 //!< a
+// CHECK: <Declaration>hexadecimal = 0x10</Declaration>
+
+, withSuffix = 1u + 010 //!< b
+// CHECK: <Declaration>withSuffix = 1u + 010</Declaration>
+
+#define ARG(x) x
+, macroArg = ARG(0x1) //!< c
+// CHECK: <Declaration>macroArg = ARG(0x1)</Declaration>
+
+#define MACROCONCAT(x, y) 22##x##y
+, macroConcat = MACROCONCAT(3, 2) //!< d
+// CHECK: <Declaration>macroConcat = MACROCONCAT(3, 2)</Declaration>
+
+#define MACRO(a,n) = 0x##a##n
+, weirdMacros MACRO(2,1) //!< e
+// CHECK: <Declaration>weirdMacros = 33</Declaration>
+
+, floatLiteral = value(0.25e3) //!< f
+// CHECK: <Declaration>floatLiteral = value(0.25e3)</Declaration>
+};
diff --git a/test/Index/index-templates.cpp b/test/Index/index-templates.cpp
index 966cc4f..424a638 100644
--- a/test/Index/index-templates.cpp
+++ b/test/Index/index-templates.cpp
@@ -219,6 +219,6 @@
 // CHECK-USRS: index-templates.cpp c:@ST>2#T#T@Y Extent=[27:1 - 31:2]
 // CHECK-USRS: index-templates.cpp c:index-templates.cpp@443 Extent=[27:10 - 27:20]
 // CHECK-USRS: index-templates.cpp c:index-templates.cpp@455 Extent=[27:22 - 27:32]
-// CHECK-USRS-NOT: type
+// CHECK-USRS: index-templates.cpp c:index-templates.cpp@ST>2#T#T@Y@UUT@T::type Extent=[29:3 - 29:25]
 // CHECK-USRS: index-templates.cpp c:@S@Z3 Extent=[33:1 - 33:14]
 // CHECK-USRS: index-templates.cpp c:@F@f#$@S@map>#$@S@Z4#$@S@Pair>#I#S1_#$@S@compare>#$@S@Pair>#S1_#S2_#$@S@allocator>#S4_#
diff --git a/test/Index/skipped-ranges.c b/test/Index/skipped-ranges.c
index bd16fb3..f6c6c7f 100644
--- a/test/Index/skipped-ranges.c
+++ b/test/Index/skipped-ranges.c
@@ -20,6 +20,6 @@
 #endif // cool
 
 // RUN: env CINDEXTEST_SHOW_SKIPPED_RANGES=1 c-index-test -test-annotate-tokens=%s:1:1:16:1 %s | FileCheck %s
-// CHECK: Skipping: [5:2 - 6:7]
-// CHECK: Skipping: [8:2 - 12:7]
-// CHECK: Skipping: [14:2 - 20:7]
+// CHECK: Skipping: [5:1 - 6:7]
+// CHECK: Skipping: [8:1 - 12:7]
+// CHECK: Skipping: [14:1 - 20:7]
diff --git a/test/Misc/ast-dump-decl.m b/test/Misc/ast-dump-decl.m
index 4cfb8aa..bc5a058 100644
--- a/test/Misc/ast-dump-decl.m
+++ b/test/Misc/ast-dump-decl.m
@@ -143,3 +143,6 @@
   __typeof__(B.foo) Test;
 }
 // CHECK: VarDecl{{.*}}Test 'typeof (B.foo)':'int'
+
+@compatibility_alias TestCompatibilityAlias A;
+// CHECK: ObjCCompatibleAliasDecl{{.*}}col:22 TestCompatibilityAlias col:45
diff --git a/test/Misc/pragma-attribute-supported-attributes-list.test b/test/Misc/pragma-attribute-supported-attributes-list.test
index d698276..834dd4c 100644
--- a/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -2,7 +2,7 @@
 
 // The number of supported attributes should never go down!
 
-// CHECK: #pragma clang attribute supports 62 attributes:
+// CHECK: #pragma clang attribute supports 65 attributes:
 // CHECK-NEXT: AMDGPUFlatWorkGroupSize (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumSGPR (SubjectMatchRule_function)
 // CHECK-NEXT: AMDGPUNumVGPR (SubjectMatchRule_function)
@@ -57,8 +57,11 @@
 // 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)
diff --git a/test/Misc/warning-flags-tree.c b/test/Misc/warning-flags-tree.c
index d71c9f6..01ba497 100644
--- a/test/Misc/warning-flags-tree.c
+++ b/test/Misc/warning-flags-tree.c
@@ -1,6 +1,6 @@
-// RUN: diagtool tree | FileCheck -strict-whitespace %s
-// RUN: diagtool tree -Weverything | FileCheck -strict-whitespace %s
-// RUN: diagtool tree everything | FileCheck -strict-whitespace %s
+// RUN: diagtool tree --internal | FileCheck -strict-whitespace %s
+// RUN: diagtool tree --internal -Weverything | FileCheck -strict-whitespace %s
+// RUN: diagtool tree --internal everything | FileCheck -strict-whitespace %s
 //
 // These three ways of running diagtool tree are the same:
 // they produce a tree for every top-level diagnostic flag.
@@ -29,8 +29,7 @@
 
 // RUN: not diagtool tree -Wthis-is-not-a-valid-flag
 
-
-// RUN: diagtool tree -Wgnu | FileCheck -strict-whitespace -check-prefix CHECK-GNU %s
+// RUN: diagtool tree --internal -Wgnu | FileCheck -strict-whitespace -check-prefix CHECK-GNU %s
 // CHECK-GNU: -Wgnu
 // CHECK-GNU:   -Wgnu-designator
 // CHECK-GNU:     ext_gnu_array_range
@@ -40,7 +39,7 @@
 // CHECK-GNU:     ext_vla
 // There are more GNU extensions but we don't need to check them all.
 
-// RUN: diagtool tree --flags-only -Wgnu | FileCheck -check-prefix CHECK-FLAGS-ONLY %s
+// RUN: diagtool tree -Wgnu | FileCheck -check-prefix CHECK-FLAGS-ONLY %s
 // CHECK-FLAGS-ONLY: -Wgnu
 // CHECK-FLAGS-ONLY:   -Wgnu-designator
 // CHECK-FLAGS-ONLY-NOT:     ext_gnu_array_range
diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp
index ed9d1e8..97386bc 100644
--- a/test/Modules/ExtDebugInfo.cpp
+++ b/test/Modules/ExtDebugInfo.cpp
@@ -69,6 +69,8 @@
 
 void foo() {
   anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum;
+  A a;
+  Virtual virt;
 }
 
 // CHECK: ![[CPP:.*]] = !DIFile(filename: {{.*}}ExtDebugInfo.cpp"
@@ -210,3 +212,10 @@
 // CHECK-SAME:           dwoId:
 // CHECK-PCH: !DICompileUnit({{.*}}splitDebugFilename:
 // CHECK-PCH:                dwoId: 18446744073709551614
+
+// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A",
+// CHECK-SAME:             DIFlagFwdDecl, identifier: "_ZTS1A")
+
+// There is a full definition of the type available in the module.
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual",
+// CHECK-SAME:             DIFlagFwdDecl, identifier: "_ZTS7Virtual")
diff --git a/test/Modules/Inputs/DebugCXX.h b/test/Modules/Inputs/DebugCXX.h
index c9cd68f..1ccf8d3 100644
--- a/test/Modules/Inputs/DebugCXX.h
+++ b/test/Modules/Inputs/DebugCXX.h
@@ -54,9 +54,9 @@
 }
 
 // Virtual class with a forward declaration.
-class FwdVirtual;
-class FwdVirtual {
-  virtual ~FwdVirtual() {}
+struct Virtual;
+struct Virtual {
+  virtual ~Virtual() {}
 };
 
 struct PureForwardDecl;
diff --git a/test/Modules/Inputs/export_as_test.modulemap b/test/Modules/Inputs/export_as_test.modulemap
new file mode 100644
index 0000000..4aaec41
--- /dev/null
+++ b/test/Modules/Inputs/export_as_test.modulemap
@@ -0,0 +1,9 @@
+module PrivateFoo {
+  export_as Foo
+  export_as Bar
+  export_as Bar
+
+  module Sub {
+    export_as Wibble
+  }
+}
diff --git a/test/Modules/Inputs/import-textual/x.h b/test/Modules/Inputs/import-textual/x.h
new file mode 100644
index 0000000..9b41ccd
--- /dev/null
+++ b/test/Modules/Inputs/import-textual/x.h
@@ -0,0 +1,6 @@
+#ifndef RANDOM_DEP
+
+@interface X
+@end
+
+#endif // RANDOM_DEP
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/ModuleDebugInfo.cpp b/test/Modules/ModuleDebugInfo.cpp
index 71b05e5..008b3e4 100644
--- a/test/Modules/ModuleDebugInfo.cpp
+++ b/test/Modules/ModuleDebugInfo.cpp
@@ -86,10 +86,10 @@
 // CHECK-SAME:             flags: DIFlagFwdDecl
 // CHECK-SAME:             identifier: "_ZTSN8DebugCXX8TemplateIfNS_6traitsIfEEEE")
 
-// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "FwdVirtual"
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Virtual"
 // CHECK-SAME:             elements:
-// CHECK-SAME:             identifier: "_ZTS10FwdVirtual")
-// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$FwdVirtual"
+// CHECK-SAME:             identifier: "_ZTS7Virtual")
+// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$Virtual"
 
 // CHECK: !DICompositeType(tag: DW_TAG_union_type,
 // CHECK-NOT:              name:
@@ -111,6 +111,11 @@
 // CHECK-SAME:             name: "InAnonymousNamespace",
 // CHECK-SAME:             elements: !{{[0-9]+}})
 
+// CHECK: ![[A:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "A",
+// CHECK-SAME:                               elements:
+// CHECK-SAME:                               vtableHolder: ![[A]],
+// CHECK-SAME:                               identifier: "_ZTS1A")
+
 // CHECK: ![[DERIVED:.*]] = {{.*}}!DICompositeType(tag: DW_TAG_class_type, name: "Derived",
 // CHECK-SAME:                                     identifier: "_ZTS7Derived")
 // CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B", scope: ![[DERIVED]],
diff --git a/test/Modules/export_as_test.c b/test/Modules/export_as_test.c
new file mode 100644
index 0000000..a73d6bf
--- /dev/null
+++ b/test/Modules/export_as_test.c
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/export_as_test.modulemap %s 2> %t.err
+// RUN: FileCheck %s < %t.err
+
+// CHECK: export_as_test.modulemap:3:13: error: conflicting re-export of module 'PrivateFoo' as 'Foo' or 'Bar'
+// CHECK: export_as_test.modulemap:4:13: warning: module 'PrivateFoo' already re-exported as 'Bar'
+// CHECK: export_as_test.modulemap:7:15: error: only top-level modules can be re-exported as public
+
+
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-nomodules.m b/test/Modules/import-textual-nomodules.m
new file mode 100644
index 0000000..7cf8c1e
--- /dev/null
+++ b/test/Modules/import-textual-nomodules.m
@@ -0,0 +1,8 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fsyntax-only -fmodules -fimplicit-module-maps -I%S/Inputs/import-textual -fmodules-cache-path=%t %s -verify
+
+// expected-no-diagnostics
+
+#import "x.h"
+#import "x.h"
+
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/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/OpenMP/atomic_capture_codegen.cpp b/test/OpenMP/atomic_capture_codegen.cpp
index 0a22e42..5140359 100644
--- a/test/OpenMP/atomic_capture_codegen.cpp
+++ b/test/OpenMP/atomic_capture_codegen.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
 // expected-no-diagnostics
 #ifndef HEADER
 #define HEADER
diff --git a/test/OpenMP/atomic_read_codegen.c b/test/OpenMP/atomic_read_codegen.c
index 0cd46e3..0cfb2d2 100644
--- a/test/OpenMP/atomic_read_codegen.c
+++ b/test/OpenMP/atomic_read_codegen.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
 // expected-no-diagnostics
 // REQUIRES: x86-registered-target
 #ifndef HEADER
diff --git a/test/OpenMP/atomic_update_codegen.cpp b/test/OpenMP/atomic_update_codegen.cpp
index 8c02a43..bb3b42e 100644
--- a/test/OpenMP/atomic_update_codegen.cpp
+++ b/test/OpenMP/atomic_update_codegen.cpp
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
 // expected-no-diagnostics
 #ifndef HEADER
 #define HEADER
diff --git a/test/OpenMP/atomic_write_codegen.c b/test/OpenMP/atomic_write_codegen.c
index 050d7a5..0c85b6e 100644
--- a/test/OpenMP/atomic_write_codegen.c
+++ b/test/OpenMP/atomic_write_codegen.c
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin10 -target-cpu core2 -fopenmp -x c -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -emit-pch -o %t %s
+// RUN: %clang_cc1 -fopenmp -x c -triple x86_64-apple-darwin10 -target-cpu core2 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
 // expected-no-diagnostics
 // REQUIRES: x86-registered-target
 #ifndef HEADER
diff --git a/test/OpenMP/distribute_codegen.cpp b/test/OpenMP/distribute_codegen.cpp
index 37f00f0..4646351 100644
--- a/test/OpenMP/distribute_codegen.cpp
+++ b/test/OpenMP/distribute_codegen.cpp
@@ -34,7 +34,7 @@
   }
 }
 
-// CHECK: define {{.*}}void @.omp_outlined.(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
+// CHECK: define {{.*}}void @{{.+}}(i32* noalias [[GBL_TIDP:%.+]], i32* noalias [[BND_TID:%.+]], float** dereferenceable({{[0-9]+}}) [[APTR:%.+]], float** dereferenceable({{[0-9]+}}) [[BPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[CPTR:%.+]], float** dereferenceable({{[0-9]+}}) [[DPTR:%.+]])
 // CHECK:  [[TID_ADDR:%.+]] = alloca i32*
 // CHECK:  [[IV:%.+iv]] = alloca i32
 // CHECK:  [[LB:%.+lb]] = alloca i32
diff --git a/test/OpenMP/nvptx_target_firstprivate_codegen.cpp b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
index 5dcff8e..f750be0 100644
--- a/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
+++ b/test/OpenMP/nvptx_target_firstprivate_codegen.cpp
@@ -1,15 +1,14 @@
-
 // Test target codegen - host bc file has to be created first.
 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
+// RUN: %clang_cc1 -debug-info-kind=limited -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-64
 // RUN: %clang_cc1 -verify -fopenmp -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
-// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
+// RUN: %clang_cc1 -debug-info-kind=limited -verify -fopenmp -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix TCHECK --check-prefix TCHECK-32
 // expected-no-diagnostics
 #ifndef HEADER
 #define HEADER
 
-template<typename tx, typename ty>
-struct TT{
+template <typename tx, typename ty>
+struct TT {
   tx X;
   ty Y;
 };
@@ -23,29 +22,32 @@
   float b[10];
   double c[5][10];
   TT<long long, char> d;
-  
-  #pragma omp target firstprivate(a)
+
+#pragma omp target firstprivate(a) map(tofrom \
+                                       : b)
   {
+    b[a] = a;
   }
-  
-  // TCHECK:  define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]])
+
+  // TCHECK:  define {{.*}}void @__omp_offloading_{{.+}}([10 x float] addrspace(1)* noalias [[B_IN:%.+]], i{{[0-9]+}} [[A_IN:%.+]])
   // TCHECK:  [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
   // TCHECK-NOT:  alloca i{{[0-9]+}},
+  // TCHECK-64:  call void @llvm.dbg.declare(metadata [10 x float] addrspace(1)** %{{.+}}, metadata !{{[0-9]+}}, metadata !DIExpression())
   // TCHECK:  store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
-  // TCHECK:  ret void  
+  // TCHECK:  ret void
 
-#pragma omp target firstprivate(aa,b,c,d)
+#pragma omp target firstprivate(aa, b, c, d)
   {
     aa += 1;
     b[2] = 1.0;
     c[1][2] = 1.0;
     d.X = 1;
-    d.Y = 1;    
+    d.Y = 1;
   }
-  
+
   // make sure that firstprivate variables are generated in all cases and that we use those instances for operations inside the
   // target region
-  // TCHECK:  define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A2_IN:%.+]], [10 x float]* {{.+}} [[B_IN:%.+]], [5 x [10 x double]]* {{.+}} [[C_IN:%.+]], [[TT]]* {{.+}} [[D_IN:%.+]])
+  // TCHECK:  define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}}{{.*}} [[A2_IN:%.+]], [10 x float]*{{.*}} [[B_IN:%.+]], [5 x [10 x double]]*{{.*}} [[C_IN:%.+]], [[TT]]*{{.*}} [[D_IN:%.+]])
   // TCHECK:  [[A2_ADDR:%.+]] = alloca i{{[0-9]+}},
   // TCHECK:  [[B_ADDR:%.+]] = alloca [10 x float]*,
   // TCHECK:  [[C_ADDR:%.+]] = alloca [5 x [10 x double]]*,
@@ -58,10 +60,12 @@
   // TCHECK:  store [10 x float]* [[B_IN]], [10 x float]** [[B_ADDR]],
   // TCHECK:  store [5 x [10 x double]]* [[C_IN]], [5 x [10 x double]]** [[C_ADDR]],
   // TCHECK:  store [[TT]]* [[D_IN]], [[TT]]** [[D_ADDR]],
-  // TCHECK:  [[CONV_A2ADDR:%.+]] = bitcast i{{[0-9]+}}* [[A2_ADDR]] to i{{[0-9]+}}*
   // TCHECK:  [[B_ADDR_REF:%.+]] = load [10 x float]*, [10 x float]** [[B_ADDR]],
+  // TCHECK:  [[B_ADDR_REF:%.+]] = load [10 x float]*, [10 x float]** %
   // TCHECK:  [[C_ADDR_REF:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** [[C_ADDR]],
+  // TCHECK:  [[C_ADDR_REF:%.+]] = load [5 x [10 x double]]*, [5 x [10 x double]]** %
   // TCHECK:  [[D_ADDR_REF:%.+]] = load [[TT]]*, [[TT]]** [[D_ADDR]],
+  // TCHECK:  [[D_ADDR_REF:%.+]] = load [[TT]]*, [[TT]]** %
 
   // firstprivate(aa): a_priv = a_in
 
@@ -74,16 +78,15 @@
   // TCHECK:  [[C_PRIV_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_PRIV]] to i8*
   // TCHECK:  [[C_IN_BCAST:%.+]] = bitcast [5 x [10 x double]]* [[C_ADDR_REF]] to i8*
   // TCHECK:  call void @llvm.memcpy.{{.+}}(i8* [[C_PRIV_BCAST]], i8* [[C_IN_BCAST]],{{.+}})
-  
+
   // firstprivate(d)
   // TCHECK:  [[D_PRIV_BCAST:%.+]] = bitcast [[TT]]* [[D_PRIV]] to i8*
   // TCHECK:  [[D_IN_BCAST:%.+]] = bitcast [[TT]]* [[D_ADDR_REF]] to i8*
   // TCHECK:  call void @llvm.memcpy.{{.+}}(i8* [[D_PRIV_BCAST]], i8* [[D_IN_BCAST]],{{.+}})
 
-  // TCHECK: load i16, i16* [[CONV_A2ADDR]],
+  // TCHECK: load i16, i16* [[A2_ADDR]],
 
-  
-  #pragma omp target firstprivate(ptr)
+#pragma omp target firstprivate(ptr)
   {
     ptr[0]++;
   }
@@ -98,13 +101,12 @@
   return a;
 }
 
-
-template<typename tx>
+template <typename tx>
 tx ftemplate(int n) {
   tx a = 0;
   tx b[10];
 
-#pragma omp target firstprivate(a,b)
+#pragma omp target firstprivate(a, b)
   {
     a += 1;
     b[2] += 1;
@@ -113,13 +115,12 @@
   return a;
 }
 
-static
-int fstatic(int n) {
+static int fstatic(int n) {
   int a = 0;
   char aaa = 0;
   int b[10];
 
-#pragma omp target firstprivate(a,aaa,b)
+#pragma omp target firstprivate(a, aaa, b)
   {
     a += 1;
     aaa += 1;
@@ -129,7 +130,7 @@
   return a;
 }
 
-// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], i{{[0-9]+}} [[A3_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
+// TCHECK: define {{.*}}void @__omp_offloading_{{.+}}(i{{[0-9]+}}{{.*}} [[A_IN:%.+]], i{{[0-9]+}}{{.*}} [[A3_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
 // TCHECK:  [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
 // TCHECK:  [[A3_ADDR:%.+]] = alloca i{{[0-9]+}},
 // TCHECK:  [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*,
@@ -138,9 +139,8 @@
 // TCHECK:  store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
 // TCHECK:  store i{{[0-9]+}} [[A3_IN]], i{{[0-9]+}}* [[A3_ADDR]],
 // TCHECK:  store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]],
-// TCHECK-64:  [[A_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}*
-// TCHECK:  [[A3_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A3_ADDR]] to i8*
 // TCHECK:  [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]],
+// TCHECK:  [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** %
 
 // firstprivate(a): a_priv = a_in
 
@@ -158,8 +158,8 @@
 struct S1 {
   double a;
 
-  int r1(int n){
-    int b = n+1;
+  int r1(int n) {
+    int b = n + 1;
 
 #pragma omp target firstprivate(b)
     {
@@ -169,7 +169,7 @@
     return (int)b;
   }
 
-  // TCHECK: define void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[B_IN:%.+]])
+  // TCHECK: define internal void @__omp_offloading_{{.+}}([[S1]]* [[TH:%.+]], i{{[0-9]+}} [[B_IN:%.+]])
   // TCHECK:  [[TH_ADDR:%.+]] = alloca [[S1]]*,
   // TCHECK:  [[B_ADDR:%.+]] = alloca i{{[0-9]+}},
   // TCHECK-NOT: alloca i{{[0-9]+}},
@@ -185,9 +185,7 @@
   // TCHECK: ret void
 };
 
-
-
-int bar(int n, double *ptr){
+int bar(int n, double *ptr) {
   int a = 0;
   a += foo(n, ptr);
   S1 S;
@@ -200,15 +198,15 @@
 
 // template
 
-// TCHECK: define void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
+// TCHECK: define internal void @__omp_offloading_{{.+}}(i{{[0-9]+}} [[A_IN:%.+]], [10 x i{{[0-9]+}}]*{{.+}} [[B_IN:%.+]])
 // TCHECK:  [[A_ADDR:%.+]] = alloca i{{[0-9]+}},
 // TCHECK:  [[B_ADDR:%.+]] = alloca [10 x i{{[0-9]+}}]*,
 // TCHECK-NOT: alloca i{{[0-9]+}},
 // TCHECK:  [[B_PRIV:%.+]] = alloca [10 x i{{[0-9]+}}],
 // TCHECK:  store i{{[0-9]+}} [[A_IN]], i{{[0-9]+}}* [[A_ADDR]],
 // TCHECK:  store [10 x i{{[0-9]+}}]* [[B_IN]], [10 x i{{[0-9]+}}]** [[B_ADDR]],
-// TCHECK-64:  [[A_ADDR_CONV:%.+]] = bitcast i{{[0-9]+}}* [[A_ADDR]] to i{{[0-9]+}}*
 // TCHECK:  [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** [[B_ADDR]],
+// TCHECK:  [[B_ADDR_REF:%.+]] = load [10 x i{{[0-9]+}}]*, [10 x i{{[0-9]+}}]** %
 
 // firstprivate(a)
 // TCHECK-NOT:  store i{{[0-9]+}} %{{.+}}, i{{[0-9]+}}*
diff --git a/test/OpenMP/ordered_codegen.cpp b/test/OpenMP/ordered_codegen.cpp
index bd7c070..af6a872 100644
--- a/test/OpenMP/ordered_codegen.cpp
+++ b/test/OpenMP/ordered_codegen.cpp
@@ -216,7 +216,7 @@
 // CHECK-LABEL: foo_simd
 void foo_simd(int low, int up) {
   // CHECK: store float 0.000000e+00, float* %{{.+}}, align {{[0-9]+}}, !llvm.mem.parallel_loop_access !
-  // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}) #{{[0-9]+}}, !llvm.mem.parallel_loop_access !
+  // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}), !llvm.mem.parallel_loop_access !
 #pragma omp simd
   for (int i = low; i < up; ++i) {
     f[i] = 0.0;
@@ -224,7 +224,7 @@
     f[i] = 1.0;
   }
   // CHECK: store float 0.000000e+00, float* %{{.+}}, align {{[0-9]+}}
-  // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}}) #{{[0-9]+}}
+  // CHECK-NEXT: call void [[CAP_FUNC:@.+]](i32* %{{.+}})
 #pragma omp for simd ordered
   for (int i = low; i < up; ++i) {
     f[i] = 0.0;
diff --git a/test/OpenMP/parallel_codegen.cpp b/test/OpenMP/parallel_codegen.cpp
index 23b3237..68a178e 100644
--- a/test/OpenMP/parallel_codegen.cpp
+++ b/test/OpenMP/parallel_codegen.cpp
@@ -109,7 +109,7 @@
 // CHECK:       call {{.*}}void @{{.+terminate.*|abort}}(
 // CHECK-NEXT:  unreachable
 // CHECK-NEXT:  }
-// CHECK-DEBUG:       define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i8*** dereferenceable({{4|8}}) %argc)
+// CHECK-DEBUG:       define internal void [[OMP_OUTLINED_DEBUG:@.+]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i8*** dereferenceable({{4|8}}) %argc)
 // CHECK-DEBUG:       store i8*** %argc, i8**** [[ARGC_PTR_ADDR:%.+]],
 // CHECK-DEBUG:       [[ARGC_REF:%.+]] = load i8***, i8**** [[ARGC_PTR_ADDR]]
 // CHECK-DEBUG-NEXT:  [[ARGC:%.+]] = load i8**, i8*** [[ARGC_REF]]
@@ -120,7 +120,9 @@
 // CHECK-DEBUG-NEXT:  }
 
 // CHECK: define linkonce_odr {{.*}}void [[FOO1]](i8** %argc)
-// CHECK-DEBUG: define linkonce_odr void [[FOO1]](i8** %argc)
+// CHECK-DEBUG-DAG: define linkonce_odr void [[FOO1]](i8** %argc)
+// CHECK-DEBUG-DAG: define internal void [[OMP_OUTLINED]](i32* noalias %.global_tid., i32* noalias %.bound_tid., i8*** dereferenceable({{4|8}}) %argc)
+// CHECK-DEBUG-DAG: call void [[OMP_OUTLINED_DEBUG]]({{[^)]+}}){{[^,]*}}, !dbg
 
 // CHECK: attributes #[[FN_ATTRS]] = {{.+}} nounwind
 // CHECK-DEBUG: attributes #[[FN_ATTRS]] = {{.+}} nounwind
diff --git a/test/OpenMP/parallel_for_simd_codegen.cpp b/test/OpenMP/parallel_for_simd_codegen.cpp
index 06d9635..369ea17 100644
--- a/test/OpenMP/parallel_for_simd_codegen.cpp
+++ b/test/OpenMP/parallel_for_simd_codegen.cpp
@@ -114,6 +114,7 @@
   int lin = 12;
   #pragma omp parallel for simd linear(lin : get_val()), linear(g_ptr)
 
+// CHECK: alloca i32,
 // Init linear private var.
 // CHECK: [[LIN_VAR:%.+]] = load i32*, i32** %
 // CHECK: [[LIN_LOAD:%.+]] = load i32, i32* [[LIN_VAR]]
diff --git a/test/OpenMP/target_parallel_debug_codegen.cpp b/test/OpenMP/target_parallel_debug_codegen.cpp
new file mode 100644
index 0000000..d7b6b89
--- /dev/null
+++ b/test/OpenMP/target_parallel_debug_codegen.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -debug-info-kind=limited | FileCheck %s
+// expected-no-diagnostics
+
+int main() {
+  /* int(*b)[a]; */
+  /* int *(**c)[a]; */
+  int a;
+  int b[10][10];
+  int c[10][10][10];
+#pragma omp target parallel firstprivate(a, b) map(tofrom \
+                                                   : c)
+  {
+    int &f = c[1][1][1];
+    int &g = a;
+    int &h = b[1][1];
+    int d = 15;
+    a = 5;
+    b[0][a] = 10;
+    c[0][0][a] = 11;
+    b[0][a] = c[0][0][a];
+  }
+#pragma omp target parallel firstprivate(a) map(tofrom \
+                                                : c, b)
+  {
+    int &f = c[1][1][1];
+    int &g = a;
+    int &h = b[1][1];
+    int d = 15;
+    a = 5;
+    b[0][a] = 10;
+    c[0][0][a] = 11;
+    b[0][a] = c[0][0][a];
+  }
+#pragma omp target parallel map(tofrom \
+                                : a, c, b)
+  {
+    int &f = c[1][1][1];
+    int &g = a;
+    int &h = b[1][1];
+    int d = 15;
+    a = 5;
+    b[0][a] = 10;
+    c[0][0][a] = 11;
+    b[0][a] = c[0][0][a];
+  }
+  return 0;
+}
+
+// CHECK: define internal void @__omp_offloading{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* {{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: call void [[NONDEBUG_WRAPPER:.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* {{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* {{[^)]+}})
+
+// CHECK: define internal void [[DEBUG_PARALLEL:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+
+// CHECK: define internal void [[NONDEBUG_WRAPPER]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: call void [[DEBUG_PARALLEL]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* {{[^)]+}})
+
+// CHECK: define void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: call void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]]* {{[^)]+}})
+
+// CHECK: define internal void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* noalias {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias {{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+// CHECK: call void [[NONDEBUG_WRAPPER:.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* {{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* {{[^)]+}})
+
+// CHECK: define internal void [[DEBUG_PARALLEL:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+
+// CHECK: define internal void [[NONDEBUG_WRAPPER]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void [[DEBUG_PARALLEL]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^)]+}})
+
+// CHECK: define void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i64 {{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^)]+}})
+
+// CHECK: define internal void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* noalias {{[^,]+}}, i32 addrspace(1)* noalias {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias {{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast i32 addrspace(1)* %{{.+}} to i32*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+// CHECK: call void [[NONDEBUG_WRAPPER:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x i32]]* {{[^)]+}})
+
+// CHECK: define internal void [[DEBUG_PARALLEL:@.+]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* noalias{{[^,]+}}, i32 addrspace(1)* noalias{{[^,]+}}, [10 x [10 x i32]] addrspace(1)* noalias{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]] addrspace(1)* %{{.+}} to [10 x [10 x [10 x i32]]]*
+// CHECK: addrspacecast i32 addrspace(1)* %{{.+}} to i32*
+// CHECK: addrspacecast [10 x [10 x i32]] addrspace(1)* %{{.+}} to [10 x [10 x i32]]*
+
+// CHECK: define internal void [[NONDEBUG_WRAPPER]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i32* dereferenceable{{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast i32* %{{.+}} to i32 addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void [[DEBUG_PARALLEL]](i32* {{[^,]+}}, i32* {{[^,]+}}, [10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 addrspace(1)* {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^)]+}})
+
+// CHECK: define void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]]* dereferenceable{{[^,]+}}, i32* dereferenceable{{[^,]+}}, [10 x [10 x i32]]* dereferenceable{{[^)]+}})
+// CHECK: addrspacecast [10 x [10 x [10 x i32]]]* %{{.+}} to [10 x [10 x [10 x i32]]] addrspace(1)*
+// CHECK: addrspacecast i32* %{{.+}} to i32 addrspace(1)*
+// CHECK: addrspacecast [10 x [10 x i32]]* %{{.+}} to [10 x [10 x i32]] addrspace(1)*
+// CHECK: call void @__omp_offloading_{{[^(]+}}([10 x [10 x [10 x i32]]] addrspace(1)* {{[^,]+}}, i32 addrspace(1)* {{[^,]+}}, [10 x [10 x i32]] addrspace(1)* {{[^)]+}})
+
diff --git a/test/Parser/switch-recovery.cpp b/test/Parser/switch-recovery.cpp
index 4b06d55..019682f 100644
--- a/test/Parser/switch-recovery.cpp
+++ b/test/Parser/switch-recovery.cpp
@@ -21,7 +21,7 @@
   void test2() {
     enum X { Xa, Xb } x;
 
-    switch (x) { // expected-warning {{enumeration value 'Xb' not handled in switch}}
+    switch (x) { // expected-warning {{enumeration value 'Xb' not handled in switch}} expected-note {{add missing switch cases}}
     case Xa; // expected-error {{expected ':' after 'case'}}
       break;
     }
diff --git a/test/Refactor/Extract/captured-variable-block-types.m b/test/Refactor/Extract/captured-variable-block-types.m
new file mode 100644
index 0000000..ef20181
--- /dev/null
+++ b/test/Refactor/Extract/captured-variable-block-types.m
@@ -0,0 +1,30 @@
+
+int capturedBlock(void (^block)(int x, int (^)())) {
+  return capturedBlock(block);
+}
+
+// CHECK1: extracted(void (^block)(int, int (^)()))
+
+typedef void (^BlockTypedef)();
+
+int capturedBlockTypedef(BlockTypedef fp) {
+  return capturedBlockTypedef(fp);
+}
+// CHECK1: extracted(BlockTypedef fp)
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:3:10-3:29 -selected=%s:11:10-11:34 %s -fblocks | FileCheck --check-prefix=CHECK1 %s
+
+@interface I
+@end
+
+@implementation I
+
+- (void)method {
+  void (^block)(int x, int (^)());
+  block(2, ^ (void) { return 0; });
+}
+// CHECK2: - (void)extracted:(void (^)(int, int (^)()))block {
+
+@end
+
+// RUN: clang-refactor-test perform -action extract-method -selected=%s:24:3-24:35 %s -fblocks | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Extract/captured-variable-function-types.cpp b/test/Refactor/Extract/captured-variable-function-types.cpp
new file mode 100644
index 0000000..cf6ccee
--- /dev/null
+++ b/test/Refactor/Extract/captured-variable-function-types.cpp
@@ -0,0 +1,17 @@
+
+int capturedFunc(void (*fp)(int x)) {
+  auto fp2 = fp;
+  capturedFunc(fp);
+  return capturedFunc(fp2);
+}
+
+// CHECK1: extracted(void (*fp)(int))
+
+typedef void (*FuncTypedef)();
+
+int capturedFuncTypedef(FuncTypedef fp) {
+  return capturedFuncTypedef(fp);
+}
+// CHECK1: extracted(FuncTypedef fp)
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:4:3-4:19 -selected=%s:13:10-13:33 %s | FileCheck --check-prefix=CHECK1 %s
diff --git a/test/Refactor/Extract/captured-variable-lambda-type.cpp b/test/Refactor/Extract/captured-variable-lambda-type.cpp
new file mode 100644
index 0000000..6042830
--- /dev/null
+++ b/test/Refactor/Extract/captured-variable-lambda-type.cpp
@@ -0,0 +1,18 @@
+
+int capturedLambda(int x) {
+  auto Lambda = [] () { };
+  Lambda();
+  auto Lambda2 = [] (int x, int y) -> int { return x + y * 2; };
+  int y = Lambda2(x, 1);
+  auto Lambda3 = [&] (int y) {
+    x = y + 2;
+  };
+  Lambda3(3);
+  return Lambda2(x, 1);
+}
+
+// CHECK1: extracted(const std::function<void ()> &Lambda)
+// CHECK1: extracted(const std::function<auto (int, int) -> int> &Lambda2, int x)
+// CHECK1: extracted(const std::function<auto (int, int) -> int> &Lambda2, const std::function<void (int)> &Lambda3, int x)
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:4:3-4:11 -selected=%s:6:3-6:24 -selected=%s:10:3-11:23 %s -std=c++11 | FileCheck --check-prefix=CHECK1 %s
diff --git a/test/Refactor/Extract/captured-variable-typedef.cpp b/test/Refactor/Extract/captured-variable-typedef.cpp
new file mode 100644
index 0000000..f6991ea
--- /dev/null
+++ b/test/Refactor/Extract/captured-variable-typedef.cpp
@@ -0,0 +1,15 @@
+typedef signed int NSInteger;
+
+int capturedTypedef(NSInteger x) {
+  return capturedTypedef(x);
+}
+// CHECK1: "static int extracted(NSInteger x) {\nreturn capturedTypedef(x);\n}\n\n" [[@LINE-3]]
+// RUN: clang-refactor-test perform -action extract -selected=%s:4:10-4:28 %s -std=c++14 | FileCheck --check-prefix=CHECK1 %s
+
+using NSUInteger = unsigned int;
+
+int capturedUsing(NSUInteger x) {
+  return capturedUsing(x);
+}
+// CHECK2: "static int extracted(NSUInteger x) {\nreturn capturedUsing(x);\n}\n\n" [[@LINE-3]]
+// RUN: clang-refactor-test perform -action extract -selected=%s:12:10-12:26 %s -std=c++14 | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Extract/captured-variable-types.cpp b/test/Refactor/Extract/captured-variable-types.cpp
new file mode 100644
index 0000000..1a83884
--- /dev/null
+++ b/test/Refactor/Extract/captured-variable-types.cpp
@@ -0,0 +1,223 @@
+
+typedef struct {
+  int width, height;
+} Rectangle;
+
+int basicTypes(int i, float f, char c, const int *ip, float *fp,
+               const Rectangle *structPointer) {
+  return basicTypes(i, f, c, ip, fp, structPointer);
+}
+// CHECK1: "static int extracted(char c, float f, float *fp, int i, const int *ip, const Rectangle *structPointer) {\nreturn basicTypes(i, f, c, ip, fp, structPointer);\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK1-NEXT: "extracted(c, f, fp, i, ip, structPointer)" [[@LINE-3]]:10 -> [[@LINE-3]]:52
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:8:10-8:52 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:8:10-8:52 %s -x c | FileCheck --check-prefix=CHECK1 %s
+
+#ifndef __cplusplus
+#define bool _Bool
+#define true 1
+#define false 0
+#endif
+
+int boolType(bool b) {
+  bool b2 = true;
+  return boolType(b && b2 && true && false);
+}
+// CHECK2: "static int extracted(bool b, bool b2) {\nreturn boolType(b && b2 && true && false);\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK2-NEXT: "extracted(b, b2)" [[@LINE-3]]:10 -> [[@LINE-3]]:44
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:24:10-24:44 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:24:10-24:44 %s -x c | FileCheck --check-prefix=CHECK2 %s
+
+int global = 0;
+
+void dontCaptureGlobalVariable() {
+  static int staticInFunction = 0;
+  int i = global + staticInFunction;
+}
+// CHECK3: "static int extracted(int staticInFunction) {\nreturn global + staticInFunction;\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK3-NEXT: "extracted(staticInFunction)" [[@LINE-3]]:11 -> [[@LINE-3]]:36
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:36:11-36:36 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:36:11-36:36 %s -x c | FileCheck --check-prefix=CHECK3 %s
+
+#ifdef __cplusplus
+
+int referenceType(const Rectangle &r, int &i) {
+  return referenceType(r, i);
+}
+// CHECK4: "static int extracted(int &i, const Rectangle &r) {\nreturn referenceType(r, i);\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK4-NEXT: "extracted(i, r)" [[@LINE-3]]:10 -> [[@LINE-3]]:29
+
+#endif
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:47:10-47:29 %s | FileCheck --check-prefix=CHECK4 %s
+
+typedef union {
+  int x;
+  Rectangle r;
+} Union;
+
+int aggregateTypeNotMutated(Rectangle r, Union u) {
+  Rectangle r2 = r;
+  Union u2 = u;
+  aggregateTypeNotMutated(r, u);
+  return aggregateTypeNotMutated(r2, u2);
+}
+// CHECK5-CPP: "static int extracted(const Rectangle &r, const Union &u) {\nreturn aggregateTypeNotMutated(r, u);\n}\n\n" [[@LINE-6]]:1 -> [[@LINE-6]]:1
+// CHECK5-CPP-NEXT: "extracted(r, u)" [[@LINE-4]]:3 -> [[@LINE-4]]:32
+// CHECK5-C: "static int extracted(const Rectangle *r, const Union *u) {\nreturn aggregateTypeNotMutated(*r, *u);\n}\n\n" [[@LINE-8]]:1 -> [[@LINE-8]]:1
+// CHECK5-C-NEXT: "extracted(&r, &u)" [[@LINE-6]]:3 -> [[@LINE-6]]:32
+// CHECK5-CPP: "static int extracted(const Rectangle &r2, const Union &u2) {\nreturn aggregateTypeNotMutated(r2, u2);\n}\n\n" [[@LINE-10]]:1 -> [[@LINE-10]]:1
+// CHECK5-CPP-NEXT: "extracted(r2, u2)" [[@LINE-7]]:10 -> [[@LINE-7]]:41
+// CHECK5-C: "static int extracted(const Rectangle *r2, const Union *u2) {\nreturn aggregateTypeNotMutated(*r2, *u2);\n}\n\n" [[@LINE-12]]:1 -> [[@LINE-12]]:1
+// CHECK5-C-NEXT: "extracted(&r2, &u2)" [[@LINE-9]]:10 -> [[@LINE-9]]:41
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:64:3-64:32 -selected=%s:65:10-65:41 %s | FileCheck --check-prefix=CHECK5-CPP %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:64:3-64:32 -selected=%s:65:10-65:41 %s -x c | FileCheck --check-prefix=CHECK5-C %s
+;
+int arrayType(const int x[]) {
+  int v[2] = {1, 2};
+  arrayType(x);
+  return arrayType(v);
+}
+// CHECK6: "static int extracted(const int *x) {\nreturn arrayType(x);\n}\n\n" [[@LINE-5]]:1 -> [[@LINE-5]]:1
+// CHECK6-NEXT: "extracted(x)" [[@LINE-4]]:3 -> [[@LINE-4]]:15
+// CHECK6: "static int extracted(int *v) {\nreturn arrayType(v);\n}\n\n" [[@LINE-7]]:1 -> [[@LINE-7]]:1
+// CHECK6-NEXT: "extracted(v)" [[@LINE-5]]:10 -> [[@LINE-5]]:22
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:81:3-81:15 -selected=%s:82:10-82:22 %s | FileCheck --check-prefix=CHECK6 %s
+
+typedef enum {
+  EnumA, EnumB
+} Enum;
+
+int enumType(Enum e) {
+  return enumType(e);
+}
+// CHECK7: "static int extracted(Enum e) {\nreturn enumType(e);\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK7-NEXT: "extracted(e)" [[@LINE-3]]:10 -> [[@LINE-3]]:21
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:96:10-96:21 %s | FileCheck --check-prefix=CHECK7 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:96:10-96:21 %s -x c | FileCheck --check-prefix=CHECK7 %s
+;
+int qualifierReduction(const int i, const int * const p, int *volatile pv, int *__restrict__ rv,
+                       const Enum e) {
+  return qualifierReduction(i, p, pv, rv, e);
+}
+// CHECK8: "static int extracted(Enum e, int i, const int *p, int *volatile pv, int *__restrict rv) {\nreturn qualifierReduction(i, p, pv, rv, e);\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK8-NEXT: "extracted(e, i, p, pv, rv)" [[@LINE-3]]:10 -> [[@LINE-3]]:45
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:106:10-106:45 %s | FileCheck --check-prefix=CHECK8 %s
+
+#ifdef __cplusplus
+
+int autoTypeHandling(int x, Rectangle &ref) {
+  auto i = x;
+  auto &r = ref;
+  return autoTypeHandling(i, r);
+}
+// CHECK9: "static int extracted(int i, Rectangle &r) {\nreturn autoTypeHandling(i, r);\n}\n\n" [[@LINE-5]]:1 -> [[@LINE-5]]:1
+// CHECK9-NEXT: "extracted(i, r)" [[@LINE-3]]:10 -> [[@LINE-3]]:32
+
+#endif
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:118:10-118:32 %s | FileCheck --check-prefix=CHECK9 %s
+
+Rectangle globalRect;
+int capturedVariableMutation(int x, int y, int z, const int *ip, Rectangle r) {
+  return x = 0, y += 2, z &= 3, ip = 0, r = globalRect, capturedVariableMutation(x, 1, 2, ip, r);
+}
+// CHECK10-CPP: "static int extracted(const int *&ip, Rectangle &r, int &x, int &y, int &z) {\nreturn x = 0, y += 2, z &= 3, ip = 0, r = globalRect, capturedVariableMutation(x, 1, 2, ip, r);\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK10-CPP-NEXT: "extracted(ip, r, x, y, z)" [[@LINE-3]]:10 -> [[@LINE-3]]:97
+
+// CHECK10-C: "static int extracted(const int **ip, Rectangle *r, int *x, int *y, int *z) {\nreturn *x = 0, *y += 2, *z &= 3, *ip = 0, *r = globalRect, capturedVariableMutation(*x, 1, 2, *ip, *r);\n}\n\n" [[@LINE-6]]:1 -> [[@LINE-6]]:1
+// CHECK10-C-NEXT: "extracted(&ip, &r, &x, &y, &z)" [[@LINE-6]]:10 -> [[@LINE-6]]:97
+
+#ifdef __cplusplus
+
+int capturedMutatedRef(Rectangle &r) {
+  return r = globalRect, capturedMutatedRef(r);
+}
+// CHECK10-CPP: "static int extracted(Rectangle &r) {\nreturn r = globalRect, capturedMutatedRef(r);\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK10-CPP-NEXT: "extracted(r)" [[@LINE-3]]:10 -> [[@LINE-3]]:47
+
+#endif
+
+int capturedArrayMutation(int x[]) {
+  return (x) = 0, capturedArrayMutation(x);
+}
+// CHECK10-CPP: "static int extracted(int *&x) {\nreturn (x) = 0, capturedArrayMutation(x);\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK10-CPP-NEXT: "extracted(x)" [[@LINE-3]]:10 -> [[@LINE-3]]:43
+// CHECK10-C: "static int extracted(int **x) {\nreturn (*x) = 0, capturedArrayMutation(*x);\n}\n\n" [[@LINE-5]]:1 -> [[@LINE-5]]:1
+// CHECK10-C-NEXT: "extracted(&x)" [[@LINE-5]]:10 -> [[@LINE-5]]:43
+;
+void mutationOutsideOfExtractedCode(int x) {
+  x = 0;
+  x = 1, mutationOutsideOfExtractedCode(x + 1);
+  x = 2;
+  return 0;
+}
+// CHECK10-CPP: "static void extracted(int x) {\nmutationOutsideOfExtractedCode(x + 1);\n}\n\n" [[@LINE-6]]:1 -> [[@LINE-6]]:1
+// CHECK10-CPP-NEXT: "extracted(x)" [[@LINE-5]]:10 -> [[@LINE-5]]:47
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:129:10-129:97 -selected=%s:140:10-140:47 -selected=%s:148:10-148:43 -selected=%s:157:10-157:47 %s | FileCheck --check-prefix=CHECK10-CPP %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:129:10-129:97 -selected=%s:148:10-148:43 %s -x c | FileCheck --check-prefix=CHECK10-C %s
+;
+void extractStatementRangeRewritePointerUse(int x) {
+  extractStatementRangeRewritePointerUse(x);
+  x = 1;
+  extractStatementRangeRewritePointerUse(x);
+  extractStatementRangeRewritePointerUse(x);
+}
+// CHECK11: "static void extracted(int *x) {\n*x = 1;\n  extractStatementRangeRewritePointerUse(*x);\n}\n\n" [[@LINE-6]]:1
+// CHECK11-NEXT: "extracted(&x)" [[@LINE-5]]:3 -> [[@LINE-4]]:44
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:169:3-170:10 %s -x c | FileCheck --check-prefix=CHECK11 %s
+
+void mutationAfterUse(int x) {
+  int y = x;
+  (void)y;
+  y = 2;
+}
+// CHECK12: "static void extracted(int &y) {\n(void)y;\n  y = 2;\n}\n\n"
+// RUN: clang-refactor-test perform -action extract -selected=%s:180:3-181:4 %s | FileCheck --check-prefix=CHECK12 %s
+
+enum TagEnum {
+  TagEnumA, TagEnumB
+};
+
+int tagEnumType(enum TagEnum e) {
+  return tagEnumType(e);
+}
+// CHECK13: (enum TagEnum e)
+// RUN: clang-refactor-test perform -action extract -selected=%s:191:10-191:24 %s | FileCheck --check-prefix=CHECK13 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:191:10-191:24 %s -x c | FileCheck --check-prefix=CHECK13 %s
+
+struct TagStruct {
+  int x;
+};
+
+int tagStructType(struct TagStruct *s) {
+  return tagStructType(s);
+}
+// CHECK14: (struct TagStruct *s)
+// RUN: clang-refactor-test perform -action extract -selected=%s:202:10-202:26 %s | FileCheck --check-prefix=CHECK14 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:202:10-202:26 %s -x c | FileCheck --check-prefix=CHECK14 %s
+
+namespace {
+struct Foo { int x; };
+}
+
+void anonymousNamespaceTypes() {
+  Foo x;
+// anonymous-ns-type1-begin: +1:1
+  x.x = 0;
+// anonymous-ns-type1-end: +0:1
+// CHECK-ANON: "static void extracted(Foo &x) {\nx.x = 0;\n}\n\n"
+// anonymous-ns-type2-begin: +1:7
+  x = Foo { 0 };
+// anonymous-ns-type2-end: -1:16
+// CHECK-ANON: "static Foo extracted() {\nreturn Foo { 0 };\n}\n\n"
+}
+// RUN: clang-refactor-test perform -action extract -selected=anonymous-ns-type1 -selected=anonymous-ns-type2 %s -std=c++11 | FileCheck --check-prefix=CHECK-ANON %s
diff --git a/test/Refactor/Extract/captured-variable-types.m b/test/Refactor/Extract/captured-variable-types.m
new file mode 100644
index 0000000..d764217
--- /dev/null
+++ b/test/Refactor/Extract/captured-variable-types.m
@@ -0,0 +1,56 @@
+
+@interface Interface
+
+@end
+
+@protocol Protocol
+
+@end
+
+int basicObjCTypes(Interface *ip, id p, id<Protocol> pp, Interface<Protocol> *ipp) {
+  return basicObjCTypes(ip, p, pp, ipp);
+}
+// CHECK1: "static int extracted(Interface *ip, Interface<Protocol> *ipp, id p, id<Protocol> pp) {\nreturn basicObjCTypes(ip, p, pp, ipp);\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK1-NEXT: "extracted(ip, ipp, p, pp)" [[@LINE-3]]:10 -> [[@LINE-3]]:40
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:11:10-11:40 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:11:10-11:40 %s -x objective-c++ | FileCheck --check-prefix=CHECK1 %s
+
+typedef signed char BOOL;
+#define YES __objc_yes
+#define NO __objc_no
+
+int boolType(BOOL b) {
+  BOOL b2 = YES;
+  return boolType(b && b2 && YES && NO);
+}
+// CHECK2: "static int extracted(BOOL b, BOOL b2) {\nreturn boolType(b && b2 && YES && NO);\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK2-NEXT: "extracted(b, b2)" [[@LINE-3]]:10 -> [[@LINE-3]]:40
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:25:10-25:40 %s | FileCheck --check-prefix=CHECK2 %s
+;
+int mutationOfObjCPointer(Interface *ip) {
+  return ip = 0, mutationOfObjCPointer(ip);
+}
+// CHECK3-C: "static int extracted(Interface **ip) {\nreturn *ip = 0, mutationOfObjCPointer(*ip);\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK3-C-NEXT: "extracted(&ip)" [[@LINE-3]]:10 -> [[@LINE-3]]:43
+// CHECK3-CPP: "static int extracted(Interface *&ip) {\nreturn ip = 0, mutationOfObjCPointer(ip);\n}\n\n" [[@LINE-5]]:1 -> [[@LINE-5]]:1
+// CHECK3-CPP-NEXT: "extracted(ip)" [[@LINE-5]]:10 -> [[@LINE-5]]:43
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:33:10-33:43 %s | FileCheck --check-prefix=CHECK3-C %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:33:10-33:43 %s -x objective-c++ | FileCheck --check-prefix=CHECK3-CPP %s
+
+void silenceStrongInARC() {
+  Interface *pointer;
+// silence-strong-in-arc-begin: +1:1
+  mutationOfObjCPointer(pointer);
+// silence-strong-in-arc-end: +0:1
+// silence-strong2-in-arc-begin: +1:1
+  pointer = 0;
+// silence-strong2-in-arc-end: +0:1
+  (void)pointer;
+}
+// CHECK-ARC: "static int extracted(Interface *pointer) {\nreturn mutationOfObjCPointer(pointer);\n}\n\n"
+// CHECK-ARC: "static void extracted(Interface **pointer) {\n*pointer = 0;\n}\n\n"
+
+// RUN: clang-refactor-test perform -action extract -selected=silence-strong-in-arc -selected=silence-strong2-in-arc %s -fobjc-arc | FileCheck --check-prefix=CHECK-ARC %s
diff --git a/test/Refactor/Extract/disallowed-expressions.cpp b/test/Refactor/Extract/disallowed-expressions.cpp
new file mode 100644
index 0000000..522cb59
--- /dev/null
+++ b/test/Refactor/Extract/disallowed-expressions.cpp
@@ -0,0 +1,50 @@
+void disallowExtractOfSimpleExpressions(int param) {
+  int var = param;
+  short var2 = (short)(var);
+  int x = 0;
+  const char *s = "Test";
+  char c = 'C';
+  double y = ((2.1));
+  const char *f = __func__;
+}
+
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:2:13-2:18 -selected=%s:2:14-2:15 -selected=%s:2:16-2:18 %s 2>&1 | FileCheck %s
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:3:16-3:28 -selected=%s:4:11-4:12 -selected=%s:5:19-5:25 %s 2>&1 | FileCheck %s
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:6:12-6:15 -selected=%s:7:14-7:21 -selected=%s:8:19-8:27 %s 2>&1 | FileCheck %s
+
+// CHECK: Failed to initiate the refactoring action (the selected expression is too simple)!
+
+void allowOperationsOnSimpleExpression(int x, int y) {
+  int z = x + y;
+  int zz = 0 + 1;
+  allowOperationsOnSimpleExpression(1, y);
+}
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:18:11-18:16 %s | FileCheck --check-prefix=CHECK1 %s
+// CHECK1: Initiated the 'extract' action at 18:11 -> 18:16
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:19:12-19:17 %s | FileCheck --check-prefix=CHECK2 %s
+// CHECK2: Initiated the 'extract' action at 19:12 -> 19:17
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:20:37-20:41 %s | FileCheck --check-prefix=CHECK3 %s
+// CHECK3: Initiated the 'extract' action at 20:3 -> 20:42
+
+void defaultParameter(int x = 0 + 1) {
+
+}
+
+struct Struct {
+  int y = 22 + 21;
+
+  Struct(int x) : y(x + 1) { }
+};
+
+int initializerExpression = 1 + 2;
+
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:32:31-32:36 -selected=%s:37:11-37:18 -selected=%s:39:21-39:26 -selected=%s:42:29-42:34 %s 2>&1 | FileCheck --check-prefix=NOT-IN-FUNC %s
+// NOT-IN-FUNC: Failed to initiate the refactoring action (the selected expression is not in a function)!
+
+void disallowWholeFunctionBody() {
+  int x = 0;
+}
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:47:34-49:2 %s 2>&1 | FileCheck --check-prefix=NOT-IN-FUNC %s
diff --git a/test/Refactor/Extract/extract-address-of-captured-variable.cpp b/test/Refactor/Extract/extract-address-of-captured-variable.cpp
new file mode 100644
index 0000000..c2d4a79
--- /dev/null
+++ b/test/Refactor/Extract/extract-address-of-captured-variable.cpp
@@ -0,0 +1,194 @@
+
+void takesVoidPtr(void *x) { }
+void takesPtr(int *x) { }
+void takesPtrPtr(int **x) { }
+
+void addressOfVariableImpliesPossibleMutation(int x, int *ip) {
+  takesPtr(&x);
+// CHECK1-C: (int *x) {\ntakesPtr(x);\n}
+// CHECK1-CPP: (int &x) {\ntakesPtr(&x);\n}
+  takesVoidPtr(&x);
+// CHECK1-C: (int *x) {\ntakesVoidPtr(x);\n}
+// CHECK1-CPP: (int &x) {\ntakesVoidPtr(&x);\n}
+  &x;
+// CHECK1-C: (int *x) {\nreturn x;\n}
+// CHECK1-CPP: (int &x) {\nreturn &x;\n}
+  *(&x) = 0;
+// CHECK1-C: extracted(int *x) {\n*(x) = 0;\n}
+// CHECK1-CPP: extracted(int &x) {\n*(&x) = 0;\n}
+  takesPtrPtr(&ip);
+// CHECK1-C: (int **ip) {\ntakesPtrPtr(ip);\n}
+// CHECK1-CPP: (int *&ip) {\ntakesPtrPtr(&ip);\n}
+  takesPtr(ip);
+// CHECK1-C: (int *ip) {\ntakesPtr(ip);\n}
+// CHECK1-CPP: (int *ip) {\ntakesPtr(ip);\n}
+  takesVoidPtr(ip);
+// CHECK1-C: (int *ip) {\ntakesVoidPtr(ip);\n}
+// CHECK1-CPP: (int *ip) {\ntakesVoidPtr(ip);\n}
+  takesPtr(&((x)));
+// CHECK1-C: (int *x) {\ntakesPtr(((x)));\n}
+// CHECK1-CPP: (int &x) {\ntakesPtr(&((x)));\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:7:3-7:15 -selected=%s:10:3-10:19 -selected=%s:13:3-13:5 -selected=%s:16:3-16:12 -selected=%s:19:3-19:19 -selected=%s:22:3-22:15 -selected=%s:25:3-25:19 -selected=%s:28:3-28:19 %s -x c | FileCheck --check-prefix=CHECK1-C %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:7:3-7:15 -selected=%s:10:3-10:19 -selected=%s:13:3-13:5 -selected=%s:16:3-16:12 -selected=%s:19:3-19:19 -selected=%s:22:3-22:15 -selected=%s:25:3-25:19 -selected=%s:28:3-28:19 %s | FileCheck --check-prefix=CHECK1-CPP %s
+
+typedef struct {
+  int width, height;
+} Rectangle;
+
+void takesStructPtr(Rectangle *sp) { }
+
+#ifdef __cplusplus
+
+void addressOfRef(int &x, int *&ip, Rectangle &r) {
+  takesPtr(&x);
+// CHECK2: (int &x) {\ntakesPtr(&x);\n}
+  takesPtrPtr(&ip);
+// CHECK2: (int *&ip) {\ntakesPtrPtr(&ip);\n}
+  takesStructPtr(&r);
+// CHECK2: (Rectangle &r) {\ntakesStructPtr(&r);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:45:3-45:15 -selected=%s:47:3-47:19 -selected=%s:49:3-49:21  %s | FileCheck --check-prefix=CHECK2 %s
+
+#endif
+
+void addressOfArray(int x[]) {
+  takesPtrPtr(&x);
+// CHECK3-C: (int **x) {\ntakesPtrPtr(x);\n}
+// CHECK3-CPP: (int *&x) {\ntakesPtrPtr(&x);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:58:3-58:18 %s -x c | FileCheck --check-prefix=CHECK3-C %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:58:3-58:18 %s | FileCheck --check-prefix=CHECK3-CPP %s
+
+typedef struct {
+  Rectangle r;
+} RectangleInStruct;
+
+void addressOfMember(Rectangle r, RectangleInStruct rs) {
+  takesPtr(&r.width);
+// CHECK4-C: (Rectangle *r) {\ntakesPtr(&r->width);\n}
+// CHECK4-CPP: (Rectangle &r) {\ntakesPtr(&r.width);\n}
+  takesPtr(&(rs).r.width);
+// CHECK4-C: (RectangleInStruct *rs) {\ntakesPtr(&(rs)->r.width);\n}
+// CHECK4-CPP: (RectangleInStruct &rs) {\ntakesPtr(&(rs).r.width);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:71:3-71:21 -selected=%s:74:3-74:26 %s -x c | FileCheck --check-prefix=CHECK4-C %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:71:3-71:21 -selected=%s:74:3-74:26 %s | FileCheck --check-prefix=CHECK4-CPP %s
+
+void takesConstPtr(const int *x) { }
+
+#ifdef __cplusplus
+
+void addressOfMember(const Rectangle &r) {
+  takesConstPtr(&r.width);
+// CHECK5: (const Rectangle &r) {\ntakesConstPtr(&r.width);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:87:3-87:26 %s | FileCheck --check-prefix=CHECK5 %s
+
+class PrivateInstanceVariables {
+  int x;
+  Rectangle r;
+
+  void method() {
+    takesPtr(&x);
+// CHECK6: extracted(int &x) {\ntakesPtr(&x);\n}
+    takesStructPtr(&(r));
+// CHECK6: extracted(Rectangle &r) {\ntakesStructPtr(&(r));\n}
+    takesPtr(&((r).width));
+// CHECK6: extracted(Rectangle &r) {\ntakesPtr(&((r).width));\n}
+  }
+};
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:98:5-98:17 -selected=%s:100:5-100:25 -selected=%s:102:5-102:27 %s | FileCheck --check-prefix=CHECK6 %s
+
+#endif
+
+void takesCVoidPtr(const void *x) { }
+void takesCPtr(const int *x) { }
+void takesCPtrPtr(int * const *x) { }
+void takesBothPtrs(const int *x, int *y) {}
+void addressForConstUseShouldPassAsConst(int x, int *ip) {
+  takesCPtr(&x);
+// CHECK7-C: (const int *x) {\ntakesCPtr(x);\n}
+// CHECK7-CPP: (const int &x) {\ntakesCPtr(&x);\n}
+  takesCVoidPtr((&(x)));
+// CHECK7-C: (const int *x) {\ntakesCVoidPtr(((x)));\n}
+// CHECK7-CPP: (const int &x) {\ntakesCVoidPtr((&(x)));\n}
+  takesCPtrPtr(&ip);
+// CHECK7-C: (int *const *ip) {\ntakesCPtrPtr(ip);\n}
+// CHECK7-CPP: (int *const &ip) {\ntakesCPtrPtr(&ip);\n}
+  takesCPtr(ip);
+// CHECK7-C: (int *ip) {\ntakesCPtr(ip);\n}
+// CHECK7-CPP: (int *ip) {\ntakesCPtr(ip);\n}
+  takesBothPtrs(&x, &x);
+// CHECK7-C: (int *x) {\ntakesBothPtrs(x, x);\n}
+// CHECK7-CPP: (int &x) {\ntakesBothPtrs(&x, &x);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:116:3-116:16 -selected=%s:119:3-119:22 -selected=%s:122:3-122:20 -selected=%s:125:3-125:16 -selected=%s:128:3-128:24 %s -x c | FileCheck --check-prefix=CHECK7-C %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:116:3-116:16 -selected=%s:119:3-119:22 -selected=%s:122:3-122:20 -selected=%s:125:3-125:16 -selected=%s:128:3-128:24 %s | FileCheck --check-prefix=CHECK7-CPP %s
+
+void addressOfConstUseAndMutation(int x) {
+  x = 0;
+  takesCPtr(&x);
+  x = 1;
+}
+// CHECK8: extracted(int &x) {\nx = 0;\n  takesCPtr(&x);\n}
+// CHECK8: extracted(int &x) {\ntakesCPtr(&x);\n  x = 1;\n}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:137:3-138:16 -selected=%s:138:3-139:8 %s | FileCheck --check-prefix=CHECK8 %s
+
+void takesCStructPtr(const Rectangle *r) { }
+
+void constAddressOfMember(Rectangle r, RectangleInStruct rs) {
+  takesCStructPtr(&r);
+// CHECK9-C: extracted(const Rectangle *r) {\ntakesCStructPtr(r);\n}
+// CHECK9-CPP: extracted(const Rectangle &r) {\ntakesCStructPtr(&r);\n}
+  takesCPtr(&r.width);
+// CHECK9-C: (const Rectangle *r) {\ntakesCPtr(&r->width);\n}
+// CHECK9-CPP: (const Rectangle &r) {\ntakesCPtr(&r.width);\n}
+  takesCPtr((&(rs).r.height));
+// CHECK9-C: (const RectangleInStruct *rs) {\ntakesCPtr((&(rs)->r.height));\n}
+// CHECK9-CPP: (const RectangleInStruct &rs) {\ntakesCPtr((&(rs).r.height));\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:149:3-149:22 -selected=%s:152:3-152:22 -selected=%s:155:3-155:30 %s -x c | FileCheck --check-prefix=CHECK9-C %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:149:3-149:22 -selected=%s:152:3-152:22 -selected=%s:155:3-155:30  %s | FileCheck --check-prefix=CHECK9-CPP %s
+
+#ifdef __cplusplus
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:87:3-87:26 %s | FileCheck --check-prefix=CHECK5 %s
+
+class PrivateInstanceVariablesConstAddress {
+  int x;
+  Rectangle r;
+
+  void method() {
+    takesCPtr(&x);
+// CHECK10: extracted(const int &x) {\ntakesCPtr(&x);\n}
+    takesCStructPtr(&r);
+// CHECK10: extracted(const Rectangle &r) {\ntakesCStructPtr(&r);\n}
+  }
+};
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:172:5-172:18 -selected=%s:174:5-174:24 %s | FileCheck --check-prefix=CHECK10 %s
+
+#endif
+
+void rewriteToPtrWithDerefParensForArrow(Rectangle *r) {
+  int y = r->width;
+  r = 0;
+// CHECK11: (Rectangle **r) {\nint y = (*r)->width;\n  *r = 0;\n}\n\n"
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:184:3-185:8 %s -x c | FileCheck --check-prefix=CHECK11 %s
+
+void constAddressWithConditionalOperator(int x, int y) {
+  takesCPtr(&(x == 0 ? x : y));
+// CHECK12: (const int &x, const int &y) {\ntakesCPtr(&(x == 0 ? x : y));\n}
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:191:3-191:31 %s | FileCheck --check-prefix=CHECK12 %s
diff --git a/test/Refactor/Extract/extract-address-of-captured-variable.mm b/test/Refactor/Extract/extract-address-of-captured-variable.mm
new file mode 100644
index 0000000..9d6661c
--- /dev/null
+++ b/test/Refactor/Extract/extract-address-of-captured-variable.mm
@@ -0,0 +1,44 @@
+
+void takesVoidPtr(void *x) { }
+void takesPtr(int *x) { }
+void takesPtrPtr(int **x) { }
+
+#ifdef USECONST
+#define CONST const
+#else
+#define CONST
+#endif
+
+typedef struct {
+  int width, height;
+} Rectangle;
+
+@interface I
+
+- (int)takesPtr:(CONST int *)x;
++ (int)takesPtr:(CONST int *)x;
+- (int)takesVoidPtr:(CONST void *)x;
+- (int)takesStructPtr:(CONST Rectangle *)r;
+
+@end
+
+void methodTakesPtr(I *i, int x, Rectangle r) {
+  [i takesPtr: &x];
+// CHECK1: extracted(I *i, int &x) {\nreturn [i takesPtr: &x];\n}
+// CHECK2: extracted(I *i, const int &x) {\nreturn [i takesPtr: &x];\n}
+  [I takesPtr: (&x)];
+// CHECK1: extracted(int &x) {\nreturn [I takesPtr: (&x)];\n}
+// CHECK2: extracted(const int &x) {\nreturn [I takesPtr: (&x)];\n}
+  [i takesVoidPtr: (&(x))];
+// CHECK1: extracted(I *i, int &x) {\nreturn [i takesVoidPtr: (&(x))];\n}
+// CHECK2: extracted(I *i, const int &x) {\nreturn [i takesVoidPtr: (&(x))];\n}
+  [i takesStructPtr: &r];
+// CHECK1: extracted(I *i, Rectangle &r) {\nreturn [i takesStructPtr: &r];\n}
+// CHECK2: extracted(I *i, const Rectangle &r) {\nreturn [i takesStructPtr: &r];\n}
+  [I takesPtr: &(r).width];
+// CHECK1: extracted(Rectangle &r) {\nreturn [I takesPtr: &(r).width];\n}
+// CHECK2: extracted(const Rectangle &r) {\nreturn [I takesPtr: &(r).width];\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:26:3-26:19 -selected=%s:29:3-29:21 -selected=%s:32:3-32:27 -selected=%s:35:3-35:25 -selected=%s:38:3-38:27 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:26:3-26:19 -selected=%s:29:3-29:21 -selected=%s:32:3-32:27 -selected=%s:35:3-35:25 -selected=%s:38:3-38:27 %s -DUSECONST | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Extract/extract-before-comments.cpp b/test/Refactor/Extract/extract-before-comments.cpp
new file mode 100644
index 0000000..f20e0ab
--- /dev/null
+++ b/test/Refactor/Extract/extract-before-comments.cpp
@@ -0,0 +1,64 @@
+
+// comment 1
+void extractBeforeComment1(int x) {
+  int y = x * x;
+}
+// CHECK1: "static int extracted(int x) {\nreturn x * x;\n}\n\n" [[@LINE-4]]:1
+
+/* comment 2 */
+
+void extractBeforeComment2(int x) {
+  int y = x * x;
+}
+// CHECK1: "static int extracted(int x) {\nreturn x * x;\n}\n\n" [[@LINE-5]]:1
+
+/// comment 1
+///
+/// line 2
+void extractBeforeDocComment1(int x) {
+  int y = x * x;
+}
+// CHECK1: "static int extracted(int x) {\nreturn x * x;\n}\n\n" [[@LINE-6]]:1
+
+/**
+ * @brief extractBeforeDocComment2
+ * @param x
+ */
+void extractBeforeDocComment2(int x) {
+  int y = x * x;
+}
+// CHECK1: "static int extracted(int x) {\nreturn x * x;\n}\n\n" [[@LINE-7]]:1
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:4:11-4:16 -selected=%s:11:11-11:16 -selected=%s:19:11-19:16 -selected=%s:28:11-28:16 %s | FileCheck --check-prefix=CHECK1 %s
+
+/**
+ * @brief The AClass class
+ */
+class AClass {
+
+  /// doc comment
+  int method(int x) {
+    return x * x;
+  }
+// CHECK2: "static int extracted(int x) {\nreturn x * x;\n}\n\n" [[@LINE-9]]:1
+};
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:41:12-41:17 %s | FileCheck --check-prefix=CHECK2 %s
+
+namespace {
+
+} // end anonymous namespace
+
+void afterBraceAfterComment() { // CHECK3: "static void extracted() {\nint x = 0;\n}\n\n" [[@LINE]]:1
+// after-brace-begin: +1:1
+  int x = 0;
+// after-brace-end: +0:1
+} // another trailing
+// This is valid CHECK3: "static void extracted() {\nint x = 0;\n}\n\n" [[@LINE]]:1
+void inbetweenerTwoComments() {
+// inbetween-begin: +1:1
+  int x = 0;
+// inbetween-end: +0:1
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=after-brace -selected=inbetween %s | FileCheck --check-prefix=CHECK3 %s
diff --git a/test/Refactor/Extract/extract-capture-instance-variable.cpp b/test/Refactor/Extract/extract-capture-instance-variable.cpp
new file mode 100644
index 0000000..b98bc0a
--- /dev/null
+++ b/test/Refactor/Extract/extract-capture-instance-variable.cpp
@@ -0,0 +1,73 @@
+
+typedef struct {
+  int width, height;
+} Rectangle;
+
+class PrivateInstanceVariables {
+  int x;
+  Rectangle r;
+
+  int method() {
+    int y = x;
+    return r.width + r.height * x + y;
+  }
+// CHECK1: (int x) {\nint y = x;\nreturn y;\n}
+// CHECK1-NEXT: extracted(x)
+// CHECK1: extracted(const Rectangle &r, int x) {\nint y = x;\n    return r.width + r.height * x + y;\n}
+// CHECK1-NEXT: extracted(r, x)
+// CHECK1: extracted(const Rectangle &r, int x, int y) {\nreturn r.width + r.height * x + y;\n}
+// CHECK1-NEXT: extracted(r, x, y)
+};
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:11:5-11:14 -selected=%s:11:5-12:38 -selected=%s:12:12-12:38 %s | FileCheck --check-prefix=CHECK1 %s
+
+class PrivateInstanceVariablesExplicitThis {
+  int x;
+
+
+  int method(int y) {
+    y = this->x;
+    {
+      int x = (this)->x;
+    }
+    y = x;
+    x = 0;
+    this->x = 0;
+    y = (y == 0 ? this : (PrivateInstanceVariablesExplicitThis *)0) -> x;
+  }
+// CHECK2: (const PrivateInstanceVariablesExplicitThis &object, int &y) {\ny = object.x;\n    {\n      int x = (object).x;\n    }\n    y = object.x;\n}
+// CHECK2-NEXT: extracted(*this, y)
+// CHECK2: extracted(const PrivateInstanceVariablesExplicitThis &object) {\nint x = (object).x;\n}
+// CHECK2-NEXT: extracted(*this)
+// CHECK2: (PrivateInstanceVariablesExplicitThis &object, int &y) {\ny = object.x;\n    {\n      int x = (object).x;\n    }\n    y = object.x;\n    object.x = 0;\n}
+// CHECK2: (PrivateInstanceVariablesExplicitThis &object) {\nobject.x = 0;\n}
+// CHECK2: (PrivateInstanceVariablesExplicitThis &object, int &y) {\ny = (y == 0 ? &object : (PrivateInstanceVariablesExplicitThis *)0) -> x;\n}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:29:5-33:10 -selected=%s:31:7-31:24 -selected=%s:29:5-34:10 -selected=%s:35:5-35:16 -selected=%s:36:5-36:73 %s | FileCheck --check-prefix=CHECK2 %s
+};
+
+class PublicInstanceVariables { int private_;
+public:
+  int x;
+  Rectangle r;
+
+  void method() {
+    int y; y = x;
+    x = 0;
+    int z = r.width + r.height * x + y;
+    this->x = (this)->r.height + (y == 0 ? this : (PublicInstanceVariables *)0) -> x;
+    x = private_;
+  }
+// CHECK3: (const PublicInstanceVariables &object, int &y) {\ny = object.x;\n}
+// CHECK3: (PublicInstanceVariables &object, int &y) {\ny = object.x;\n    object.x = 0;\n}
+// CHECK3: (PublicInstanceVariables &object) {\nobject.x = 0;\n}
+// CHECK3: (const PublicInstanceVariables &object, int y) {\nint z = object.r.width + object.r.height * object.x + y;\n}
+// CHECK3: (PublicInstanceVariables &object, int y) {\nobject.x = (object).r.height + (y == 0 ? &object : (PublicInstanceVariables *)0) -> x;\n}
+// CHECK3: (PublicInstanceVariables &object, int private_) {\nobject.x = object.private_;\n}
+  void constMethod() const {
+    const_cast<PublicInstanceVariables *>(this)->x = 2;
+  }
+// CHECK3: (const PublicInstanceVariables &object) {\nconst_cast<PublicInstanceVariables *>(&object)->x = 2;\n}
+};
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:55:12-55:17 -selected=%s:55:12-56:10 -selected=%s:56:5-56:10 -selected=%s:57:5-57:39 -selected=%s:58:5-58:85 -selected=%s:59:5-59:17 -selected=%s:68:5-68:55 %s | FileCheck --check-prefix=CHECK3 %s
diff --git a/test/Refactor/Extract/extract-capture-self.m b/test/Refactor/Extract/extract-capture-self.m
new file mode 100644
index 0000000..4f8375a
--- /dev/null
+++ b/test/Refactor/Extract/extract-capture-self.m
@@ -0,0 +1,56 @@
+
+@interface AClass {
+  int ivar1;
+}
+
+@property int prop;
+
+- (int)instanceMethod;
++ (int)classMethod;
+
+@end
+
+@implementation AClass {
+  int ivar2;
+}
+
+- (int)instanceMethod {
+  ivar2 = 0;
+  ivar1 = 0;
+  self->ivar2 = 0;
+  self.prop = 0;
+  int x = self->ivar1;
+  int y = self.prop;
+  [self instanceMethod];
+  [AClass classMethod];
+  return 0;
+}
+// CHECK1: (AClass *object) {\nobject->ivar2 = 0;\n}
+// CHECK1: (AClass *object) {\nobject->ivar2 = 0;\n}
+// CHECK1: (AClass *object) {\nobject.prop = 0;\n}\n\n"
+// CHECK1: (AClass *object) {\nint y = object.prop;\n}
+// CHECK1: (AClass *object) {\nreturn [object instanceMethod];\n}
+// CHECK1: (AClass *object) {\nobject->ivar2 = 0;\n  object->ivar1 = 0;\n  object->ivar2 = 0;\n  object.prop = 0;\n  int x = object->ivar1;\n  int y = object.prop;\n  [object instanceMethod];\n  [AClass classMethod];\n}\n\n"
+// CHECK1: () {\nreturn [AClass classMethod];\n}\n\n"
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:18:3-18:12 -selected=%s:20:3-20:18 -selected=%s:21:3-21:16 -selected=%s:23:3-23:20 -selected=%s:24:3-24:24 -selected=%s:18:3-25:23 -selected=%s:25:3-25:23 %s | FileCheck --check-prefix=CHECK1 %s
+
++ (int)classMethod {
+  int x = self.classMethod;
+  [self classMethod];
+}
+
+// CHECK2: () {\nint x = AClass.classMethod;\n}
+// CHECK2: () {\nreturn [AClass classMethod];\n}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:39:3-39:27 -selected=%s:40:3-40:21 %s | FileCheck --check-prefix=CHECK2 %s
+
+- (void)rhsSelfCaptureAndRewrite:(AClass *)i { // CHECK3: "static void extracted(AClass *object, AClass *i) {\ni.prop= object.prop;\n}\n\n"
+// rhs-prop-begin: +1:3
+  i.prop= self.prop;
+// rhs-prop-end: -1:21
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=rhs-prop %s | FileCheck --check-prefix=CHECK3 %s
+
+@end
diff --git a/test/Refactor/Extract/extract-capture-static-var.cpp b/test/Refactor/Extract/extract-capture-static-var.cpp
new file mode 100644
index 0000000..097e176
--- /dev/null
+++ b/test/Refactor/Extract/extract-capture-static-var.cpp
@@ -0,0 +1,12 @@
+
+
+void captureStaticVars() {
+  static int x;
+  int y = x;
+  x += 1;
+// CHECK1: extracted(int x) {\nint y = x;\n}\n\n"
+// CHECK1: extracted(int &x) {\nx += 1;\n}
+// CHECK1: extracted() {\nstatic int x;\n  int y = x;\n  x += 1;\n}\n\n"
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:5:3-5:12 -selected=%s:6:3-6:9 -selected=%s:4:3-6:9 %s | FileCheck --check-prefix=CHECK1 %s
diff --git a/test/Refactor/Extract/extract-capture-super.m b/test/Refactor/Extract/extract-capture-super.m
new file mode 100644
index 0000000..0b18143
--- /dev/null
+++ b/test/Refactor/Extract/extract-capture-super.m
@@ -0,0 +1,42 @@
+// RUN: clang-refactor-test perform -action extract -selected=super-msg -selected=super-prop -selected=super-self -selected=super-class-msg -selected=super-class-prop %s | FileCheck %s
+
+@interface BaseClass
+
+@property int prop;
+
+- (int)instanceMethod;
++ (void)classMethod;
+
+@property(class) int classProp;
+
+@end
+
+@interface SubClass: BaseClass
+
+@end
+
+@implementation SubClass
+
+- (void)method {
+  // super-msg-begin: +1:1
+  [super instanceMethod];  // CHECK: extracted(BaseClass *superObject) {\n[superObject instanceMethod];\n}
+  // super-msg-end: +0:1   // CHECK: extracted(super.self)
+  // super-prop-begin: +1:11
+  int x = super.prop;      // CHECK: extracted(BaseClass *superObject) {\nreturn superObject.prop;\n}
+  // super-prop-end: -1:21 // CHECK: extracted(super.self)
+  // super-self-begin: +1:1
+  int y = self.prop;      // CHECK: extracted(SubClass *object, BaseClass *superObject) {\nint y = object.prop;\n  int z = superObject.prop;\n}
+  int z = super.prop;     // CHECK: extracted(self, super.self);
+  // super-self-end: +0:1
+}
+
++ (void)classMethod {
+  // super-class-msg-begin: +1:1
+  [super classMethod];         // CHECK: extracted() {\n[BaseClass classMethod];\n}
+  // super-class-msg-end: +0:1 // CHECK: extracted()
+  // super-class-prop-begin: +1:9
+  (void)super.classProp;       // CHECK: extracted() {\nreturn BaseClass.classProp;\n}
+  // super-class-prop-end: -1:24 // CHECK: extracted()
+}
+
+@end
diff --git a/test/Refactor/Extract/extract-capture-this.cpp b/test/Refactor/Extract/extract-capture-this.cpp
new file mode 100644
index 0000000..cb15a5e
--- /dev/null
+++ b/test/Refactor/Extract/extract-capture-this.cpp
@@ -0,0 +1,66 @@
+
+class AClassWithMethods {
+  void method() {
+  }
+  void constMethod() const {
+  }
+  int operator << (int x) const { return x; }
+  int operator >> (int x) { return x; }
+
+  void toBeExtracted() {
+    method();
+    constMethod();
+    *this << 2;
+    *(this) >> 2;
+    this->constMethod();
+    (*(this)).constMethod();
+  }
+// CHECK1: (AClassWithMethods &object) {\nobject.method();\n}
+// CHECK1: (const AClassWithMethods &object) {\nobject.constMethod();\n}
+// CHECK1: (AClassWithMethods &object) {\nobject.method();\n    object.constMethod();\n}
+// CHECK1: (const AClassWithMethods &object) {\nreturn object << 2;\n}
+// CHECK1: (AClassWithMethods &object) {\nreturn (object) >> 2;\n}
+// CHECK1: (const AClassWithMethods &object) {\nobject.constMethod();\n}
+// CHECK1: (const AClassWithMethods &object) {\n((object)).constMethod();\n}
+
+  void toBeExtracted2();
+};
+// RUN: clang-refactor-test perform -action extract -selected=%s:11:5-11:13 -selected=%s:12:5-12:17 -selected=%s:11:5-12:17 -selected=%s:13:5-13:14 -selected=%s:14:5-14:16 -selected=%s:15:5-15:24 -selected=%s:16:5-16:28 %s | FileCheck --check-prefix=CHECK1 %s
+
+void takesRef(AClassWithMethods &object) {}
+void takesConstRef(const AClassWithMethods &object) {}
+void takesPtr(AClassWithMethods *object) {}
+void takesConstPtr(const AClassWithMethods *object) {}
+
+void AClassWithMethods::toBeExtracted2() {
+  takesRef(*this);
+  takesConstRef((*(this)));
+  takesPtr(this);
+  takesConstPtr((this));
+  takesConstPtr(false ? this : (AClassWithMethods*)0);
+}
+// CHECK2: (AClassWithMethods &object) {\ntakesRef(object);\n}
+// CHECK2: (const AClassWithMethods &object) {\ntakesConstRef(((object)));\n}
+// CHECK2: (AClassWithMethods &object) {\ntakesPtr(&object);\n}
+// CHECK2: (const AClassWithMethods &object) {\ntakesConstPtr((&object));\n}
+// CHECK2: (AClassWithMethods &object) {\ntakesConstPtr(false ? &object : (AClassWithMethods*)0);\n}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:36:3-36:18 -selected=%s:37:3-37:27 -selected=%s:38:3-38:17 -selected=%s:39:3-39:24 -selected=%s:40:3-40:54 %s | FileCheck --check-prefix=CHECK2 %s
+
+#ifdef USECONST
+#define CONST const
+#else
+#define CONST
+#endif
+
+class FallbackToMethodConstness {
+  int getter() const { return 0; }
+  int method(int x, FallbackToMethodConstness *other) CONST {
+    return (x == 0 ? this : other)->getter();
+  }
+// CHECK3: (FallbackToMethodConstness &object, FallbackToMethodConstness *other, int x) {\nreturn (x == 0 ? &object : other)->getter();\n}
+// CHECK3-CONST: (const FallbackToMethodConstness &object, FallbackToMethodConstness *other, int x) {\nreturn (x == 0 ? &object : other)->getter();\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:59:5-59:45 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:59:5-59:45 %s -DUSECONST | FileCheck --check-prefix=CHECK3-CONST %s
diff --git a/test/Refactor/Extract/extract-capture-used-after-extraction.cpp b/test/Refactor/Extract/extract-capture-used-after-extraction.cpp
new file mode 100644
index 0000000..03fff5c
--- /dev/null
+++ b/test/Refactor/Extract/extract-capture-used-after-extraction.cpp
@@ -0,0 +1,214 @@
+
+void takesInt(int x);
+
+typedef struct { int width; int height; } Rectangle;
+
+#ifdef USEINIT1
+#define INIT1 r.width = 0; { int r, y; }
+#else
+#define INIT1 { int r, y; }
+#endif
+
+void extractCaptureUsedAfterSimple(int x) {
+  Rectangle r;
+  INIT1;
+  int y = x * x;
+#ifdef USEAFTER1
+  takesInt(y);
+#endif
+#ifdef USEAFTER2
+  takesInt(r.height);
+#endif
+#ifdef USEAFTER3
+  r.width = 0;
+#endif
+#ifdef USEAFTER4
+  y += 1;
+#endif
+}
+// CHECK1: "static void extracted(int x) {\nRectangle r;\n  INIT1;\n  int y = x * x;\n}\n\n"
+// CHECK1-NEXT: "extracted(x);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s | FileCheck --check-prefix=CHECK1 %s
+
+// CHECK2: "static void extracted(Rectangle &r, int x, int &y) {\n\n  INIT1;\n  y = x * x;\n}\n\n"
+// CHECK2-NEXT: "Rectangle r;\nint y;\nextracted(r, x, y);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s -DUSEINIT1 -DUSEAFTER1 -DUSEAFTER2 | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s -DUSEINIT1 -DUSEAFTER3 -DUSEAFTER4 | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s -DUSEINIT1 -DUSEAFTER1 -DUSEAFTER2 -DUSEAFTER3 -DUSEAFTER4 | FileCheck --check-prefix=CHECK2 %s
+
+// CHECK3: "static void extracted(int x, int &y) {\n\n  INIT1;\n  y = x * x;\n}\n\n"
+// CHECK3-NEXT: "Rectangle r;\nint y;\nextracted(x, y);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s -DUSEAFTER1 -DUSEAFTER2 | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s -DUSEAFTER3 -DUSEAFTER4 | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s -DUSEAFTER1 -DUSEAFTER2 -DUSEAFTER3 -DUSEAFTER4 | FileCheck --check-prefix=CHECK3 %s
+
+// CHECK4: "static void extracted(int x, int &y) {\nRectangle r;\n  INIT1;\n  y = x * x;\n}\n\n"
+// CHECK4-NEXT: "int y;\nextracted(x, y);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s -DUSEINIT1 -DUSEAFTER1 | FileCheck --check-prefix=CHECK4 %s
+
+// CHECK5: "static void extracted(Rectangle &r, int x) {\n\n  INIT1;\n  int y = x * x;\n}\n\n"
+// CHECK5-NEXT: "Rectangle r;\nextracted(r, x);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s -DUSEINIT1 -DUSEAFTER3 | FileCheck --check-prefix=CHECK5 %s
+
+// CHECK6: "static void extracted(int x) {\n\n  INIT1;\n  int y = x * x;\n}\n\n"
+// CHECK6-NEXT: "Rectangle r;\nextracted(x);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:13:3-15:16 %s -DUSEAFTER3 | FileCheck --check-prefix=CHECK6 %s
+
+void extractCaptureAfterUseMultipleDecls() {
+#ifdef MULTIPLE_DECL1
+  int x = 1, y = 2, z = 3; { int x, y, z; };
+#endif
+#ifdef MULTIPLE_DECL2
+  int x, y = 2, *z; { int y; }
+#endif
+#ifdef MULTIPLE_DECL3
+  int x = 1, y, * z = 0, a, b = {0}; { int a; }
+#endif
+#ifdef USEX
+  x;
+#endif
+#ifdef USEY
+  y;
+#endif
+#ifdef USEZ
+  z;
+#endif
+#ifdef USEA
+  a;
+#endif
+#ifdef USEB
+  b;
+#endif
+}
+
+// CHECK7: "static void extracted() {\nint x = 1, y = 2, z = 3;\n}\n\n"
+// CHECK7-NEXT; "extracted();"
+// RUN: clang-refactor-test perform -action extract -selected=%s:59:3-59:26 %s -DMULTIPLE_DECL1 | FileCheck --check-prefix=CHECK7 %s
+// CHECK8: "static void extracted(int &x, int &y, int &z) {\nx = 1; y = 2; z = 3;\n}\n\n"
+// CHECK8-NEXT: "int x;\nint y;\nint z;\nextracted(x, y, z);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:59:3-59:26 %s -DMULTIPLE_DECL1 -DUSEX -DUSEY -DUSEZ | FileCheck --check-prefix=CHECK8 %s
+// CHECK9: "static void extracted(int &x) {\nx = 1; int y = 2; int z = 3; { int x, y, z; }\n}\n\n"
+// CHECK9-NEXT: "int x;\nextracted(x);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:59:3-59:44 %s -DMULTIPLE_DECL1 -DUSEX | FileCheck --check-prefix=CHECK9 %s
+// CHECK10: "static void extracted(int &y) {\nint x = 1; y = 2; int z = 3; { int x, y, z; }\n}\n\n"
+// CHECK10-NEXT: "int y;\nextracted(y);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:59:3-59:44 %s -DMULTIPLE_DECL1 -DUSEY | FileCheck --check-prefix=CHECK10 %s
+// CHECK11: "static void extracted(int &z) {\nint x = 1; int y = 2; z = 3; { int x, y, z; }\n}\n\n"
+// CHECK11-NEXT: "int z;\nextracted(z);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:59:3-59:44 %s -DMULTIPLE_DECL1 -DUSEZ | FileCheck --check-prefix=CHECK11 %s
+
+// CHECK12: "static void extracted() {\nint x, y = 2, *z;\n}\n\n"
+// CHECK12-NEXT: "extracted();"
+// RUN: clang-refactor-test perform -action extract -selected=%s:62:3-62:19 %s -DMULTIPLE_DECL2 | FileCheck --check-prefix=CHECK12 %s
+// CHECK13: "static void extracted(int &y) {\ny = 2;\n}\n\n"
+// CHECK13-NEXT: "int x;\nint y;\nint * z;\nextracted(y);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:62:3-62:19 %s -DMULTIPLE_DECL2 -DUSEX -DUSEY -DUSEZ | FileCheck --check-prefix=CHECK13 %s
+// CHECK14: "static void extracted(int &y) {\nint x; y = 2; int * z; { int y; }\n}\n\n"
+// CHECK14-NEXT: "int y;\nextracted(y);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:62:3-62:31 %s -DMULTIPLE_DECL2 -DUSEY | FileCheck --check-prefix=CHECK14 %s
+
+// CHECK15: "static void extracted() {\nint x = 1, y, * z = 0, a, b = {0};\n}\n\n"
+// CHECK15-NEXT: "extracted();"
+// RUN: clang-refactor-test perform -action extract -selected=%s:65:3-65:36 %s -DMULTIPLE_DECL3 | FileCheck --check-prefix=CHECK15 %s
+// CHECK16: "static void extracted(int &x, int *&z) {\nx = 1; z = 0; int a; int b = {0};\n}\n\n"
+// CHECK16-NEXT: "int x;\nint y;\nint * z;\nextracted(x, z);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:65:3-65:36 %s -DMULTIPLE_DECL3 -DUSEX -DUSEY -DUSEZ | FileCheck --check-prefix=CHECK16 %s
+// CHECK17: "static void extracted(int &b, int &x, int *&z) {\nx = 1; z = 0; b = {0};\n}\n\n"
+// CHECK17-NEXT: "int x;\nint y;\nint * z;\nint a;\nint b;\nextracted(b, x, z);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:65:3-65:36 %s -DMULTIPLE_DECL3 -DUSEX -DUSEY -DUSEZ -DUSEA -DUSEB | FileCheck --check-prefix=CHECK17 %s
+// CHECK18: "static void extracted() {\nint x = 1; int y; int * z = 0; int b = {0}; { int a; }\n}\n\n"
+// CHECK18-NEXT: "int a;\nextracted();"
+// RUN: clang-refactor-test perform -action extract -selected=%s:65:3-65:48 %s -DMULTIPLE_DECL3 -DUSEA | FileCheck --check-prefix=CHECK18 %s
+
+#define ONE 1
+
+void preserveInitExpressionText() {
+  int a = ONE;
+  int x = ONE, y = ONE;
+  a, y;
+}
+
+// CHECK19: "static void extracted(int &a, int &y) {\na = ONE;\n  int x = ONE; y = ONE;\n}\n\n
+// CHECK19-NEXT: "int a;\nint y;\nextracted(a, y);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:126:3-127:23 %s | FileCheck --check-prefix=CHECK19 %s
+
+class Construct {
+public:
+  Construct();
+  Construct(int x, int y);
+};
+
+void handleConstruct() {
+  Construct a(1, 2);
+  Construct b(3, 4), c(5, 6);
+  a, c;
+}
+// CHECK20: "static void extracted(Construct &a, Construct &c) {\na = Construct(1, 2);\n  Construct b(3, 4); c = Construct(5, 6);\n}\n\n"
+// CHECK20-NEXT: "Construct a;\nConstruct c;\nextracted(a, c);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:142:3-143:29 %s | FileCheck --check-prefix=CHECK20 %s
+
+struct Construct2 {
+  int x, y;
+};
+
+void handleConstruct2() {
+  Construct2 a = {1, 2};
+  Construct2 b = {3, 4}, c = {5, 6};
+  a, c;
+}
+// CHECK21: "static void extracted(Construct2 &a, Construct2 &c) {\na = {1, 2};\n  Construct2 b = {3, 4}; c = {5, 6};\n}\n\n"
+// CHECK21-NEXT: "Construct2 a;\nConstruct2 c;\nextracted(a, c);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:155:3-156:29 %s -std=c++11 | FileCheck --check-prefix=CHECK21 %s
+
+class Construct3 {
+public:
+  Construct3();
+  Construct3(int x);
+};
+
+void handleConstruct3() {
+  Construct3 a = 1;
+  Construct3 b = 2, c = 3 + 3;
+  a, c;
+}
+// CHECK22: "static void extracted(Construct3 &a, Construct3 &c) {\na = 1;\n  Construct3 b = 2; c = 3 + 3;\n}\n\n"
+// CHECK22-NEXT: "Construct3 a;\nConstruct3 c;\nextracted(a, c);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:170:3-171:26 %s -std=c++11 | FileCheck --check-prefix=CHECK22 %s
+
+void handleConstruct2InitList() {
+  Construct2 a { 5, 6 };
+  Construct2 b { 1, 2 }, c { 3, 4 };
+  a, c;
+}
+// CHECK23: "static void extracted(Construct2 &a, Construct2 &c) {\na = { 5, 6 };\n  Construct2 b = { 1, 2 }; c = { 3, 4 };\n}\n\n"
+// CHECK23-NEXT: "Construct2 a;\nConstruct2 c;\nextracted(a, c);"
+// RUN: clang-refactor-test perform -action extract -selected=%s:179:3-180:36 %s -std=c++11 | FileCheck --check-prefix=CHECK23 %s
+
+void onlyOneUsedAfterExtractionIsReturned() {
+  const int x = 0;
+  x;
+  Construct a(1, 2);
+  a;
+}
+// CHECK24: "static int extracted() {\nconst int x = 0;\nreturn x;\n}\n\n"
+// CHECK24-NEXT: "const int x = extracted();"
+// CHECK24: "static Construct extracted() {\nConstruct a(1, 2);\nreturn a;\n}\n\n"
+// CHECK24-NEXT: "Construct a = extracted();"
+
+int avoidReturningWhenReturnUsed() {
+  int x = 0;
+  if (x != 0) { return 22; }
+  x;
+}
+// CHECK24: "static int extracted(int &x) {\nx = 0;\n  if (x != 0) { return 22; }\n}\n\n"
+// CHECK24-NEXT: "int x;\nextracted(x);"
+
+void returnOnlyWhenReturnReturnsNothing() {
+  int x = 0;
+  if (x != 0) { return; }
+  x;
+}
+// CHECK24: "static int extracted() {\nint x = 0;\n  if (x != 0) { return x; }\nreturn x;\n}\n\n"
+// CHECK24-NEXT: "int x = extracted();"
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:188:3-188:18 -selected=%s:190:3-190:20 -selected=%s:199:3-200:29 -selected=%s:207:3-208:26 %s -std=c++11 | FileCheck --check-prefix=CHECK24 %s
diff --git a/test/Refactor/Extract/extract-capture-used-after-extraction.m b/test/Refactor/Extract/extract-capture-used-after-extraction.m
new file mode 100644
index 0000000..c115bab
--- /dev/null
+++ b/test/Refactor/Extract/extract-capture-used-after-extraction.m
@@ -0,0 +1,25 @@
+void takesInt(int);
+void passByPointer() {
+  int x = 1;
+  int y = 0, z = 2;
+  takesInt(x);
+  z = 2;
+  x, z;
+}
+// CHECK1: "static void extracted(int *x, int *z) {\n*x = 1;\n  int y = 0; *z = 2;\n  takesInt(*x);\n  *z = 2;\n}\n\n"
+// CHECK1-NEXT: "int x;\nint z;\nextracted(&x, &z)"
+// RUN: clang-refactor-test perform -action extract -selected=%s:3:3-6:8 %s | FileCheck --check-prefix=CHECK1 %s
+
+typedef struct { int width; int height; } Rectangle;
+
+void handleStructInit() {
+  Rectangle a = { 5, 6 };
+  Rectangle b = { 1, 2 }, c = { 3, 4 };
+  takesInt(a.width);
+  c.height = 10;
+  a, c;
+}
+// The produced code is invalid but we can let the user deal with it:
+// CHECK2: "static void extracted(Rectangle *a, Rectangle *c) {\n*a = { 5, 6 };\n  Rectangle b = { 1, 2 }; *c = { 3, 4 };\n  takesInt(a->width);\n  c->height = 10;\n}\n\n" 15:1 -> 15:1
+// CHECK2: "Rectangle a;\nRectangle c;\nextracted(&a, &c)"
+// RUN: clang-refactor-test perform -action extract -selected=%s:16:3-19:16 %s | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Extract/extract-expression-into-var.cpp b/test/Refactor/Extract/extract-expression-into-var.cpp
new file mode 100644
index 0000000..9fd4f7a
--- /dev/null
+++ b/test/Refactor/Extract/extract-expression-into-var.cpp
@@ -0,0 +1,47 @@
+int call(int x);
+
+void extractExpressionIntoVar(int x, int y, int z) {
+  {
+    // expr1-begin: +1:13
+    int p = x + y - z;   // CHECK: "int extractedExpr = x + y;\n" [[@LINE]]:5 -> [[@LINE]]:5 [Symbol extracted-decl 0 1:5 -> 1:18]
+    // expr1-end: -1:19  // CHECK: "extractedExpr" [[@LINE-1]]:13 -> [[@LINE-1]]:18 [Symbol extracted-decl-ref 0 1:1 -> 1:14]
+    // expr2-begin: +1:6 // CHECK: "std::function<void (int)> extractedExpr = [&](int x) {\n       p = x;\n    };\n" [[@LINE+1]]:5 -> [[@LINE+1]]:5 [Symbol extracted-decl 0 1:27 -> 1:40]
+    ([&](int x) {
+       p = x;
+    })(0);
+    // expr2-end: -1:6   // CHECK: "extractedExpr" [[@LINE-3]]:6 -> [[@LINE-1]]:6
+  }
+  #define MACROARG(x) (x)
+  // expr3-begin: +1:20
+  int p = MACROARG(y + z) - x; // CHECK: "int extractedExpr = y + z;\n" [[@LINE]]:3 -> [[@LINE]]:3
+  // expr3-end: -1:25   // CHECK: "extractedExpr" [[@LINE-1]]:20 -> [[@LINE-1]]:25
+  #define MACROSTMT(x, y) int var = (x) + (y);
+  // expr4-begin: +1:16
+  MACROSTMT(0, call(p * z))   // CHECK: "int extractedExpr = call(p * z);\n" [[@LINE]]:3 -> [[@LINE]]:3
+  // expr4-end: -1:27   // CHECK: "extractedExpr" [[@LINE-1]]:16 -> [[@LINE-1]]:27
+}
+
+// RUN: clang-refactor-test perform -action extract-expression -selected=expr1 -selected=expr2 -selected=expr3 -selected=expr4 -emit-associated %s -std=c++11 | FileCheck %s
+
+// RUN: clang-refactor-test list-actions -at=%s:6:13 -selected=%s:6:13-6:18 %s -std=c++11 | FileCheck --check-prefix=CHECK-ACTION %s
+// CHECK-ACTION: Extract Expression
+
+void dontExtractStatement(int x, int y) {
+  // stmt1-begin: +1:3
+  x = y;
+  // stmt1-end: -1:8
+  // stmt2-begin: +1:3
+  return;
+  // stmt2-end: +0:1
+}
+
+// RUN: not clang-refactor-test perform -action extract-expression -selected=stmt1 -selected=stmt2 %s -std=c++11 2>&1 | FileCheck --check-prefix=CHECK-FAIL %s
+// CHECK-FAIL: Failed to initiate the refactoring action!
+
+void dontExtractVoidCall() {
+  // void-call-begin: +1:3
+  dontExtractVoidCall();
+  // void-call-end: -1:24
+}
+
+// RUN: not clang-refactor-test perform -action extract-expression -selected=void-call %s -std=c++11 2>&1 | FileCheck --check-prefix=CHECK-FAIL %s
diff --git a/test/Refactor/Extract/extract-expression-into-var.m b/test/Refactor/Extract/extract-expression-into-var.m
new file mode 100644
index 0000000..ec94dab
--- /dev/null
+++ b/test/Refactor/Extract/extract-expression-into-var.m
@@ -0,0 +1,12 @@
+// RUN: clang-refactor-test perform -action extract-expression -selected=expr1 -selected=expr2 %s | FileCheck %s
+
+void extractExpressionIntoVar(int x, int y, int z) {
+  // expr1-begin: +1:9
+  (void)@selector(foo:bar:); // CHECK: "SEL extractedExpr = @selector(foo:bar:);\n" [[@LINE]]:3 -> [[@LINE]]:3
+  // expr1-end: -1:28        // CHECK: "extractedExpr" [[@LINE-1]]:9 -> [[@LINE-1]]:28
+  // expr2-begin: +1:4       // CHECK: "void (^extractedExpr)(void) = ^ {\n    // do nothing\n  };\n" [[@LINE+1]]:3 -> [[@LINE+1]]:3
+  (^ {
+    // do nothing
+  })();
+  // expr2-end: -1:4         // CHECK: "extractedExpr" [[@LINE-3]]:4 -> [[@LINE-1]]:4
+}
diff --git a/test/Refactor/Extract/extract-expression.cpp b/test/Refactor/Extract/extract-expression.cpp
new file mode 100644
index 0000000..56b26df
--- /dev/null
+++ b/test/Refactor/Extract/extract-expression.cpp
@@ -0,0 +1,60 @@
+
+struct Rectangle { int width, height; };
+
+int sumArea(Rectangle *rs, int count) {
+  int sum = 0;
+  for (int i = 0; i < count; ++i) {
+    Rectangle r = rs[i];
+    sum += r.width * r.height;
+  }
+  return sum;
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:8:12-8:30 %s | FileCheck --check-prefix=CHECK1 %s
+// CHECK1: "static int extracted(const Rectangle &r) {\nreturn r.width * r.height;\n}\n\n" 4:1 -> 4:1
+// CHECK1-NEXT: "extracted(r)" 8:12 -> 8:30
+;
+void extractFullExpressionIfPartiallySelected(const Rectangle &r) {
+  int area = r.width * r.height;
+}
+// CHECK2: "static int extracted(const Rectangle &r) {\nreturn r.width * r.height;\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK2-NEXT: "extracted(r)" [[@LINE-3]]:14 -> [[@LINE-3]]:32
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:18:20-18:25 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:18:15-18:32 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:18:14-18:30 %s | FileCheck --check-prefix=CHECK2 %s
+;
+int extractFullMultipleCandidates(const Rectangle &r1) {
+  int y = r1.width - r1.width * r1.height;
+}
+// CHECK3-1: "static int extracted(const Rectangle &r1) {\nreturn - r1.width * r1.height;\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK3-1-NEXT: "+ extracted(r1)" [[@LINE-3]]:20 -> [[@LINE-3]]:42
+// CHECK3-2: "static int extracted(const Rectangle &r1) {\nreturn r1.width - r1.width * r1.height;\n}\n\n" [[@LINE-5]]:1 -> [[@LINE-5]]:1
+// CHECK3-2-NEXT: "extracted(r1)" [[@LINE-5]]:11 -> [[@LINE-5]]:42
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:28:20-28:42 %s | FileCheck --check-prefix=CHECK3-1 %s
+// RUN: clang-refactor-test perform -action extract -candidate 0 -selected=%s:28:20-28:42 %s | FileCheck --check-prefix=CHECK3-1 %s
+// RUN: clang-refactor-test perform -action extract -candidate 1 -selected=%s:28:20-28:42 %s | FileCheck --check-prefix=CHECK3-2 %s
+
+// RUN: not clang-refactor-test perform -action extract -candidate 2 -selected=%s:28:20-28:42 %s 2>&1 | FileCheck --check-prefix=CHECK-CAND-FAIL %s
+// CHECK-CAND-FAIL: failed to select the refactoring candidate
+;
+int extractFullMultipleCandidatesCaptureJustExtractedVariables(
+    const Rectangle &r1, const Rectangle &r2) {
+  return r1.width - r2.width * r2.height;
+}
+// CHECK4: "static int extracted(const Rectangle &r2) {\nreturn - r2.width * r2.height;\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK4-NEXT: "+ extracted(r2)" [[@LINE-3]]:19 -> [[@LINE-3]]:41
+
+// RUN: clang-refactor-test perform -action extract -candidate 0 -selected=%s:44:19-44:41 %s | FileCheck --check-prefix=CHECK4 %s
+
+// Even when the expression result is unused statement, we still want to extract
+// it as an expression.
+;
+void extractStatementExpression(const Rectangle &r) {
+  r.width * r.height;
+}
+// CHECK5: "static int extracted(const Rectangle &r) {\nreturn r.width * r.height;\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK5-NEXT: "extracted(r)" [[@LINE-3]]:3 -> [[@LINE-3]]:21
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:55:3-55:21 %s | FileCheck --check-prefix=CHECK5 %s
diff --git a/test/Refactor/Extract/extract-from-class.cpp b/test/Refactor/Extract/extract-from-class.cpp
new file mode 100644
index 0000000..29d9a00
--- /dev/null
+++ b/test/Refactor/Extract/extract-from-class.cpp
@@ -0,0 +1,45 @@
+
+#ifdef MULTIPLE
+class OuterClass {
+#endif
+
+class AClass {
+
+  int method(int x) {
+    return x + x * 2;
+  }
+// CHECK1: "static int extracted(int x) {\nreturn x + x * 2;\n}\n\n" [[@LINE-5]]:1
+// CHECK2: "static int extracted(int x) {\nreturn x + x * 2;\n}\n\n" [[@LINE-9]]:1
+;
+  AClass(int x) {
+    int y = x * 1;
+  }
+// CHECK1: "static int extracted(int x) {\nreturn x * 1;\n}\n\n" [[@LINE-11]]:1
+// CHECK2: "static int extracted(int x) {\nreturn x * 1;\n}\n\n" [[@LINE-15]]:1
+  ~AClass() {
+    int x = 0 + 4;
+  }
+// CHECK1: "static int extracted() {\nreturn 0 + 4;\n}\n\n" [[@LINE-16]]:1
+// CHECK2: "static int extracted() {\nreturn 0 + 4;\n}\n\n" [[@LINE-20]]:1
+;
+  int operator +(int x) {
+    return x + x * 3;
+  }
+// CHECK1: "static int extracted(int x) {\nreturn x + x * 3;\n}\n\n" [[@LINE-22]]:1
+// CHECK2: "static int extracted(int x) {\nreturn x + x * 3;\n}\n\n" [[@LINE-26]]:1
+;
+  void otherMethod(int x);
+};
+
+#ifdef MULTIPLE
+}
+#endif
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:9:12-9:21 -selected=%s:15:13-15:18 -selected=%s:20:13-20:18 -selected=%s:26:12-26:21 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:9:12-9:21 -selected=%s:15:13-15:18 -selected=%s:20:13-20:18 -selected=%s:26:12-26:21 %s -DMULTIPLE | FileCheck --check-prefix=CHECK2 %s
+;
+void AClass::otherMethod(int x) {
+  int y = x * x + 10;
+}
+// CHECK3: "static int extracted(int x) {\nreturn x * x + 10;\n}\n\n" [[@LINE-3]]:1
+// RUN: clang-refactor-test perform -action extract -selected=%s:42:11-42:21 %s | FileCheck --check-prefix=CHECK3 %s
diff --git a/test/Refactor/Extract/extract-header-inline.h b/test/Refactor/Extract/extract-header-inline.h
new file mode 100644
index 0000000..a323a11
--- /dev/null
+++ b/test/Refactor/Extract/extract-header-inline.h
@@ -0,0 +1,7 @@
+// RUN: clang-refactor-test perform -action extract -selected=extract %s | FileCheck %s
+;
+void extractInline(int x) { // CHECK: "inline int extracted(int x) {\nreturn x + 1;\n}\n\n" [[@LINE]]:1
+// extract-begin: +1:11
+  int y = x + 1;
+// extract-end: -1:16
+}
diff --git a/test/Refactor/Extract/extract-initiate.cpp b/test/Refactor/Extract/extract-initiate.cpp
new file mode 100644
index 0000000..3ddbc9f
--- /dev/null
+++ b/test/Refactor/Extract/extract-initiate.cpp
@@ -0,0 +1,150 @@
+struct Rectangle { int width, height; };
+
+int sumArea(Rectangle *rs, int count) {
+  int sum = 0;
+  for (int i = 0; i < count; ++i) {
+    Rectangle r = rs[i];
+    sum += r.width * r.height;
+  }
+  return sum;
+}
+
+// RUN: clang-refactor-test list-actions -at=%s:7:30 -selected=%s:7:12-7:30 %s | FileCheck --check-prefix=CHECK-ACTION %s
+// CHECK-ACTION: Extract Function
+
+// Ensure the an entire expression can be extracted:
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:7:12-7:30 %s | FileCheck --check-prefix=CHECK1 %s
+// CHECK1: Initiated the 'extract' action at 7:12 -> 7:30
+
+// Ensure that an expression can be extracted even when it's not fully selected:
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:7:13-7:30 -selected=%s:7:18-7:30 -selected=%s:7:20-7:30 -selected=%s:7:19-7:30 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action extract -selected=%s:7:12-7:29 -selected=%s:7:12-7:23 -selected=%s:7:12-7:21 -selected=%s:7:12-7:22 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action extract -selected=%s:7:19-7:22 -selected=%s:7:20-7:21 -selected=%s:7:15-7:25 %s | FileCheck --check-prefix=CHECK1 %s
+
+// Ensure that the action isn't allowed be when no expression is selected:
+
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:1:1-1:5 -selected=%s:2:1-2:1 -selected=%s:3:1-3:38 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// RUN: not clang-refactor-test initiate -action extract -at=%s:1:1 -in=%s:3:1-38  %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// CHECK-NO: Failed to initiate the refactoring action
+// CHECK-NO-NOT: Initiated the 'extract' action
+
+int multipleCandidates(Rectangle &r1, Rectangle &r2) {
+  int x = r1.width + r1.height; // CHECK2-SINGLE: Initiated the 'extract' action at [[@LINE]]:11 -> [[@LINE]]:31
+  int y = r1.width - r2.width * r2.height;
+}
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:34:20-34:31 -selected=%s:34:19-34:23 %s | FileCheck --check-prefix=CHECK2 %s
+// CHECK2: Initiated the 'extract' action with multiple candidates:
+// CHECK2-NEXT: + r1.height
+// CHECK2-NEXT: r1.width + r1.height
+// RUN: clang-refactor-test initiate -action extract -selected=%s:34:20-34:21 %s | FileCheck --check-prefix=CHECK2-SINGLE %s
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:35:19-35:42 %s | FileCheck --check-prefix=CHECK3 %s
+// CHECK3: Initiated the 'extract' action with multiple candidates:
+// CHECK3-NEXT: - r2.width * r2.height
+// CHECK3-NEXT: r1.width - r2.width * r2.height
+
+void trimWhitespaceAndSemiColons(const Rectangle &r) {
+  int x =  r.width   +   r.width * r.height; ;
+  //CHECK4: Initiated the 'extract' action at [[@LINE-1]]:26 -> [[@LINE-1]]:44
+  //CHECK5: Initiated the 'extract' action at [[@LINE-2]]:12 -> [[@LINE-2]]:44
+}
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:50:23-50:46 -selected=%s:50:23-50:45 %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test initiate -action extract -selected=%s:50:10-51:3 %s | FileCheck --check-prefix=CHECK5 %s
+
+void disallowBlankStatements() {
+  // comment
+  ;
+
+}
+
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:59:1-59:3 -selected=%s:60:1-62:1 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void allowCommentSelection(int y) {
+  char c = "//fake comment" [y] ;
+}
+
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:67:13-67:16 %s 2>&1 | FileCheck --check-prefix=CHECK-SIMPLE %s
+// CHECK-SIMPLE: Failed to initiate the refactoring action (the selected expression is too simple)
+
+void extractStatements(const Rectangle &r) {
+  (void)r;
+  int area = r.width * r.height;
+  int perimeter = r.width + r.height;
+  int sum = area + perimeter;
+  // CHECK6: Initiated the 'extract' action at [[@LINE-3]]:3 -> [[@LINE-2]]:38
+  // CHECK7: Initiated the 'extract' action at [[@LINE-5]]:3 -> [[@LINE-2]]:30
+}
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:75:1-76:38 -selected=%s:74:11-77:3 -selected=%s:75:14-76:26 %s | FileCheck --check-prefix=CHECK6 %s
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:74:1-77:30 -selected=%s:73:45-78:1 %s | FileCheck --check-prefix=CHECK7 %s
+
+void extractStatementsCompoundChild(const Rectangle &r) {
+  int x = 0;
+  {
+    int area = r.width * r.height;
+  }
+  int y = 0;
+  int z = 1;
+  // CHECK8: Initiated the 'extract' action at [[@LINE-5]]:3 -> [[@LINE-2]]:13
+}
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:89:5-91:12 %s | FileCheck --check-prefix=CHECK8 %s
+
+void extractStatementsTrimComments(const Rectangle &r) {
+  int x = 0;
+
+  // comment
+  int area = r.width * r.height;
+
+  // another comment
+  int y = 0;
+
+  // trailing comment
+}
+// CHECK9: Initiated the 'extract' action at [[@LINE-7]]:3 -> [[@LINE-7]]:33
+// CHECK10: Initiated the 'extract' action at [[@LINE-5]]:3 -> [[@LINE-5]]:13
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:100:1-102:32 -selected=%s:101:6-104:21 -selected=%s:100:1-105:3  %s | FileCheck --check-prefix=CHECK9 %s
+// RUN: clang-refactor-test initiate -action extract -selected=%s:103:1-105:12 -selected=%s:104:6-107:22 -selected=%s:103:1-108:1  %s | FileCheck --check-prefix=CHECK10 %s
+
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:101:1-101:13 -selected=%s:106:1-107:22 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void disallowEmptyCompoundStatement() {
+  // comment
+}
+
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:118:1-118:13 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void trimLeadingCompoundStatementComment() {
+  // comment
+
+  int x = 0;
+}
+
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:124:1-124:13 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void extractEntireCompoundStatement() {
+  {
+    int x = 0;
+    int y = 0;
+  }
+  // CHECK11: Initiated the 'extract' action at [[@LINE-4]]:3 -> [[@LINE-1]]:4
+  // CHECK12: Initiated the 'extract' action at [[@LINE-4]]:5 -> [[@LINE-3]]:15
+  // CHECK13: Initiated the 'extract' action at [[@LINE-5]]:5 -> [[@LINE-4]]:15
+}
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:132:3-135:4  %s | FileCheck --check-prefix=CHECK11 %s
+// RUN: clang-refactor-test initiate -action extract -selected=%s:132:3-135:3  %s | FileCheck --check-prefix=CHECK12 %s
+// RUN: clang-refactor-test initiate -action extract -selected=%s:132:4-135:4  %s | FileCheck --check-prefix=CHECK13 %s
+
+void disallowExtractionWhenSelectionRangeIsOutsideFunction() {
+  int x = 0;
+  int x = 1;
+}
+
+// RUN: not clang-refactor-test initiate -action extract -selected=%s:143:1-147:12 -selected=%s:146:3-150:3 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
diff --git a/test/Refactor/Extract/extract-initiate.m b/test/Refactor/Extract/extract-initiate.m
new file mode 100644
index 0000000..4af03c6
--- /dev/null
+++ b/test/Refactor/Extract/extract-initiate.m
@@ -0,0 +1,14 @@
+
+@interface I
+@end
+
+@implementation I
+
+- (int)computeAreaSquaredGivenWidth:(int)width height:(int)height {
+  int area = width * height;
+  return area * area;
+}
+//CHECK1: Initiated the 'extract' action at [[@LINE-3]]:14 -> [[@LINE-3]]:28
+// RUN: clang-refactor-test initiate -action extract -selected=%s:8:14-8:28 %s | FileCheck --check-prefix=CHECK1 %s
+
+@end
diff --git a/test/Refactor/Extract/extract-macros.cpp b/test/Refactor/Extract/extract-macros.cpp
new file mode 100644
index 0000000..ecac1ce
--- /dev/null
+++ b/test/Refactor/Extract/extract-macros.cpp
@@ -0,0 +1,39 @@
+#define ONE 1
+
+void extractExprMacros(int x) {
+  bool b = x == ONE;
+// CHECK1: {\nreturn x == ONE;\n}
+  int y = ONE + x;
+// CHECK1: {\nreturn ONE + x;\n}
+  int z = ONE - ONE * ONE;
+// CHECK1: {\nreturn ONE - ONE * ONE;\n}
+// CHECK1: {\nreturn ONE * ONE;\n}
+// CHECK1: {\nreturn - ONE * ONE;\n}
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:4:12-4:20 -selected=%s:6:11-6:19 -selected=%s:8:12-8:26 -selected=%s:8:17-8:26 -selected=%s:8:15-8:26 %s | FileCheck --check-prefix=CHECK1 %s
+
+#define MACRO2(x, y) x, y
+
+int function(int x);
+
+// MACRO-ARG3: "static int extracted(int x, int &y, int z) {\nreturn y = MACRO2(x + 2, function(z));\n}\n\n" [[@LINE+4]]:1
+// MACRO-ARG2: "static int extracted(int z) {\nreturn function(z);\n}\n\n" [[@LINE+3]]:1
+// MACRO-ARG1: "static int extracted(int x) {\nreturn x + 2;\n}\n\n" [[@LINE+2]]:1
+;
+void extractFromMacroArgument(int x, int y, int z) {
+
+  // macro-arg-expr4-begin: +4:7
+  // macro-arg-expr3-begin: +3:14
+  // macro-arg-expr2-begin: +2:21
+  // macro-arg-expr1-begin: +1:14
+  y = MACRO2(x + 2, function(z)); // comment4
+  // macro-arg-expr1-end: -1:19 // MACRO-ARG1: "extracted(x)" [[@LINE-1]]:14 -> [[@LINE-1]]:19
+  // macro-arg-expr2-end: -2:32 // MACRO-ARG2: "extracted(z)" [[@LINE-2]]:21 -> [[@LINE-2]]:32
+  // macro-arg-expr3-end: -3:32 // MACRO-ARG3: "extracted(x, y, z)" [[@LINE-3]]:3 -> [[@LINE-3]]:33
+  // macro-arg-expr4-end: -4:19
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=macro-arg-expr1 %s | FileCheck --check-prefix=MACRO-ARG1 %s
+// RUN: clang-refactor-test perform -action extract -selected=macro-arg-expr2 %s | FileCheck --check-prefix=MACRO-ARG2 %s
+// RUN: clang-refactor-test perform -action extract -selected=macro-arg-expr3 %s | FileCheck --check-prefix=MACRO-ARG3 %s
+// RUN: clang-refactor-test perform -action extract -selected=macro-arg-expr4 %s | FileCheck --check-prefix=MACRO-ARG3 %s
diff --git a/test/Refactor/Extract/extract-method.cpp b/test/Refactor/Extract/extract-method.cpp
new file mode 100644
index 0000000..84beaa8
--- /dev/null
+++ b/test/Refactor/Extract/extract-method.cpp
@@ -0,0 +1,153 @@
+
+void function(int x) {
+  int y = x * x;
+}
+
+class InitiateMethodExtraction {
+public:
+
+  InitiateMethodExtraction() {
+    int x = constMethod(1);
+  }
+// CHECK1: "void extracted() {\nint x = constMethod(1);\n}\n\n" [[@LINE-3]]:3 -> [[@LINE-3]]:3
+// CHECK1-NEXT: "extracted();" [[@LINE-3]]:5 -> [[@LINE-3]]:28
+// CHECK2: "static void extracted(const InitiateMethodExtraction &object) {\nint x = object.constMethod(1);\n}\n\n"
+// CHECK2-NEXT: "extracted(*this);"
+;
+  ~InitiateMethodExtraction() {
+    int x = constMethod(2);
+  }
+// CHECK1: "void extracted() {\nint x = constMethod(2);\n}\n\n" [[@LINE-3]]:3 -> [[@LINE-3]]:3
+// CHECK1-NEXT: "extracted();" [[@LINE-3]]:5 -> [[@LINE-3]]:28
+// CHECK2: "static void extracted(const InitiateMethodExtraction &object) {\nint x = object.constMethod(2);\n}\n\n"
+// CHECK2-NEXT: "extracted(*this);"
+;
+  void method() {
+    int x = constMethod(3);
+  }
+// CHECK1: "void extracted() {\nint x = constMethod(3);\n}\n\n" [[@LINE-3]]:3 -> [[@LINE-3]]:3
+// CHECK1-NEXT: "extracted();" [[@LINE-3]]:5 -> [[@LINE-3]]:28
+// CHECK2: "static void extracted(const InitiateMethodExtraction &object) {\nint x = object.constMethod(3);\n}\n\n"
+// CHECK2-NEXT: "extracted(*this);"
+;
+  int constMethod(int x) const {
+    return x + x * 2;
+  }
+// CHECK1: "int extracted(int x) const {\nreturn x + x * 2;\n}\n\n" [[@LINE-3]]:3 -> [[@LINE-3]]:3
+// CHECK1-NEXT: "extracted(x);" [[@LINE-3]]:5 -> [[@LINE-3]]:22
+// CHECK2: "static int extracted(int x) {\nreturn x + x * 2;\n}\n\n"
+// CHECK2-NEXT: "extracted(x);"
+;
+  int operator << (int x) {
+    return constMethod(x);
+  }
+// CHECK1: "int extracted(int x) {\nreturn constMethod(x);\n}\n\n" [[@LINE-3]]:3 -> [[@LINE-3]]:3
+// CHECK1-NEXT: "extracted(x)" [[@LINE-3]]:12 -> [[@LINE-3]]:26
+// CHECK2: "static int extracted(const InitiateMethodExtraction &object, int x) {\nreturn object.constMethod(x);\n}\n\n"
+// CHECK2-NEXT: "extracted(*this, x)"
+;
+  static void staticMethod(int x) {
+    int y = x * x;
+  }
+// CHECK1: "static void extracted(int x) {\nint y = x * x;\n}\n\n" [[@LINE-3]]:3 -> [[@LINE-3]]:3
+// CHECK1-NEXT: "extracted(x);" [[@LINE-3]]:5 -> [[@LINE-3]]:19
+// CHECK2: "static void extracted(int x) {\nint y = x * x;\n}\n\n"
+// CHECK2-NEXT: "extracted(x);"
+;
+  void otherMethod();
+};
+
+void InitiateMethodExtraction::otherMethod() {
+  int x = constMethod(4);
+}
+// CHECK1: "void extracted();\n\n" [[@LINE-6]]:3 -> [[@LINE-6]]:3
+// CHECK1-NEXT: "void InitiateMethodExtraction::extracted() {\nint x = constMethod(4);\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK1-NEXT: "extracted();" [[@LINE-4]]:3 -> [[@LINE-4]]:26
+// CHECK2: "static void extracted(const InitiateMethodExtraction &object) {\nint x = object.constMethod(4);\n}\n\n"
+// CHECK2-NEXT: "extracted(*this);"
+
+// RUN: clang-refactor-test list-actions -at=%s:10:5 -selected=%s:10:5-10:27 %s | FileCheck --check-prefix=CHECK-METHOD %s
+
+// CHECK-METHOD:      Extract Function{{$}}
+// CHECK-METHOD-NEXT: Extract Method{{$}}
+
+// RUN: clang-refactor-test list-actions -at=%s:3:3 -selected=%s:3:3-3:16 %s | FileCheck --check-prefix=CHECK-FUNC %s
+
+// CHECK-FUNC:     Extract Function{{$}}
+// CHECK-FUNC-NOT: Extract Method
+
+// RUN: clang-refactor-test perform -action extract-method -selected=%s:10:5-10:27 -selected=%s:18:5-18:27 -selected=%s:26:5-26:27 -selected=%s:34:5-34:21 -selected=%s:42:12-42:26 -selected=%s:50:5-50:18 -selected=%s:61:3-61:25 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:10:5-10:27 -selected=%s:18:5-18:27 -selected=%s:26:5-26:27 -selected=%s:34:5-34:21 -selected=%s:42:12-42:26 -selected=%s:50:5-50:18 -selected=%s:61:3-61:25 %s | FileCheck --check-prefix=CHECK2 %s
+
+
+
+
+
+
+
+namespace ns {
+  struct Outer {
+    struct Inner {
+      Inner(int x);
+
+      // comment
+      void method2(int x) const; // this stays!
+      int field;
+    };
+  };
+}
+ns::Outer::Inner::Inner(int x) {
+  int y = x + x;
+}
+// CHECK3: "void extracted(int x);\n\n" [[@LINE-11]]:7 -> [[@LINE-11]]:7
+// CHECK3: "void ns::Outer::Inner::extracted(int x) {\nint y = x + x;\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK3: "extracted(x);" [[@LINE-4]]:3 -> [[@LINE-4]]:17
+
+namespace ns {
+
+  // comment
+  void Outer::Inner::method2(int x) const {
+    if (x != 0)
+      int z = x * x;
+    else {
+      (void)x;
+    }
+  }
+// CHECK3: "void extracted(int x) const;\n\n" [[@LINE-23]]:7 -> [[@LINE-23]]:7
+// CHECK3: "void Outer::Inner::extracted(int x) const {\nif (x != 0)\n      int z = x * x;\n    else {\n      (void)x;\n    }\n}\n\n" [[@LINE-9]]:3 -> [[@LINE-9]]:3
+// CHECK3: "extracted(x);" [[@LINE-8]]:5 -> [[@LINE-4]]:6
+;
+  void Outer::Inner::methodNotDeclared(int x) {
+    int z = x * x;
+  }
+}
+// CHECK3: "\n\nvoid extracted(int x);\n" [[@LINE-30]]:48 -> [[@LINE-30]]:48
+// CHECK3: "void Outer::Inner::extracted(int x) {\nint z = x * x;\n}\n\n" [[@LINE-5]]:3 -> [[@LINE-5]]:3
+// CHECK3: "extracted(x);" [[@LINE-5]]:5 -> [[@LINE-5]]:19
+
+struct Empty {
+  int field;
+};
+
+void Empty::method() {
+  field = 22;
+}
+// CHECK3: "void extracted();\n\n" [[@LINE-5]]:1 -> [[@LINE-5]]:1
+// CHECK3: "void Empty::extracted() {\nfield = 22;\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK3: "extracted()" [[@LINE-4]]:3 -> [[@LINE-4]]:13
+
+// RUN: clang-refactor-test perform -action extract-method -selected=%s:100:3-100:16 -selected=%s:110:5-114:4 -selected=%s:121:5-121:18 -selected=%s:133:3-133:13 %s | FileCheck --check-prefix=CHECK3 %s
+
+template<typename T1, typename T2, int X>
+struct TemplateExtraction {
+  void method(); // CHECK4: "void extracted();\n\n" [[@LINE]]:3 -> [[@LINE]]:3
+};
+
+template<typename T1, typename T2, int x> // CHECK4: "template <typename T1, typename T2, int x> \nvoid TemplateExtraction<T1, T2, x>::extracted() {\nint y = x;\n}\n\n" [[@LINE]]:1 -> [[@LINE]]:1
+void TemplateExtraction<T1, T2, x>::method() {
+// template-method-begin: +1:1
+  int y = x;
+// template-method-end: +0:1
+}
+
+// RUN: clang-refactor-test perform -action extract-method -selected=template-method %s | FileCheck --check-prefix=CHECK4 %s
diff --git a/test/Refactor/Extract/extract-method.m b/test/Refactor/Extract/extract-method.m
new file mode 100644
index 0000000..6c136b0
--- /dev/null
+++ b/test/Refactor/Extract/extract-method.m
@@ -0,0 +1,57 @@
+
+void function(int x) {
+  int y = x * x;
+}
+
+@interface MethodExtraction
+
+- (int)method;
+- (void)classMethod;
+
+@end
+
+@implementation MethodExtraction
+
+- (void)aMethod:(int)x withY:(int)y {
+  int a = x + y;
+}
+// CHECK1: "- (void)extracted:(int)x y:(int)y {\nint a = x + y;\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK1-NEXT: "[self extracted:x y:y];" [[@LINE-3]]:3 -> [[@LINE-3]]:17
+// CHECK2: "static void extracted(int x, int y) {\nint a = x + y;\n}\n\n"
+// CHECK2-NEXT: "extracted(x, y);"
+;
++ (void)classMethod {
+  int x = 1;
+  int y = function(x);
+}
+// CHECK1: "+ (void)extracted {\nint x = 1;\n  int y = function(x);\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+// CHECK1-NEXT: "[self extracted];" [[@LINE-4]]:3 -> [[@LINE-3]]:23
+// CHECK2: "static void extracted() {\nint x = 1;\n  int y = function(x);\n}\n\n"
+// CHECK2-NEXT: "extracted();"
+
+@end
+
+@implementation MethodExtraction (Category)
+
+- (void)catMethod {
+  int x = [self method];
+}
+
++ (void)catClassMethod {
+  int x = function(42);
+}
+
+@end
+
+// RUN: clang-refactor-test list-actions -at=%s:16:3 -selected=%s:16:3-16:16 %s | FileCheck --check-prefix=CHECK-METHOD %s
+
+// CHECK-METHOD:      Extract Function{{$}}
+// CHECK-METHOD-NEXT: Extract Method{{$}}
+
+// RUN: clang-refactor-test list-actions -at=%s:3:3 -selected=%s:3:3-3:16 %s | FileCheck --check-prefix=CHECK-FUNC %s
+
+// CHECK-FUNC:     Extract Function{{$}}
+// CHECK-FUNC-NOT: Extract Method
+
+// RUN: clang-refactor-test perform -action extract-method -selected=%s:16:3-16:16 -selected=%s:24:3-25:22 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:16:3-16:16 -selected=%s:24:3-25:22 %s | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Extract/extract-mutation-of-captured-variable.cpp b/test/Refactor/Extract/extract-mutation-of-captured-variable.cpp
new file mode 100644
index 0000000..1b9e2ee
--- /dev/null
+++ b/test/Refactor/Extract/extract-mutation-of-captured-variable.cpp
@@ -0,0 +1,130 @@
+
+typedef struct {
+  int width, height;
+} Rectangle;
+
+#ifdef ADD
+#define MUT(x, y) x += y
+#endif
+
+#ifdef MUL
+#define MUT(x, y) x *= y
+#endif
+
+#ifdef BIT
+#define MUT(x, y) x |= y
+#endif
+
+#ifdef SHIFT
+#define MUT(x, y) x >>= y
+#endif
+
+#ifdef INC1
+#define MUT(x, y) ++x
+#endif
+
+#ifdef INC2
+#define MUT(x, y) x++
+#endif
+
+#ifdef DEC1
+#define MUT(x, y) --x
+#endif
+
+#ifdef DEC2
+#define MUT(x, y) x--
+#endif
+
+#ifndef MUT
+#define MUT(x, y) x = y
+#endif
+
+#ifdef FIELD
+class MutatePrivateInstanceVariables {
+  int x;
+  int y;
+  Rectangle r;
+
+#endif
+
+void mutateVariableOrField
+#ifndef FIELD
+  (int x, int y, Rectangle r)
+#else
+  ()
+#endif
+{
+  (MUT(x, 1));
+// CHECK1: (int &x) {\nreturn (MUT(x, 1));\n}
+
+  (MUT((x), 1));
+// CHECK1: (int &x) {\nreturn (MUT((x), 1));\n}
+
+  (MUT(r.width, 1));
+// CHECK1: (Rectangle &r) {\nreturn (MUT(r.width, 1));\n}
+
+  (MUT((x, r.height), 1));
+// CHECK1: (Rectangle &r, int x) {\nreturn (MUT((x, r.height), 1));\n}
+
+  (MUT((x == 0 ? x : y), 1));
+// CHECK1: (int &x, int &y) {\nreturn (MUT((x == 0 ? x : y), 1));\n}
+
+  Rectangle a, b;
+  (x == 0 ? (r) : b) = a;
+// CHECK2: (const Rectangle &a, Rectangle &b, Rectangle &r, int x) {\nreturn (x == 0 ? (r) : b) = a;\n}
+
+}
+
+#ifdef FIELD
+};
+#endif
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s -DFIELD | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:73:3-73:25 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:73:3-73:25 %s -DFIELD | FileCheck --check-prefix=CHECK2 %s
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s -DADD | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s -DMUL -DFIELD | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s -DBIT | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s -DSHIFT -DFIELD | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s -DINC1 | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s -DINC2 -DFIELD | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s -DDEC1 | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:57:3-57:14 -selected=%s:60:3-60:16 -selected=%s:63:3-63:20 -selected=%s:66:3-66:26 -selected=%s:69:3-69:29 %s -DDEC2 -DFIELD | FileCheck --check-prefix=CHECK1 %s
+
+void dontMutateVariable(int *array, int x) {
+  array[x] = 0;
+// CHECK3: (int *array, int x) {\narray[x] = 0;\n}
+  *array = 0;
+// CHECK3: (int *array) {\n*array = 0;\n}
+  array = 0;
+// CHECK3: extracted(int *&array) {\narray = 0;\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:101:3-101:15 -selected=%s:103:3-103:13 -selected=%s:105:3-105:12 %s | FileCheck --check-prefix=CHECK3 %s
+
+#ifdef __cplusplus
+
+int &returnsRef(int x) {
+  static int result = 0;
+  return result;
+}
+
+void dontMutateCallArguments(int x) {
+  returnsRef(x) = 0;
+// CHECK4: extracted(int x) {\nreturnsRef(x) = 0;\n}
+}
+
+void mutateRefVar(int &x) {
+  x = 0;
+// CHECK4: extracted(int &x) {\nx = 0;\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:119:3-119:20 -selected=%s:124:3-124:8 %s | FileCheck --check-prefix=CHECK4 %s
+
+#endif
diff --git a/test/Refactor/Extract/extract-objc-property.m b/test/Refactor/Extract/extract-objc-property.m
new file mode 100644
index 0000000..7fc7919
--- /dev/null
+++ b/test/Refactor/Extract/extract-objc-property.m
@@ -0,0 +1,60 @@
+@interface HasProperty
+
+@property (strong) HasProperty *item;
+
+- (HasProperty *)implicitProp;
+
+- (void)setImplicitSetter:(HasProperty *)value;
+
+@end
+
+@implementation HasProperty
+
+- (void)test {
+// property-name-begin: +2:8
+// property-begin: +1:3
+  self.item;
+// property-end: -1:12
+// property-name-end: -2:12
+// CHECK: "static HasProperty * extracted(HasProperty *object) {\nreturn object.item;\n}\n\n"
+
+// implicit-name-begin: +2:8
+// implicit-begin: +1:3
+  self.implicitProp;
+// implicit-end: -1:20
+// implicit-name-end: -2:20
+// CHECK: "static HasProperty * extracted(HasProperty *object) {\nreturn object.implicitProp;\n}\n\n"
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=property -selected=implicit %s -fobjc-arc | FileCheck %s
+// RUN: clang-refactor-test perform -action extract -selected=property-name -selected=implicit-name %s -fobjc-arc | FileCheck %s
+
+- (void)prohibitSetterExtraction {
+// setter-pref-begin: +2:8
+// setter-begin: +1:3
+  self.item = 0;
+// setter-end: -1:12
+// setter-pref-end: -2:12
+// implicit-setter-pref-begin: +2:8
+// implicit-setter-begin: +1:3
+  self.implicitSetter = 0;
+// implicit-setter-end: -1:22
+// implicit-setter-pref-end: -2:22
+}
+// CHECK-SETTER: Failed to initiate the refactoring action (property setter can't be extracted)!
+// RUN: not clang-refactor-test initiate -action extract -selected=setter -selected=setter-pref -selected=implicit-setter -selected=implicit-setter-pref %s -fobjc-arc 2>&1 | FileCheck --check-prefix=CHECK-SETTER %s
+
+@end
+
+@interface HasIntProp
+@property (readwrite) int item;
+@end
+
+// AVOID-CRASH: "static void extracted(HasIntProp *f) {\nf.item = !f.item;\n}\n\n"
+// avoid-extraction-crash-begin: +1:42
+void avoidExtractionCrash(HasIntProp *f) {
+  f.item = !f.item;
+// avoid-extraction-crash-end: -1:5
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=avoid-extraction-crash %s -fobjc-arc | FileCheck --check-prefix=AVOID-CRASH %s
diff --git a/test/Refactor/Extract/extract-reference-of-captured-variable.cpp b/test/Refactor/Extract/extract-reference-of-captured-variable.cpp
new file mode 100644
index 0000000..1c71169
--- /dev/null
+++ b/test/Refactor/Extract/extract-reference-of-captured-variable.cpp
@@ -0,0 +1,287 @@
+
+void takesPtr(int *x) { }
+
+typedef struct {
+  int width, height;
+} Rectangle;
+
+void takesStructPtr(Rectangle *sp) { }
+
+void variableTakesRef(int x, Rectangle r) {
+  int &y = x;
+  takesPtr(&y);
+// CHECK1: (int &x) {\nint &y = x;\n  takesPtr(&y);\n}
+  Rectangle p = r;
+  Rectangle &rp = p;
+  takesStructPtr(&rp);
+// CHECK1: (const Rectangle &r) {\nRectangle p = r;\n  Rectangle &rp = p;\n  takesStructPtr(&rp);\n}
+// CHECK1: (Rectangle &p) {\nRectangle &rp = p;\n  takesStructPtr(&rp);\n}
+  int &member = ((r).width);
+  int z = member;
+// CHECK1: (Rectangle &r) {\nint &member = ((r).width);\n  int z = member;\n}
+
+// Even though y takes a reference to x, we still want to pass it by value here.
+  int a = x;
+// CHECK1: (int x) {\nint a = x;\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:11:3-12:15 -selected=%s:14:3-16:22 -selected=%s:15:3-16:22 -selected=%s:19:3-20:17 -selected=%s:24:3-24:12 %s | FileCheck --check-prefix=CHECK1 %s
+
+class PrivateInstanceVariables {
+  int x;
+  Rectangle r;
+
+  void method() {
+    int &y = x;
+// CHECK2: extracted(int &x) {\nint &y = x;\n}
+    Rectangle &rr = r;
+// CHECK2: extracted(Rectangle &r) {\nRectangle &rr = r;\n}
+    int &z = ((r).width);
+// CHECK2: extracted(Rectangle &r) {\nint &z = ((r).width);\n}
+  }
+};
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:35:5-35:15 -selected=%s:37:5-37:22 -selected=%s:39:5-39:25 %s | FileCheck --check-prefix=CHECK2 %s
+
+#ifdef USECONST
+#define CONST const
+#else
+#define CONST
+#endif
+
+void takesRef(CONST int &x) { }
+
+void takesStructRef(CONST Rectangle &r) { }
+
+void takesValue(int x) { }
+
+struct ConsTakesRef {
+  ConsTakesRef(CONST int &x) { }
+
+  void takesRef(CONST int &x) const { }
+  void takesValue(int x) const { }
+};
+
+int operator << (CONST Rectangle &r, CONST int &x) { return 0; }
+
+void callTakesRef(int x, Rectangle r) {
+  takesRef(x);
+// CHECK3: extracted(int &x) {\ntakesRef(x);\n}
+// CHECK4: extracted(int x) {\ntakesRef(x);\n}
+  takesValue(x);
+// CHECK3: extracted(int x) {\ntakesValue(x);\n}
+// CHECK4: extracted(int x) {\ntakesValue(x);\n}
+  auto k = ConsTakesRef(x); auto y = ConsTakesRef(x);
+// CHECK3: extracted(int &x) {\nauto k = ConsTakesRef(x);\n}
+// CHECK4: extracted(int x) {\nauto k = ConsTakesRef(x);\n}
+  y.takesRef((x));
+// CHECK3: extracted(int &x, const ConsTakesRef &y) {\ny.takesRef((x));\n}
+// CHECK4: extracted(int x, const ConsTakesRef &y) {\ny.takesRef((x));\n}
+  y.takesValue(x);
+// CHECK3: extracted(int x, const ConsTakesRef &y) {\ny.takesValue(x);\n}
+// CHECK4: extracted(int x, const ConsTakesRef &y) {\ny.takesValue(x);\n}
+  takesStructRef((r));
+// CHECK3: extracted(Rectangle &r) {\ntakesStructRef((r));\n}
+// CHECK4: extracted(const Rectangle &r) {\ntakesStructRef((r));\n}
+  takesRef((r).height);
+// CHECK3: extracted(Rectangle &r) {\ntakesRef((r).height);\n}
+// CHECK4: extracted(const Rectangle &r) {\ntakesRef((r).height);\n}
+  y.takesRef(r.width);
+// CHECK3: extracted(Rectangle &r, const ConsTakesRef &y) {\ny.takesRef(r.width);\n}
+// CHECK4: extracted(const Rectangle &r, const ConsTakesRef &y) {\ny.takesRef(r.width);\n}
+  takesValue(r.width);
+// CHECK3: extracted(const Rectangle &r) {\ntakesValue(r.width);\n}
+// CHECK4: extracted(const Rectangle &r) {\ntakesValue(r.width);\n}
+  r << x;
+// CHECK3: extracted(Rectangle &r, int &x) {\nreturn r << x;\n}
+// CHECK4: extracted(const Rectangle &r, int x) {\nreturn r << x;\n}
+
+  int &r1 = x;
+  takesRef(x);
+// CHECK3: extracted(int &x) {\nint &r1 = x;\n  takesRef(x);\n}
+// CHECK4: extracted(int &x) {\nint &r1 = x;\n  takesRef(x);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:68:3-68:14 -selected=%s:71:3-71:16 -selected=%s:74:3-74:27 -selected=%s:77:3-77:18 -selected=%s:80:3-80:18 -selected=%s:83:3-83:22 -selected=%s:86:3-86:23 -selected=%s:89:3-89:22 -selected=%s:92:3-92:22 -selected=%s:95:3-95:9 -selected=%s:99:3-100:14 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:68:3-68:14 -selected=%s:71:3-71:16 -selected=%s:74:3-74:27 -selected=%s:77:3-77:18 -selected=%s:80:3-80:18 -selected=%s:83:3-83:22 -selected=%s:86:3-86:23 -selected=%s:89:3-89:22 -selected=%s:92:3-92:22 -selected=%s:95:3-95:9 -selected=%s:99:3-100:14 %s -DUSECONST | FileCheck --check-prefix=CHECK4 %s
+
+void takesConstRef(const int &x) { }
+
+void callTakeRefAndConstRef(int x) {
+  takesRef(x);
+  takesConstRef(x);
+// CHECK5: extracted(int &x) {\ntakesRef(x);\n  takesConstRef(x);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:111:3-112:19 %s | FileCheck --check-prefix=CHECK5 %s
+
+class PrivateInstanceVariablesCallRefs {
+  int x;
+  Rectangle r;
+
+  void callsTakeRef() {
+    takesRef(x);
+// CHECK6: extracted(int &x) {\ntakesRef(x);\n}
+// CHECK7: extracted(int x) {\ntakesRef(x);\n}
+    takesStructRef(r);
+// CHECK6: extracted(Rectangle &r) {\ntakesStructRef(r);\n}
+// CHECK7: extracted(const Rectangle &r) {\ntakesStructRef(r);\n}
+    takesRef(r.width);
+// CHECK6: extracted(Rectangle &r) {\ntakesRef(r.width);\n}
+// CHECK7: extracted(const Rectangle &r) {\ntakesRef(r.width);\n}
+  }
+};
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:123:5-123:16 -selected=%s:126:5-126:22 -selected=%s:129:5-129:22 %s | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:123:5-123:16 -selected=%s:126:5-126:22 -selected=%s:129:5-129:22 %s -DUSECONST | FileCheck --check-prefix=CHECK7 %s
+
+void variableTakesConstRef(int x, Rectangle r) {
+  const int &y = x;
+// CHECK8: extracted(int x) {\nconst int &y = x;\n}
+  const Rectangle &p = r;
+// CHECK8: extracted(const Rectangle &r) {\nconst Rectangle &p = r;\n}
+  const int &z = r.width;
+// CHECK8: extracted(const Rectangle &r) {\nconst int &z = r.width;\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:139:3-139:19 -selected=%s:141:3-141:25 -selected=%s:143:3-143:25 %s | FileCheck --check-prefix=CHECK8 %s
+
+class ClassWithMethod {
+public:
+  int method() CONST { return 0; }
+  int operator + (int x) CONST { return x; }
+};
+
+void nonConstMethodCallImpliesNonConstReceiver(ClassWithMethod x) {
+  x.method();
+// CHECK10: extracted(ClassWithMethod &x) {\nreturn x.method();\n}
+// CHECK11: extracted(const ClassWithMethod &x) {\nreturn x.method();\n}
+  x.operator +(2);
+// CHECK10: extracted(ClassWithMethod &x) {\nreturn x.operator +(2);\n}
+// CHECK11: extracted(const ClassWithMethod &x) {\nreturn x.operator +(2);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:156:3-156:14 -selected=%s:159:3-159:18 %s | FileCheck --check-prefix=CHECK10 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:156:3-156:14 -selected=%s:159:3-159:18 %s -DUSECONST | FileCheck --check-prefix=CHECK11 %s
+
+void ignoreMethodCallsOnPointer(ClassWithMethod *x) {
+  x->method();
+// CHECK12: extracted(ClassWithMethod *x) {\nreturn x->method();\n}
+  x->operator +(2);
+// CHECK12: extracted(ClassWithMethod *x) {\nreturn x->operator +(2);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:168:3-168:13 -selected=%s:170:3-170:19 %s | FileCheck --check-prefix=CHECK12 %s
+
+void takesRValueRef(int &&x) { }
+void takesRValueStructRef(Rectangle &&r) { }
+
+void callTakesRValueRef(int x) {
+  takesRValueRef(static_cast<int&&>(x));
+// CHECK13: extracted(int &x) {\ntakesRValueRef(static_cast<int&&>(x));\n}
+  Rectangle r;
+  takesRValueStructRef((static_cast<Rectangle&&>(r)));
+// CHECK13: extracted(Rectangle &r) {\ntakesRValueStructRef((static_cast<Rectangle&&>(r)));\n}
+  int &&y = static_cast<int&&>(r.height);
+// CHECK13: extracted(Rectangle &r) {\nint &&y = static_cast<int&&>(r.height);\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:180:3-180:20 -selected=%s:183:3-183:54 -selected=%s:185:3-185:41 %s | FileCheck --check-prefix=CHECK13 %s
+
+void referencesInConditionalOperator(int x, int y) {
+  takesRef(x == 0 ? x : y);
+// CHECK14: (int &x, int &y) {\ntakesRef(x == 0 ? x : y);\n}
+// CHECK15: (int x, int y) {\ntakesRef(x == 0 ? x : y);\n}
+  Rectangle a, b;
+  takesStructRef(y == 0 ? (a) : b);
+// CHECK14: (Rectangle &a, Rectangle &b, int y) {\ntakesStructRef(y == 0 ? (a) : b);\n}
+// CHECK15: (const Rectangle &a, const Rectangle &b, int y) {\ntakesStructRef(y == 0 ? (a) : b);\n}
+  takesRef(x == 0 ? (a).width : (y == 0 ? y : b.height));
+// CHECK14: (Rectangle &a, Rectangle &b, int x, int &y) {\ntakesRef(x == 0 ? (a).width : (y == 0 ? y : b.height));\n}
+// CHECK15: (const Rectangle &a, const Rectangle &b, int x, int y) {\ntakesRef(x == 0 ? (a).width : (y == 0 ? y : b.height));\n}
+  takesRef((x == 0 ? a : (b)).width);
+// CHECK14: (Rectangle &a, Rectangle &b, int x) {\ntakesRef((x == 0 ? a : (b)).width);\n}
+// CHECK15: (const Rectangle &a, const Rectangle &b, int x) {\ntakesRef((x == 0 ? a : (b)).width);\n}
+  takesRef(x == 0 ? y : y);
+// CHECK14: (int x, int &y) {\ntakesRef(x == 0 ? y : y);\n}
+// CHECK15: (int x, int y) {\ntakesRef(x == 0 ? y : y);\n}
+  ClassWithMethod caller1, caller2;
+  (x == 0 ? caller1 : caller2).method();
+// CHECK14: (ClassWithMethod &caller1, ClassWithMethod &caller2, int x) {\nreturn (x == 0 ? caller1 : caller2).method();\n}
+// CHECK15: (const ClassWithMethod &caller1, const ClassWithMethod &caller2, int x) {\nreturn (x == 0 ? caller1 : caller2).method();\n}
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:192:3-192:27 -selected=%s:196:3-196:35 -selected=%s:199:3-199:57 -selected=%s:202:3-202:37 -selected=%s:205:3-205:27 -selected=%s:209:3-209:40 %s | FileCheck --check-prefix=CHECK14 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:192:3-192:27 -selected=%s:196:3-196:35 -selected=%s:199:3-199:57 -selected=%s:202:3-202:37 -selected=%s:205:3-205:27 -selected=%s:209:3-209:40 %s -DUSECONST | FileCheck --check-prefix=CHECK15 %s
+
+class PrivateInstanceVariablesConditionalOperatorRefs {
+  int x;
+  Rectangle r;
+
+  void callsTakeRef(int y) {
+    takesRef(y == 0 ? x : r.width);
+  }
+};
+// CHECK16: (Rectangle &r, int &x, int y) {\ntakesRef(y == 0 ? x : r.width);\n}
+// RUN: clang-refactor-test perform -action extract -selected=%s:222:5-222:35 %s | FileCheck --check-prefix=CHECK16 %s
+
+class ReferencesInCommaOperator {
+  int x;
+
+  void callsTakeRef(int y, Rectangle r) {
+    takesRef((x, y));
+// CHECK17: (int x, int &y) {\ntakesRef((x, y));\n}
+    takesRef((y, x));
+// CHECK17: (int &x, int y) {\ntakesRef((y, x));\n}
+    takesStructRef((takesValue(x), r));
+// CHECK17: (Rectangle &r, int x) {\ntakesStructRef((takesValue(x), r));\n}
+  }
+};
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:232:5-232:21 -selected=%s:234:5-234:21 -selected=%s:236:5-236:39 %s | FileCheck --check-prefix=CHECK17 %s
+
+struct StaticMember {
+  static int staticMember;
+};
+
+void memberMustBeNonStaticField(StaticMember s) {
+  takesRef(s.staticMember);
+// CHECK18: (const StaticMember &s) {\ntakesRef(s.staticMember);\n}
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:248:3-248:27 %s | FileCheck --check-prefix=CHECK18 %s
+
+class ClassWithMethod2 {
+public:
+  ClassWithMethod member;
+};
+
+class ClassWithMethod;
+
+void nonConstMethodCallImpliesNonConstReceiver2(ClassWithMethod2 x) {
+  x.member.method();
+// CHECK19: (ClassWithMethod2 &x) {\nreturn x.member.method();\n}
+// CHECK20: (const ClassWithMethod2 &x) {\nreturn x.member.method();\n}
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:261:3-261:20 %s | FileCheck --check-prefix=CHECK19 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:261:3-261:20 %s -DUSECONST | FileCheck --check-prefix=CHECK20 %s
+
+class PrivateInstaceVariablesCallRefsBase {
+  int x;
+};
+
+class PrivateInstanceVariablesCallRefs2: public PrivateInstaceVariablesCallRefsBase {
+  int y;
+  Rectangle r;
+
+  void callsTakeRef() {
+    takesRef(this->x);
+    takesRef((this)->y);
+    takesRef(static_cast<PrivateInstaceVariablesCallRefsBase *>(this)->x);
+    takesRef((0, ((const_cast<PrivateInstanceVariablesCallRefs2 *>(this)->r.width))));
+  }
+// CHECK21: (PrivateInstanceVariablesCallRefs2 &object) {\ntakesRef(object.x);\n}
+// CHECK21: (PrivateInstanceVariablesCallRefs2 &object) {\ntakesRef((object).y);\n}
+// CHECK21: (PrivateInstanceVariablesCallRefs2 &object) {\ntakesRef(static_cast<PrivateInstaceVariablesCallRefsBase *>(&object)->x);\n}
+// CHECK21: (PrivateInstanceVariablesCallRefs2 &object) {\ntakesRef((0, ((const_cast<PrivateInstanceVariablesCallRefs2 *>(&object)->r.width))));\n}
+};
+// RUN: clang-refactor-test perform -action extract -selected=%s:277:5-277:22 -selected=%s:278:5-278:24 -selected=%s:279:5-279:74 -selected=%s:280:5-280:86 %s | FileCheck --check-prefix=CHECK21 %s
diff --git a/test/Refactor/Extract/extract-reference-of-captured-variable.mm b/test/Refactor/Extract/extract-reference-of-captured-variable.mm
new file mode 100644
index 0000000..9d0f9c2
--- /dev/null
+++ b/test/Refactor/Extract/extract-reference-of-captured-variable.mm
@@ -0,0 +1,50 @@
+
+#ifdef USECONST
+#define CONST const
+#else
+#define CONST
+#endif
+
+typedef struct {
+  int width, height;
+} Rectangle;
+
+@interface I
+
+- (int)takesRef:(CONST int &)x;
++ (int)takesRef:(CONST int &)x;
+- (int)takesVal:(int)x;
+- (int)takesStructRef:(CONST Rectangle &)r;
+
+@end
+
+void methodTakesRef(I *i, int x, Rectangle r) {
+  [i takesRef: x];
+// CHECK1: extracted(I *i, int &x) {\nreturn [i takesRef: x];\n}
+// CHECK2: extracted(I *i, int x) {\nreturn [i takesRef: x];\n}
+  [I takesRef: x];
+// CHECK1: extracted(int &x) {\nreturn [I takesRef: x];\n}
+// CHECK2: extracted(int x) {\nreturn [I takesRef: x];\n}
+  [i takesVal: x];
+// CHECK1: extracted(I *i, int x) {\nreturn [i takesVal: x];\n}
+// CHECK2: extracted(I *i, int x) {\nreturn [i takesVal: x];\n}
+  [i takesStructRef: r];
+// CHECK1: extracted(I *i, Rectangle &r) {\nreturn [i takesStructRef: r];\n}
+// CHECK2: extracted(I *i, const Rectangle &r) {\nreturn [i takesStructRef: r];\n}
+  [I takesRef: (r).width];
+// CHECK1: extracted(Rectangle &r) {\nreturn [I takesRef: (r).width];\n}
+// CHECK2: extracted(const Rectangle &r) {\nreturn [I takesRef: (r).width];\n}
+}
+
+class PrivateInstanceVariablesMethodCallRefs {
+  int x;
+
+  void methodTakesRef(I *j) {
+    [j takesRef: x];
+// CHECK1: extracted(I *j, int &x) {\nreturn [j takesRef: x];\n}
+// CHECK2: extracted(I *j, int x) {\nreturn [j takesRef: x];\n}
+  }
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:22:3-22:18 -selected=%s:25:3-25:18 -selected=%s:28:3-28:18 -selected=%s:31:3-31:24 -selected=%s:34:3-34:26 -selected=%s:43:5-43:20 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:22:3-22:18 -selected=%s:25:3-25:18 -selected=%s:28:3-28:18 -selected=%s:31:3-31:24 -selected=%s:34:3-34:26 -selected=%s:43:5-43:20 %s -DUSECONST | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Extract/extract-statement-macros.cpp b/test/Refactor/Extract/extract-statement-macros.cpp
new file mode 100644
index 0000000..b412a34
--- /dev/null
+++ b/test/Refactor/Extract/extract-statement-macros.cpp
@@ -0,0 +1,47 @@
+#define INT int
+#define MACRO INT y = x * x
+
+void extractStatementsTrimComments(int x) {
+  INT y = 0;
+
+  // comment
+  MACRO;
+
+  int z = 0;
+}
+// CHECK1: Initiated the 'extract' action at [[@LINE-4]]:3 -> [[@LINE-2]]:13
+// CHECK2: Initiated the 'extract' action at [[@LINE-8]]:3 -> [[@LINE-5]]:9
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:6:1-10:12 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action extract -selected=%s:5:3-9:1 %s | FileCheck --check-prefix=CHECK2 %s
+
+#define BLOCK __attribute__((__blocks__(byref)))
+void macroAtDeclStmt() {
+  // attr-begin: +1:38
+  BLOCK const char *Message = "HELLO";
+  int X = 123;
+  // attr-end: -1:13
+}
+// CHECK3: Initiated the 'extract' action at [[@LINE-4]]:3 -> [[@LINE-3]]:15
+// RUN: clang-refactor-test initiate -action extract -selected=attr %s -fblocks | FileCheck --check-prefix=CHECK3 %s
+
+#define MUT(x) (--(x))
+
+void macroExtractionEndsInMacroArgument(int x, int y) { // CHECK4: "static void extracted(int &x, int &y) {\ny = MUT(x);\n}\n\n" [[@LINE]]:1
+// CHECK5: "static int extracted(int &x) {\nreturn MUT(x);\n}\n\n" [[@LINE-1]]:1
+
+  // macro-arg-expr-begin: +3:7
+  // macro-arg-end1-begin: +2:1
+  // macro-arg-end2-begin: +1:1
+  y = MUT(x); // comment
+  // macro-arg-end1-end: -1:25
+  // macro-arg-end2-end: -2:14
+  // macro-arg-expr-end: -3:13
+
+  // CHECK4: "extracted(x, y)" [[@LINE-5]]:3 -> [[@LINE-5]]:13
+  // CHECK5: "extracted(x)" [[@LINE-6]]:7 -> [[@LINE-6]]:13
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=macro-arg-end1 %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test perform -action extract -selected=macro-arg-end2  %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test perform -action extract -selected=macro-arg-expr %s | FileCheck --check-prefix=CHECK5 %s
diff --git a/test/Refactor/Extract/extract-statements.cpp b/test/Refactor/Extract/extract-statements.cpp
new file mode 100644
index 0000000..4861d11
--- /dev/null
+++ b/test/Refactor/Extract/extract-statements.cpp
@@ -0,0 +1,178 @@
+
+struct Rectangle { int width, height; };
+
+void extractStatement(const Rectangle &r) {
+  int area = r.width * r.height;
+// CHECK1: "static void extracted(const Rectangle &r) {\nint area = r.width * r.height;\n}\n\n"
+// CHECK1-NEXT: "extracted(r);" [[@LINE-2]]:3 -> [[@LINE-2]]:33
+  if (r.width) {
+    int x = r.height;
+  }
+// CHECK1: "static void extracted(const Rectangle &r) {\nif (r.width) {\n    int x = r.height;\n  }\n}\n\n"
+// CHECK1-NEXT: "extracted(r);" [[@LINE-4]]:3 -> [[@LINE-2]]:4
+  if (r.width) {
+    int x = r.height;
+  } ; // This semicolon shouldn't be extracted.
+// CHECK1: "static void extracted(const Rectangle &r) {\nif (r.width) {\n    int x = r.height;\n  }\n}\n\n"
+// CHECK1-NEXT: "extracted(r);" [[@LINE-4]]:3 -> [[@LINE-2]]:4
+  do {
+  } while (true) ;
+// CHECK1: "static void extracted() {\ndo {\n  } while (true) ;\n}\n\n"
+// CHECK1-NEXT: "extracted();" [[@LINE-3]]:3 -> [[@LINE-2]]:19
+  do {
+  } while (true) /*we still want to take this semicolon*/ ;
+// CHECK1: "static void extracted() {\ndo {\n  } while (true) /*we still want to take this semicolon*/ ;\n}\n\n"
+// CHECK1-NEXT: "extracted();" [[@LINE-3]]:3 -> [[@LINE-2]]:60
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:5:3-5:32 -selected=%s:8:3-10:4 -selected=%s:13:3-15:4 -selected=%s:18:3-19:17 -selected=%s:22:3-23:17 %s | FileCheck --check-prefix=CHECK1 %s
+;
+void extractCantFindSemicolon() {
+  do {
+  } while (true)
+  // Add a semicolon in both the extracted and original function as we don't
+  // want to extract the semicolon below:
+  ;
+// CHECK2: "static void extracted() {\ndo {\n  } while (true);\n}\n\n"
+// CHECK2-NEXT: "extracted();" [[@LINE-6]]:3 -> [[@LINE-5]]:17
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:31:3-32:17 %s | FileCheck --check-prefix=CHECK2 %s
+
+void extractedStmtNoNeedForSemicolon() {
+  {
+    int x = 0;
+  }
+// CHECK3: "static void extracted() {\n{\n    int x = 0;\n  }\n}\n\n"
+  switch (2) {
+  case 1:
+    break;
+  case 2:
+    break;
+  }
+// CHECK3: "static void extracted() {\nswitch (2) {\n  case 1:\n    break;\n  case 2:\n    break;\n  }\n}\n\n"
+  while (true) {
+    int x = 0;
+  }
+// CHECK3: "static void extracted() {\nwhile (true) {\n    int x = 0;\n  }\n}\n\n"
+  for (int i = 0; i < 10; ++i) {
+  }
+// CHECK3: "static void extracted() {\nfor (int i = 0; i < 10; ++i) {\n  }\n}\n\n"
+  struct XS {
+    int *begin() { return 0; }
+    int *end() { return 0; }
+  };
+  XS xs;
+  for (int i : xs) {
+  }
+// CHECK3: "static void extracted(const XS &xs) {\nfor (int i : xs) {\n  }\n}\n\n"
+  try { int x = 0; }
+  catch (const int &i) {
+    int y = i;
+  }
+// CHECK3: "static void extracted() {\ntry { int x = 0; }\n  catch (const int &i) {\n    int y = i;\n  }\n}\n\n"
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:42:3-44:4 -selected=%s:46:3-51:4 -selected=%s:53:3-55:4 -selected=%s:57:3-58:4 -selected=%s:65:3-66:4 -selected=%s:68:3-71:4 %s -std=c++11 | FileCheck --check-prefix=CHECK3 %s
+;
+void extractStatementRange(int x) {
+  x = 2;
+  int y = 0;
+  extractStatementRange(x);
+  if (x == 2) {
+    int z = 0;
+  }
+  x = 2;
+
+// CHECK4: "static void extracted(int x) {\nextractStatementRange(x);\n  if (x == 2) {\n    int z = 0;\n  }\n}\n\n" [[@LINE-9]]:1
+// CHECK4-NEXT: "extracted(x);" [[@LINE-7]]:3 -> [[@LINE-4]]:4
+
+// CHECK4: "static void extracted(int x) {\nint y = 0;\n  extractStatementRange(x);\n}\n\n" [[@LINE-12]]:1
+// CHECK4-NEXT: "extracted(x)" [[@LINE-11]]:3 -> [[@LINE-10]]:27
+
+// CHECK4: "static void extracted(int &x) {\nx = 2;\n  int y = 0;\n  extractStatementRange(x);\n}\n\n" [[@LINE-15]]:1
+// CHECK4-NEXT: "extracted(x)" [[@LINE-15]]:3 -> [[@LINE-13]]:27
+
+// CHECK4: "static void extracted(int &x) {\nx = 2;\n  int y = 0;\n}\n\n" [[@LINE-18]]:1
+// CHECK4-NEXT: "extracted(x);" [[@LINE-18]]:3 -> [[@LINE-17]]:13
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:80:3-83:4 -selected=%s:79:3-80:6 -selected=%s:78:3-80:6 -selected=%s:78:3-79:6 %s | FileCheck --check-prefix=CHECK4 %s
+
+void extractedVariableUsedAndDefinedInExtractedCode(int x) {
+  int y = x;
+  if (y == 1) {
+    int z = 0;
+  }
+// CHECK5: "static void extracted(int x) {\nint y = x;\n  if (y == 1) {\n    int z = 0;\n  }\n}\n\n"
+// CHECK5-NEXT: "extracted(x);"
+// CHECK5: "static void extracted(int y) {\nif (y == 1) {\n    int z = 0;\n  }\n}\n\n"
+// CHECK5-NEXT: "extracted(y);"
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:102:2-105:4 -selected=%s:103:2-105:4 %s | FileCheck --check-prefix=CHECK5 %s
+
+void extractAssignmentAsStatementOrExpr(int x) {
+  x = 2;
+// CHECK6: "static void extracted(int &x) {\nx = 2;\n}\n\n"
+  x = x = 3;
+// CHECK6: "static int extracted(int &x) {\nreturn x = 3;\n}\n\n"
+  (void)(x = 4);
+// CHECK6: "static int extracted(int &x) {\nreturn x = 4;\n}\n\n"
+  if (x = 5) {
+  }
+// CHECK6: "static int extracted(int &x) {\nreturn x = 5;\n}\n\n"
+  if (true)
+    x = 6;
+// CHECK6: "static void extracted(int &x) {\nx = 6;\n}\n\n"
+  bool b = 2;
+  if (b = false) {
+  }
+// CHECK6: "static bool extracted(bool &b) {\nreturn b = false;\n}\n\n"
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:115:3-115:8 -selected=%s:117:7-117:12 -selected=%s:119:10-119:15 -selected=%s:121:7-121:12 -selected=%s:125:5-125:10 -selected=%s:128:7-128:16 %s | FileCheck --check-prefix=CHECK6 %s
+
+void extractCompoundAssignmentAsStatementOrExpr(int x) {
+  x += 2;
+// CHECK7: "static void extracted(int &x) {\nx += 2;\n}\n\n"
+  x = x += 3;
+// CHECK7: "static int extracted(int &x) {\nreturn x += 3;\n}\n\n"
+  if (x *= 4) {
+  }
+// CHECK7: "static int extracted(int &x) {\nreturn x *= 4;\n}\n\n"
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:136:3-136:9 -selected=%s:138:7-138:13 -selected=%s:140:7-140:13 %s | FileCheck --check-prefix=CHECK7 %s
+
+int inferReturnTypeFromReturnStatement(int x) {
+  if (x == 0) {
+    return x;
+  }
+  if (x == 1) {
+    return x + 1;
+  }
+  return x + 2;
+}
+// CHECK8: "static int extracted(int x) {\nif (x == 1) {\n    return x + 1;\n  }\n  return x + 2;\n}\n\n"
+// CHECK8: "static int extracted(int x) {\nif (x == 1) {\n    return x + 1;\n  }\n}\n\n"
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:151:3-154:15 -selected=%s:151:3-153:4 %s | FileCheck --check-prefix=CHECK8 %s
+
+void careForNonCompoundSemicolons() {
+// if-open-begin:+1:1
+  if (true)
+    careForNonCompoundSemicolons();
+// if-open-end: -1:35
+// CHECK9: "static void extracted() {\nif (true)\n    careForNonCompoundSemicolons();\n}\n\n"
+// CHECK9: "extracted();" [[@LINE-4]]:3 -> [[@LINE-3]]:36
+
+// for-open-begin:+1:1
+  for (int i = 0; i < 10; ++i)
+    while (i != 0)
+      ;
+// for-open-end: +0:1
+// CHECK9:"static void extracted() {\nfor (int i = 0; i < 10; ++i)\n    while (i != 0)\n      ;\n}\n\n" [[@LINE-15]]:1
+// CHECK9: "extracted();" [[@LINE-5]]:3 -> [[@LINE-3]]:8
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=if-open -selected=for-open %s | FileCheck --check-prefix=CHECK9 %s
diff --git a/test/Refactor/Extract/extract-statements.m b/test/Refactor/Extract/extract-statements.m
new file mode 100644
index 0000000..db86ab8
--- /dev/null
+++ b/test/Refactor/Extract/extract-statements.m
@@ -0,0 +1,57 @@
+@interface NSArray
++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt;
+@end
+
+void extractedStmtNoNeedForSemicolon(NSArray *array) {
+  for (id i in array) {
+    int x = 0;
+  }
+// CHECK1: "static void extracted(NSArray *array) {\nfor (id i in array) {\n    int x = 0;\n  }\n}\n\n"
+  id lock;
+  @synchronized(lock) {
+    int x = 0;
+  }
+// CHECK1: "static void extracted(id lock) {\n@synchronized(lock) {\n    int x = 0;\n  }\n}\n\n"
+  @autoreleasepool {
+    int x = 0;
+  }
+// CHECK1: "static void extracted() {\n@autoreleasepool {\n    int x = 0;\n  }\n}\n\n"
+  @try {
+    int x = 0;
+  } @finally {
+  }
+// CHECK1: "static void extracted() {\n@try {\n    int x = 0;\n  } @finally {\n  }\n}\n\n"
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:6:3-8:4 -selected=%s:11:3-13:4 -selected=%s:15:3-17:4 -selected=%s:19:3-22:4 %s | FileCheck --check-prefix=CHECK1 %s
+
+@interface I
+
+@end
+
+@implementation I
+
+- (int)inferReturnTypeFromReturnStatement:(int)x {
+  if (x == 0) {
+    return x;
+  }
+  if (x == 1) {
+    return x + 1;
+  }
+  return x + 2;
+}
+// CHECK2: "static int extracted(int x) {\nif (x == 1) {\n    return x + 1;\n  }\n  return x + 2;\n}\n\n"
+// CHECK2: "static int extracted(int x) {\nif (x == 1) {\n    return x + 1;\n  }\n}\n\n"
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:38:3-41:15 -selected=%s:38:3-40:4 %s | FileCheck --check-prefix=CHECK2 %s
+
+@end
+
+void partiallySelectedWithImpCastCrash(I *object) {
+// partially-selected-begin: +1:3
+  object;
+// partially-selected-end: +1:11
+// comment
+// CHECK3: "static void extracted(I *object) {\nobject;\n}\n\n"
+// RUN: clang-refactor-test perform -action extract -selected=partially-selected %s | FileCheck --check-prefix=CHECK3 %s
+}
diff --git a/test/Refactor/Extract/extract-whole-source-construct.cpp b/test/Refactor/Extract/extract-whole-source-construct.cpp
new file mode 100644
index 0000000..93df9e0
--- /dev/null
+++ b/test/Refactor/Extract/extract-whole-source-construct.cpp
@@ -0,0 +1,120 @@
+void extractEntireIfWhenSelectedBody(int x) {
+  if (x == 1)
+  {
+    int z = x + 2;
+  }
+  else if (x == 3)
+  {
+    int y = x + 1;
+  }
+  // CHECK1: Initiated the 'extract' action at [[@LINE-8]]:3 -> [[@LINE-1]]:4
+}
+
+// RUN: clang-refactor-test initiate -action extract -selected=%s:3:3-5:4 -selected=%s:7:3-9:4 -selected=%s:4:5-8:19 -selected=%s:6:12-9:4 %s | FileCheck --check-prefix=CHECK1 %s
+
+void extractEntireSourceConstructWhenSelectedBody(int x) {
+  switch (x)
+   {
+  case 0:
+    break;
+  case 1:
+    break;
+  }
+// CHECK2: Initiated the 'extract' action at [[@LINE-7]]:3 -> [[@LINE-1]]:4
+// RUN: clang-refactor-test initiate -action extract -selected=%s:17:4-22:4 %s | FileCheck --check-prefix=CHECK2 %s
+
+  for (int i = 0; i < x; ++i)
+   {
+    break;
+  }
+// CHECK3: Initiated the 'extract' action at [[@LINE-4]]:3 -> [[@LINE-1]]:4
+// RUN: clang-refactor-test initiate -action extract -selected=%s:27:4-29:4 %s | FileCheck --check-prefix=CHECK3 %s
+
+  while (x < 0)
+   {
+    break;
+  }
+// CHECK4: Initiated the 'extract' action at [[@LINE-4]]:3 -> [[@LINE-1]]:4
+// RUN: clang-refactor-test initiate -action extract -selected=%s:34:4-36:4 %s | FileCheck --check-prefix=CHECK4 %s
+
+  do
+   {
+    break;
+  }
+  while (x != 0);
+// CHECK5: Initiated the 'extract' action at [[@LINE-5]]:3 -> [[@LINE-1]]:17
+// RUN: clang-refactor-test initiate -action extract -selected=%s:41:4-43:4 %s | FileCheck --check-prefix=CHECK5 %s
+}
+
+void extractJustTheCompoundStatement() {
+  {
+    {
+      int x = 0;
+    }
+  }
+// CHECK6: Initiated the 'extract' action at [[@LINE-4]]:5 -> [[@LINE-2]]:6
+// RUN: clang-refactor-test initiate -action extract -selected=%s:51:5-53:6 %s | FileCheck --check-prefix=CHECK6 %s
+}
+
+void extractSwitch(int x) {
+  switch (x) {
+    extractSwitch(x - 1);
+
+    case 0:
+      extractSwitch(x + 1);
+      break;
+
+    // comment
+    case 1:
+      extractSwitch(x + 2);
+      break;
+
+    default:
+      extractSwitch(x + 2);
+      break;
+
+  }
+// CHECK7: Initiated the 'extract' action at [[@LINE-17]]:3 -> [[@LINE-1]]:4
+// RUN: clang-refactor-test initiate -action extract -selected=%s:61:3-64:27 -selected=%s:63:5-63:11 -selected=%s:68:5-69:27 -selected=%s:72:5-72:13 %s | FileCheck --check-prefix=CHECK7 %s
+}
+
+class AClass {
+  void method();
+
+  void extractWholeCallWhenJustMethodSelected() {
+    method();
+  }
+};
+// CHECK8: Initiated the 'extract' action at [[@LINE-3]]:5 -> [[@LINE-3]]:13
+// RUN: clang-refactor-test initiate -action extract -selected=%s:85:5-85:6 -selected=%s:85:5-85:11 %s | FileCheck --check-prefix=CHECK8 %s
+
+void extractWholeCallWhenJustMethodSelected() {
+  AClass a;
+  a.method();
+}
+// CHECK9: Initiated the 'extract' action at [[@LINE-2]]:3 -> [[@LINE-2]]:13
+// RUN: clang-refactor-test initiate -action extract -selected=%s:93:3-93:7 -selected=%s:93:5-93:11 %s | FileCheck --check-prefix=CHECK9 %s
+;
+void avoidExtractingTooMuch(bool boolean) { // CHECK10: void extracted() {\nint x = 2;\n    // avoid-{{.*}}-end:+1:15\n    int y = x;\n}\n\n" [[@LINE]]:1
+  if (boolean) {
+    // avoid-too-much-begin:+1:1 // CHECK10: "extracted();" [[@LINE+1]]:5 -> [[@LINE+3]]:15
+    int x = 2;
+    // avoid-too-much-end:+1:15
+    int y = x;
+  } else {
+    int z = 3;
+  }
+
+  // switch-casesel-begin: +4:3 // switch-casesel-end: +4:4 // CHECK10: void extracted(bool boolean) {\nswitch ((int)boolean) {\n case 0:\n avoidExtractingTooMuch(boolean);\n avoidExtractingTooMuch(boolean);\n break;\n }\n}
+  // switch-case0-begin: +4:5 // switch-case0-end: +4:36 // CHECK10: void extracted(bool boolean) {\navoidExtractingTooMuch(boolean);\n}
+  // switch-case1-begin: +3:5 // switch-case1-end: +4:36 // CHECK10: void extracted(bool boolean) {\navoidExtractingTooMuch(boolean);\n    avoidExtractingTooMuch(boolean);\n}\n\n"
+  switch ((int)boolean) {
+  case 0:
+    avoidExtractingTooMuch(boolean);
+    avoidExtractingTooMuch(boolean);
+    break;
+  }
+  // CHECK10: "extracted(boolean)" [[@LINE-4]]:5 -> [[@LINE-3]]:36
+}
+
+// RUN: clang-refactor-test perform -action extract -selected=avoid-too-much -selected=switch-casesel -selected=switch-case0 -selected=switch-case1 %s | FileCheck --check-prefix=CHECK10 %s
diff --git a/test/Refactor/Extract/extracted-declaration-name.mm b/test/Refactor/Extract/extracted-declaration-name.mm
new file mode 100644
index 0000000..f9d7228
--- /dev/null
+++ b/test/Refactor/Extract/extracted-declaration-name.mm
@@ -0,0 +1,50 @@
+
+int compute(int n, int x, int y) {
+  int sum = 0;
+  for (int i = 0; i < n; ++i) {
+// extract-func-begin: +1:12
+    sum += (x - i) * (y + i);
+// extract-func-end: -1:29
+  }
+  return sum;
+}
+// RUN: clang-refactor-test perform -action extract -emit-associated -selected=extract-func %s | FileCheck --check-prefix=CHECK1 %s
+// CHECK1: "static int extracted(int i, int x, int y) {\nreturn (x - i) * (y + i);\n}\n\n" [[@LINE-10]]:1 -> [[@LINE-10]]:1 [Symbol extracted-decl 0 1:12 -> 1:21]
+// CHECK1-NEXT: "extracted(i, x, y)" [[@LINE-7]]:12 -> [[@LINE-7]]:29 [Symbol extracted-decl-ref 0 1:1 -> 1:10]
+
+struct Struct {
+  int func(int y) { return y; }
+
+  int compute(int x, int y);
+};
+
+int Struct::compute(int x, int y) {
+// extract-member-func-begin: +1:10
+  return x * func(y + x) + y;
+// extract-member-func-end: -1:25
+}
+// RUN: clang-refactor-test perform -action extract-method -emit-associated -selected=extract-member-func %s | FileCheck --check-prefix=CHECK2 %s
+// CHECK2: "int extracted(int x, int y);\n\n" [[@LINE-9]]:3 -> [[@LINE-9]]:3 [Symbol extracted-decl 0 1:5 -> 1:14]
+// CHECK2-NEXT: "int Struct::extracted(int x, int y) {\nreturn x * func(y + x);\n}\n\n" [[@LINE-7]]:1 -> [[@LINE-7]]:1 [Symbol extracted-decl 0 1:13 -> 1:22]
+// CHECK2-NEXT: "extracted(x, y)" [[@LINE-6]]:10 -> [[@LINE-6]]:25 [Symbol extracted-decl-ref 0 1:1 -> 1:10]
+
+@interface I
+
+@property int p;
+
+- (void)foo:(int)x with:(int)y;
+
+@end
+
+@implementation I
+
+- (void)foo:(int)x with:(int)y {
+// extract-selector-begin: +1:1
+  int m = compute(10, self.p + y, x);
+// extract-selector-end: +0:1
+}
+
+@end
+// RUN: clang-refactor-test perform -action extract-method -emit-associated -selected=extract-selector %s | FileCheck --check-prefix=CHECK3 %s
+// CHECK3: "- (void)extracted:(int)x y:(int)y {\nint m = compute(10, self.p + y, x);\n}\n\n" [[@LINE-8]]:1 -> [[@LINE-8]]:1 [Symbol extracted-decl 0 1:9 -> 1:18 1:26 -> 1:27]
+// CHECK3-NEXT: "[self extracted:x y:y];" [[@LINE-7]]:3 -> [[@LINE-7]]:38 [Symbol extracted-decl-ref 0 1:7 -> 1:16 1:19 -> 1:20]
diff --git a/test/Refactor/Extract/return-c-bool.c b/test/Refactor/Extract/return-c-bool.c
new file mode 100644
index 0000000..0cb5a64
--- /dev/null
+++ b/test/Refactor/Extract/return-c-bool.c
@@ -0,0 +1,28 @@
+#ifndef __cplusplus
+#define bool _Bool
+#define true 1
+#define false 0
+#endif
+typedef struct {
+  bool b;
+} HasBool;
+
+bool boolType(bool b, HasBool *s) {
+  bool x = b && true;
+  bool y = boolType(b, s);
+  bool z = s->b;
+  bool a = !b;
+  return (b || true);
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:11:12-11:21 -selected=%s:12:12-12:26 --selected=%s:13:12-13:16 --selected=%s:14:12-14:14 --selected=%s:15:10-15:21 %s | FileCheck %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:11:12-11:21 -selected=%s:12:12-12:26 --selected=%s:13:12-13:16 --selected=%s:14:12-14:14 --selected=%s:15:10-15:21 %s -x c++ | FileCheck %s
+// CHECK: "static bool extracted
+;
+int boolCompareOps(int x, int y) {
+  bool a = x == y;
+  bool b = x >= y;
+  bool c = ((x < y));
+  return 0;
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:22:12-22:18 -selected=%s:23:12-23:18 --selected=%s:24:12-24:21 %s | FileCheck %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:22:12-22:18 -selected=%s:23:12-23:18 --selected=%s:24:12-24:21 %s -x c++ | FileCheck %s
diff --git a/test/Refactor/Extract/return-correct-stl-type.cpp b/test/Refactor/Extract/return-correct-stl-type.cpp
new file mode 100644
index 0000000..f7b9444
--- /dev/null
+++ b/test/Refactor/Extract/return-correct-stl-type.cpp
@@ -0,0 +1,51 @@
+namespace std {
+
+struct Traits {
+  typedef char char_type;
+};
+
+template<typename TraitsType>
+struct BasicString {
+  typedef typename TraitsType::char_type value_type;
+  value_type value() const;
+  const value_type *data() const;
+};
+
+template<typename TraitsType>
+BasicString<TraitsType>
+operator+(const BasicString<TraitsType> &lhs,
+          const BasicString<TraitsType> &rhs);
+template<typename TraitsType>
+BasicString<TraitsType>
+operator+(const BasicString<TraitsType> &lhs,
+          const char *rhs);
+
+template<typename TraitsType>
+struct BasicString;
+typedef BasicString<Traits> String;
+
+} // end namespace std
+
+void returnCharTypeNotUselessValueType() {
+// CHECK1: "static char extracted(const std::String &x) {\nreturn x.value();\n}\n\n" [[@LINE-1]]:1
+// CHECK1: "static const char * extracted(const std::String &x) {\nreturn x.data();\n}\n\n" [[@LINE-2]]:1
+  std::String x;
+// return-char-begin: +1:9
+  (void)x.value();
+// return-char-end: +0:1
+// return-data-begin: +1:9
+  (void)x.data();
+// return-data-end: +0:1
+} // RUN: clang-refactor-test perform -action extract -selected=return-char -selected=return-data %s | FileCheck --check-prefix=CHECK1 %s
+
+void operatorTypeInferral() {
+// CHECK2: "static std::String extracted(const std::String &x) {\nreturn x + "hello";\n}\n\n" [[@LINE-1]]:1
+// CHECK2: "static std::String extracted(const std::String &x) {\nreturn x + x;\n}\n\n" [[@LINE-2]]:1
+  std::String x;
+// infer-string1-begin: +1:10
+  (void)(x + "hello");
+// infer-string1-end: -1:21
+// infer-string2-begin: +1:10
+  (void)(x + x);
+// infer-string2-end: -1:15
+} // RUN: clang-refactor-test perform -action extract -selected=infer-string1 -selected=infer-string2 %s | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Extract/return-objc-bool.m b/test/Refactor/Extract/return-objc-bool.m
new file mode 100644
index 0000000..109ae5b
--- /dev/null
+++ b/test/Refactor/Extract/return-objc-bool.m
@@ -0,0 +1,89 @@
+#ifdef SIGNED
+typedef signed char BOOL;
+#else
+
+#ifndef __cplusplus
+#define bool _Bool
+#endif
+
+typedef bool BOOL;
+
+#endif
+
+#define YES __objc_yes
+#define NO __objc_no
+
+typedef struct {
+  BOOL b;
+} HasBool;
+
+// Always prefer to use BOOL in the Objective-C methods.
+
+@interface I
+@end
+
+@implementation I
+
+- (BOOL)boolType:(BOOL)b with:(HasBool*)s {
+  BOOL x = b && YES;
+  BOOL y = [self boolType: b with: s];
+  BOOL z = s->b;
+  BOOL a = !b;
+  return (b == NO);
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:28:12-28:20 -selected=%s:29:12-29:38 -selected=%s:30:12-30:16 -selected=%s:31:12-31:14 -selected=%s:32:10-32:19 %s | FileCheck --check-prefix=CHECKBOOL %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:28:12-28:20 -selected=%s:29:12-29:38 -selected=%s:30:12-30:16 -selected=%s:31:12-31:14 -selected=%s:32:10-32:19 %s -D SIGNED | FileCheck --check-prefix=CHECKBOOL %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:28:12-28:20 -selected=%s:29:12-29:38 -selected=%s:30:12-30:16 -selected=%s:31:12-31:14 -selected=%s:32:10-32:19 %s -x objective-c++ | FileCheck --check-prefix=CHECKBOOL %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:28:12-28:20 -selected=%s:29:12-29:38 -selected=%s:30:12-30:16 -selected=%s:31:12-31:14 -selected=%s:32:10-32:19 %s -x objective-c++ -D SIGNED | FileCheck --check-prefix=CHECKBOOL %s
+
+// CHECKBOOL: "static BOOL extracted
+
+#ifdef __cplusplus
+
+// Prefer BOOL even in Objective-C++ methods.
+
+- (BOOL)chooseBOOLEvenInCPlusPlus:(bool)b and:(bool)c {
+  bool x = b && c;
+  bool n = !b;
+}
+
+#endif
+// RUN: clang-refactor-test perform -action extract -selected=%s:46:12-46:18 -selected=%s:47:12-47:14 %s -x objective-c++ | FileCheck --check-prefix=CHECKBOOL %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:46:12-46:18 -selected=%s:47:12-47:14 %s -x objective-c++ -D SIGNED | FileCheck --check-prefix=CHECKBOOL %s
+
+@end
+
+#ifdef __cplusplus
+
+// In Objective-C++ functions/methods we want to pick the type based on the expression.
+
+BOOL boolObjCFunction(BOOL b, BOOL c) {
+  BOOL x = b && c;
+  BOOL y = boolObjCFunction(b, c);
+  return b;
+}
+// RUN: clang-refactor-test perform -action extract -selected=%s:61:12-61:18 -selected=%s:62:12-62:34 %s -x objective-c++ | FileCheck --check-prefix=CHECKBOOL %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:61:12-61:18 -selected=%s:62:12-62:34 %s -x objective-c++ -D SIGNED | FileCheck --check-prefix=CHECKBOOL %s
+
+bool boolCPlusPlusFunction(bool b, bool c) {
+  bool x = b && c;
+  bool y = boolCPlusPlusFunction(b, c);
+  return b;
+}
+// CHECKNORMAL: "static bool extracted
+// RUN: clang-refactor-test perform -action extract -selected=%s:69:12-69:18 -selected=%s:70:12-70:39 %s -x objective-c++ | FileCheck --check-prefix=CHECKNORMAL %s
+
+class AClass {
+  AClass(BOOL b, BOOL c, bool d, bool e) {
+    BOOL x = b && c;
+    bool y = d && e;
+  }
+  void method(BOOL b, BOOL c, bool d, bool e) {
+    BOOL x = b || c;
+    bool y = d || e;
+  }
+};
+// RUN: clang-refactor-test perform -action extract -selected=%s:78:14-78:20 -selected=%s:82:14-84:20 %s -x objective-c++ | FileCheck --check-prefix=CHECKBOOL %s
+// RUN: clang-refactor-test perform -action extract -selected=%s:79:14-79:20 -selected=%s:83:14-83:20 %s -x objective-c++ | FileCheck --check-prefix=CHECKNORMAL %s
+
+#endif
diff --git a/test/Refactor/Extract/return-objc-generic-argument-type.m b/test/Refactor/Extract/return-objc-generic-argument-type.m
new file mode 100644
index 0000000..42d9770
--- /dev/null
+++ b/test/Refactor/Extract/return-objc-generic-argument-type.m
@@ -0,0 +1,40 @@
+// RUN: clang-refactor-test perform -action extract -selected=prop -selected=imp-prop -selected=class-prop -selected=class-prop2 -selected=class-method %s | FileCheck %s
+
+@interface NSObject
+@end
+
+@interface Array<Element> : NSObject
+
+@property Element prop;
+
+- (Element)get;
+
+@property (class) Array<Element> *classProp;
+
++ (Element *)classGet;
+
+@end
+
+void foo(Array<NSObject *> *objects) {
+// prop-begin: +1:3
+  objects.prop;
+// prop-end: -1:15
+// CHECK: "static NSObject * extracted(Array<NSObject *> *objects) {\nreturn objects.prop;\n}\n\n"
+// imp-prop-begin: +1:3
+  objects.get;
+// imp-prop-end: -1:14
+// CHECK: "static NSObject * extracted(Array<NSObject *> *objects) {\nreturn objects.get;\n}\n\n"
+// class-prop-begin: +1:3
+  Array.classProp;
+// class-prop-end: -1:30
+// CHECK: "static Array * extracted() {\nreturn Array.classProp;\n}\n\n"
+  typedef Array<NSObject *> ObjectArray;
+// class-prop2-begin: +1:3
+  [ObjectArray classProp];
+// class-prop2-end: -1:26
+// CHECK: "static Array<NSObject *> * extracted() {\nreturn [ObjectArray classProp];\n}\n\n"
+// class-method-begin: +1:3
+  [ObjectArray classGet];
+// class-method-end: -1:25
+// CHECK: "static NSObject ** extracted() {\nreturn [ObjectArray classGet];\n}\n\n"
+}
diff --git a/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-duplicates.cpp b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-duplicates.cpp
new file mode 100644
index 0000000..ba97e23
--- /dev/null
+++ b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-duplicates.cpp
@@ -0,0 +1,63 @@
+
+struct AClass {
+  int method();
+  int method2();
+};
+struct AWrapperClass {
+  AClass &object(int x);
+};
+
+void duplicatesWithParens(AWrapperClass &wrapper) {
+  wrapper.object(0).method();
+// CHECK1: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-1]]:3
+  ((wrapper).object((0))).method();
+// CHECK2: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-1]]:4
+}
+
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:11:3-20 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:13:4-25 %s | FileCheck --check-prefix=CHECK2 %s
+
+
+void noDuplicatesWithParens(AWrapperClass &wrapper) {
+  wrapper.object(- 1).method();
+#ifndef DUPLICATE
+  wrapper.object((- 1)).method();
+#else
+  (wrapper).object(- 1).method();
+#endif
+// CHECK3: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-6]]:3
+
+  wrapper.object(1 + 2).method();
+#ifndef DUPLICATE
+  wrapper.object((1 + 2)).method();
+#else
+  ((wrapper)).object(1 + 2).method();
+#endif
+// CHECK4: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-6]]:3
+
+  wrapper.object(true ? 0 : 1).method();
+#ifndef DUPLICATE
+  wrapper.object((true ? 0 : 1)).method();
+#else
+  ((wrapper)).object(true ? (0) : (1)).method();
+#endif
+// CHECK5: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-6]]:3
+}
+
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:22:3-22 %s -DDUPLICATE | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:30:3-24 %s -DDUPLICATE | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:38:3-31 %s -DDUPLICATE | FileCheck --check-prefix=CHECK5 %s
+
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:22:1-32 -in=%s:30:1-34 -in=%s:38:1-41 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// CHECK-NO: Failed to initiate the refactoring action!
+
+void noDuplicatesWhenSemanticsChange(AWrapperClass &wrapper) {
+  wrapper.object(0).method();
+  if (true) {
+    AWrapperClass wrapperBase;
+    AWrapperClass &wrapper = wrapperBase;
+    wrapper.object(0).method();
+  }
+}
+
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:55:1-30 in=%s:59:1-32 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
diff --git a/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-duplicates.m b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-duplicates.m
new file mode 100644
index 0000000..bafc192
--- /dev/null
+++ b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-duplicates.m
@@ -0,0 +1,32 @@
+
+@interface Object
+
+- (int)instanceMethod;
+
+@end
+
+@interface Wrapper
+
+- (Object *)returnsObject:(int)arg;
+
+- (Object *)classMethodReturnsObject;
++ (Object *)classMethodReturnsObject;
+
+@end
+
+void differentWrapperVariables(Wrapper *wrapper) {
+  [[wrapper returnsObject: 42] instanceMethod];
+  Wrapper *copyWrapper = wrapper;
+  if (wrapper) {
+    Wrapper *wrapper = copyWrapper;
+    [[wrapper returnsObject: 42] prop];
+  }
+  [[Wrapper classMethodReturnsObject] instanceMethod];
+  if (wrapper) {
+    __auto_type Wrapper = wrapper;
+    [[Wrapper classMethodReturnsObject] instanceMethod];
+  }
+}
+
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:18:1-48 -in=%s:24:1-55 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// CHECK-NO: Failed to initiate the refactoring action!
diff --git a/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-initiate.cpp b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-initiate.cpp
new file mode 100644
index 0000000..de8b1d8
--- /dev/null
+++ b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-initiate.cpp
@@ -0,0 +1,109 @@
+
+struct AClass {
+  int method();
+  int method2();
+};
+struct AWrapperClass {
+  AClass &object();
+};
+
+void takesClass(AWrapperClass &wrapper) {
+  wrapper.object().method();
+  wrapper.object().method();
+  wrapper.object().method2();
+}
+// CHECK1: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-4]]:3
+// CHECK2: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-4]]:3
+// CHECK3: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-4]]:3
+
+// Suggest extracting 'wrapper.object()'
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:11:3-19 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:12:3-19 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:13:3-19 %s | FileCheck --check-prefix=CHECK3 %s
+
+// CHECK-NO: Failed to initiate the refactoring action!
+
+// Avoid suggesting extraction of 'wrapper.object().method2()'
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:13:20-30 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test list-actions -at=%s:11:11 %s | FileCheck --check-prefix=CHECK-ACTION %s
+// CHECK-ACTION: Extract Repeated Expression
+
+AClass &returnsReference(int x);
+AClass &returnsAndTakesFunctionPointer(AClass& (*)(int));
+
+void checkReferenceCall() {
+  returnsReference(0).method();
+  returnsReference(0).method2();
+  returnsAndTakesFunctionPointer(returnsReference).method();
+  returnsAndTakesFunctionPointer(returnsReference).method2();
+}
+// CHECK4: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-5]]:3
+// CHECK5: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-4]]:3
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:36:3-22 %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:38:3-51 %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:36:23-32 -in=%s:37:23-32 -in=%s:38:52-61 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+struct WithFields {
+  int x, y;
+};
+struct WithFieldsOperators {
+  WithFields *operator ->();
+  WithFields &operator ()();
+
+  const WithFields &operator [](int x) const;
+  WithFields &operator [](int x);
+};
+
+void checkOperatorCalls(WithFieldsOperators &op, int id) {
+  op[id].x;
+  op[id].y;
+// CHECK6: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:3
+  op().x;
+  op().x;
+// CHECK7: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:3
+  op->x;
+  op->x;
+}
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:59:3-9 %s | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:62:3-7 %s | FileCheck --check-prefix=CHECK7 %s
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:59:10-12 -in=%s:62:8-10 -in=%s:65:3-9 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+struct AWrapperClass2 {
+  AClass *object() const;
+};
+
+void checkPointerType(AWrapperClass *object, AWrapperClass2 *object2) {
+  object->object().method();
+  if (object) {
+    object->object().method2();
+  }
+// CHECK8: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-4]]:3
+  object2->object()->method();
+  int m = object2->object()->method2();
+// CHECK9: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:3
+}
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:77:3-19 %s | FileCheck --check-prefix=CHECK8 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:82:3-20 %s | FileCheck --check-prefix=CHECK9 %s
+
+struct ConstVsNonConst {
+  int field;
+  void constMethod() const;
+  void method();
+};
+
+struct ConstVsNonConstWrapper {
+  const ConstVsNonConst &object() const;
+  ConstVsNonConst &object();
+};
+
+void checkFoo(ConstVsNonConstWrapper &object) {
+  object.object().constMethod();
+  object.object().method();
+}
+// CHECK10: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-3]]:3
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -at=%s:101:3 %s | FileCheck --check-prefix=CHECK10 %s
+
+// Check that the action can be initiate using a selection:
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -selected=%s:11:3-11:19 -selected=%s:11:15-11:19 -selected=%s:11:3-11:17 -selected=%s:11:15-11:18 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -selected=%s:11:3-11:22 -selected=%s:11:1-13:30 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
diff --git a/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-initiate.m b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-initiate.m
new file mode 100644
index 0000000..11df71f
--- /dev/null
+++ b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-initiate.m
@@ -0,0 +1,106 @@
+
+@interface Base
+
+@end
+
+@interface Object: Base {
+  int ivar;
+}
+
+- (int)instanceMethod;
+
+@property int prop;
+@property void (^block)();
+
+@end
+
+@interface Wrapper
+
+- (Object *)returnsObject:(int)arg;
+
++ (Object *)classMethodReturnsObject;
+
+@property(class) Object *classObject;
+
+@property Object *object;
+
+@end
+
+void test(Wrapper *wrapper) {
+  [[wrapper returnsObject: 42] instanceMethod];
+  [[wrapper returnsObject: 42] prop];
+// CHECK1: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:4
+// CHECK2: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:4
+
+  wrapper.object.prop;
+  [wrapper.object instanceMethod];
+// CHECK3: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:3
+// CHECK4: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:4
+
+  [[wrapper object] block];
+  [[wrapper object] instanceMethod];
+// CHECK5: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:4
+// CHECK6: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:4
+
+  [[Wrapper classMethodReturnsObject] instanceMethod];
+  [[Wrapper classMethodReturnsObject] prop];
+// CHECK7: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:4
+// CHECK8: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:4
+
+  Wrapper.classObject.prop;
+  if (1)
+    [Wrapper.classObject instanceMethod];
+// CHECK9: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-3]]:3
+// CHECK10: Initiated the 'extract-repeated-expr-into-var' action at [[@LINE-2]]:6
+}
+
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:30:4-31 %s -fblocks | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:31:4-31 %s -fblocks | FileCheck --check-prefix=CHECK2 %s
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:30:1-3 -in=%s:30:32-48 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:35:3-17 %s -fblocks | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:36:4-18 %s -fblocks | FileCheck --check-prefix=CHECK4 %s
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:35:18-23 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:40:4-20 %s -fblocks | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:41:4-20 %s -fblocks | FileCheck --check-prefix=CHECK6 %s
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:40:21-28 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:45:4-38 %s -fblocks | FileCheck --check-prefix=CHECK7 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:46:4-38 %s -fblocks | FileCheck --check-prefix=CHECK8 %s
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:45:39-55 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:50:3-22 %s -fblocks | FileCheck --check-prefix=CHECK9 %s
+// RUN: clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:52:6-25 %s -fblocks | FileCheck --check-prefix=CHECK10 %s
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:50:23-28 -in=%s:51:1-9 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// CHECK-NO: Failed to initiate the refactoring action!
+
+void testInvalidMethod(Wrapper *ref) {
+  if (2)
+    [[ref classObject] instanceMethod];
+  [ref classObject].block();
+}
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -in=%s:81:6-23 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+@interface ImplicitPropertyWithoutGetter
+- (void) setValue: (int) value;
+@end
+void implicitPropertyWithoutGetter(ImplicitPropertyWithoutGetter *x) {
+  x.value = 0;
+  x.value = 1;
+}
+
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -at=%s:90:3 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// Prohibit ininiation in macros:
+
+#define MACROREF(X) X.object
+
+void prohibitMacroExpr(Wrapper *wrapper) {
+  // macro-prohibited: +1:3
+  wrapper.object.prop = 0;
+  MACROREF(wrapper).prop = 1;
+}
+
+// RUN: not clang-refactor-test initiate -action extract-repeated-expr-into-var -at=macro-prohibited %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
diff --git a/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.cpp b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.cpp
new file mode 100644
index 0000000..4d8c400
--- /dev/null
+++ b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.cpp
@@ -0,0 +1,100 @@
+
+struct AClass {
+  void constMethod() const;
+  void method();
+};
+
+struct AWrapper {
+  const AClass &object(int x) const;
+  AClass &object(int x);
+};
+
+void takesClass(AWrapper &ref) {
+  int x = 0;
+  ref.object(x).constMethod();
+  int y = 0;
+  ref.object(x).method();
+}
+// CHECK1: "AClass &object = ref.object(x);\nobject" [[@LINE-4]]:3 -> [[@LINE-4]]:16
+
+// CHECK1-NEXT: "object" [[@LINE-4]]:3 -> [[@LINE-4]]:16
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:14:3 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:16:3 %s | FileCheck --check-prefix=CHECK1 %s
+
+void variableNameSuggested(AWrapper &object) {
+#ifdef IN_COMPOUND
+  {
+#endif
+  object.object(21).constMethod();
+  object.object(21).method();
+#ifdef IN_COMPOUND
+  }
+#endif
+}
+// CHECK2: "AClass &object = object.object(21);\nobject" [[@LINE-6]]:3 -> [[@LINE-6]]:20
+
+// CHECK2-NEXT: "object" [[@LINE-7]]:3 -> [[@LINE-7]]:20
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:29:3 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:29:3 %s -D IN_COMPOUND | FileCheck --check-prefix=CHECK2 %s
+
+void takesClass2(AWrapper &ref) {
+  int x = 0;
+  if (x)
+    ref.object(x).constMethod();
+  ref.object(x).method();
+}
+// CHECK3: "AClass &object = ref.object(x);\n" [[@LINE-4]]:3 -> [[@LINE-4]]:3
+// CHECK3-NEXT: "object" [[@LINE-4]]:5 -> [[@LINE-4]]:18
+// CHECK3-NEXT: "object" [[@LINE-4]]:3 -> [[@LINE-4]]:16
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:45:5 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:46:3 %s | FileCheck --check-prefix=CHECK3 %s
+
+void takesClass4(AWrapper &ref) {
+  int x = 0;
+  if (x) {
+    ref.object(x).constMethod();
+    ref.object(x).method();
+  }
+}
+// CHECK4: "AClass &object = ref.object(x);\nobject" [[@LINE-4]]:5 -> [[@LINE-4]]:18
+
+// CHECK4-NEXT: "object" [[@LINE-5]]:5 -> [[@LINE-5]]:18
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:58:5 %s | FileCheck --check-prefix=CHECK4 %s
+
+void insertIntoCommonCompound1(AWrapper &ref) {
+#ifdef EMBED
+  int x = 0;
+  while (true) {
+#endif
+  int x = 0;
+  if (x) {
+    if (true) {
+      int y = x;
+      ref.object(x).constMethod();
+    }
+  } else {
+    ref.object(x).method();
+  }
+// CHECK5: "AClass &object = ref.object(x);\n" [[@LINE-8]]:3 -> [[@LINE-8]]:3
+// CHECK5-NEXT: "object" [[@LINE-6]]:7 -> [[@LINE-6]]:20
+// CHECK5-NEXT: "object" [[@LINE-4]]:5 -> [[@LINE-4]]:18
+#ifdef EMBED
+  }
+#endif
+}
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:77:7 %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:80:5 %s -DEMBED | FileCheck --check-prefix=CHECK5 %s
+
+void checkFirstStmtInCompoundPlacement(AWrapper &ref) {
+  while (true) {
+    ref.object(20);
+    ref.object(20).method();
+// CHECK6: "AClass &object = ref.object(20);\nobject" [[@LINE-2]]:5 -> [[@LINE-2]]:19
+  }
+}
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:94:5 %s | FileCheck --check-prefix=CHECK6 %s
diff --git a/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.m b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.m
new file mode 100644
index 0000000..23ed359
--- /dev/null
+++ b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.m
@@ -0,0 +1,98 @@
+
+@interface Object {
+  int ivar;
+}
+
+- (int)instanceMethod;
+
+@property int prop;
+@property void (^block)();
+
+@end
+
+@interface Wrapper
+
+- (Object *)returnsObject:(int)arg;
+
++ (Object *)classMethodReturnsObject;
+
+@property(class) Object *classObject;
+
+@property Object *object;
+
+@end
+
+void takesClass(Wrapper *ref) {
+  int x = 0;
+  [[ref returnsObject: x] instanceMethod];
+  int y = x;
+  [ref returnsObject: x].prop;
+}
+// CHECK1: "Object *duplicate = [ref returnsObject:x];\n" [[@LINE-4]]:3 -> [[@LINE-4]]:3
+// CHECK1-NEXT: "duplicate" [[@LINE-5]]:4 -> [[@LINE-5]]:26
+// CHECK1-NEXT: "duplicate" [[@LINE-4]]:3 -> [[@LINE-4]]:25
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:27:4 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:29:3 %s | FileCheck --check-prefix=CHECK1 %s
+
+void takesClass2(Wrapper *ref) {
+  if (2)
+    [[ref object] instanceMethod];
+  [ref object].block();
+}
+// CHECK2: "Object *object = [ref object];\n" [[@LINE-4]]:3 -> [[@LINE-4]]:3
+// CHECK2-NEXT: "object" [[@LINE-4]]:6 -> [[@LINE-4]]:18
+// CHECK2-NEXT: "object" [[@LINE-4]]:3 -> [[@LINE-4]]:15
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:40:6 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:41:3 %s | FileCheck --check-prefix=CHECK2 %s
+
+void takesClass3(Wrapper *ref) {
+  if (ref) {
+    [ref.object instanceMethod];
+    ref.object.block();
+  }
+}
+// CHECK3: "Object *object = ref.object;\n" [[@LINE-4]]:5 -> [[@LINE-4]]:5
+// CHECK3-NEXT: "object" [[@LINE-5]]:6 -> [[@LINE-5]]:16
+// CHECK3-NEXT: "object" [[@LINE-5]]:5 -> [[@LINE-5]]:15
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:52:6 %s | FileCheck --check-prefix=CHECK3 %s
+
+void worksOnClass() {
+  [Wrapper classMethodReturnsObject]->ivar = 0;
+  [[Wrapper classMethodReturnsObject] instanceMethod];
+}
+// CHECK4: "Object *classMethodReturnsObject = [Wrapper classMethodReturnsObject];\nclassMethodReturnsObject" [[@LINE-3]]:3 -> [[@LINE-3]]:37
+
+// CHECK4-NEXT: "classMethodReturnsObject" [[@LINE-4]]:4 -> [[@LINE-4]]:38
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:63:4 %s | FileCheck --check-prefix=CHECK4 %s
+
+void worksOnClassProperty() {
+  Wrapper.classObject->ivar = 0;
+  Wrapper.classObject.prop = 2;
+}
+// CHECK5: "Object *classObject = Wrapper.classObject;\nclassObject" [[@LINE-3]]:3 -> [[@LINE-3]]:22
+
+// CHECK5-NEXT: "classObject" [[@LINE-4]]:3 -> [[@LINE-4]]:22
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:73:3 %s | FileCheck --check-prefix=CHECK5 %s
+
+#define MACROARG1(X, Y) (X)
+#define MACROARG2(X) X; ref.object.prop = 0
+
+void macroArgument(Wrapper *ref) {
+  // macro-arg1: +1:13
+  MACROARG1(Wrapper.classObject->ivar, 1); // MACRO-ARG1: "Object *classObject = Wrapper.classObject;\n" [[@LINE]]:3 -> [[@LINE]]:3
+                                             // MACRO-ARG1-NEXT: "classObject" [[@LINE-1]]:13 -> [[@LINE-1]]:32
+  MACROARG1(Wrapper.classObject.prop, 0) = 0;// MACRO-ARG1-NEXT: "classObject" [[@LINE]]:13 -> [[@LINE]]:32
+
+  // macro-arg2: +3:13
+  MACROARG2(int x = 0; ref.object->ivar); // MACRO-ARG2: "Object *object = ref.object;\n" [[@LINE]]:3 -> [[@LINE]]:3
+                                          // MACRO-ARG2-NEXT: "object" [[@LINE-1]]:24 -> [[@LINE-1]]:34
+  MACROARG2(ref.object.prop);// MARO-ARG2-NEXT: "object" [[@LINE]]:13 -> [[@LINE]]:23
+}
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=macro-arg1 %s | FileCheck --check-prefix=MACRO-ARG1 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=macro-arg2 %s | FileCheck --check-prefix=MACRO-ARG2 %s
diff --git a/test/Refactor/FillInEnumSwitchCases/fill-in-cases-forward-decl.c b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-forward-decl.c
new file mode 100644
index 0000000..dd63951
--- /dev/null
+++ b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-forward-decl.c
@@ -0,0 +1,26 @@
+#ifndef AFTER
+enum ForwardEnumDecl;
+#endif
+
+enum ForwardEnumDecl {
+  A, B
+};
+
+#ifdef AFTER
+enum ForwardEnumDecl;
+#endif
+
+void dontInitiateOnIncompleteEnum(enum ForwardEnumDecl e) {
+  switch (e) {
+  }
+// CHECK: "case A:\n<#code#>\nbreak;\ncase B:\n<#code#>\nbreak;\n" [[@LINE-1]]:3
+
+  switch (e) {
+  case A:
+    break;
+  }
+// CHECK: "case B:\n<#code#>\nbreak;\n" [[@LINE-1]]:3
+}
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:14:3 -at=%s:18:3 %s | FileCheck %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:14:3 -at=%s:18:3 %s -D AFTER | FileCheck %s
diff --git a/test/Refactor/FillInEnumSwitchCases/fill-in-cases-initiate.cpp b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-initiate.cpp
new file mode 100644
index 0000000..3d8c1a7
--- /dev/null
+++ b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-initiate.cpp
@@ -0,0 +1,150 @@
+enum Color {
+  Black,
+  Blue,
+  White,
+  Gold
+};
+
+void initiate(Color c, int i) {
+  switch (c) {
+  case Black:
+    break;
+  }
+// CHECK1: Initiated the 'fill-in-enum-switch-cases' action at [[@LINE-4]]:3
+
+  switch (c) {
+  }
+// CHECK2: Initiated the 'fill-in-enum-switch-cases' action at [[@LINE-2]]:3
+}
+
+// RUN: clang-refactor-test list-actions -at=%s:9:3 %s | FileCheck --check-prefix=CHECK-ACTION %s
+// CHECK-ACTION: Add Missing Switch Cases
+
+// Ensure the the action can be initiated around a switch:
+
+// RUN: clang-refactor-test initiate -action fill-in-enum-switch-cases -in=%s:9:3-15 -in=%s:10:1-14 -in=%s:11:1-11 -in=%s:12:1-3 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action fill-in-enum-switch-cases -in=%s:15:3-15 -in=%s:16:1-4 %s | FileCheck --check-prefix=CHECK2 %s
+
+// Ensure that the action can't be initiated in other places:
+
+// RUN: not clang-refactor-test initiate -action fill-in-enum-switch-cases -in=%s:8:1-32 -in=%s:9:1-2 -in=%s:13:1-77 -in=%s:15:1-2 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// CHECK-NO: Failed to initiate the refactoring action
+
+void dontInitiate(Color c, int i) {
+  switch (c) {
+  case Black:
+    break;
+  case Blue:
+    break;
+  case White:
+    break;
+  case Gold:
+    break;
+  }
+
+  switch (i) {
+  case 0:
+    break;
+  }
+
+  switch ((int)c) {
+  case 0:
+    break;
+  }
+}
+
+// Ensure that the action can't be initiated on switches that have all cases or
+// that don't work with an enum.
+
+// RUN: not clang-refactor-test initiate -action fill-in-enum-switch-cases -in=%s:34:3-15 %s 2>&1 | FileCheck --check-prefix=CHECK-ALL-COVERED %s
+// CHECK-ALL-COVERED: Failed to initiate the refactoring action (All enum cases are already covered)!
+// RUN: not clang-refactor-test initiate -action fill-in-enum-switch-cases -in=%s:45:3-15 -in=%s:50:3-20 %s 2>&1 | FileCheck --check-prefix=CHECK-NOT-ENUM %s
+// CHECK-NOT-ENUM: Failed to initiate the refactoring action (The switch doesn't operate on an enum)!
+
+void initiateWithDefault(Color c, int i) {
+  switch (c) {
+  case Black:
+    break;
+  default:
+    break;
+  }
+// CHECK3: Initiated the 'fill-in-enum-switch-cases' action at [[@LINE-6]]:3
+
+  switch (c) {
+  default:
+    break;
+  }
+// CHECK4: Initiated the 'fill-in-enum-switch-cases' action at [[@LINE-4]]:3
+}
+
+// RUN: clang-refactor-test initiate -action fill-in-enum-switch-cases -at=%s:65:3 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action fill-in-enum-switch-cases -at=%s:73:3 %s | FileCheck --check-prefix=CHECK4 %s
+
+enum class Shape {
+  Rectangle,
+  Circle,
+  Octagon
+};
+
+typedef enum {
+  Anon1,
+  Anon2
+} AnonymousEnum;
+
+void initiateEnumClass(Shape shape, AnonymousEnum anon) {
+  switch (shape) {
+  }
+// CHECK5: Initiated the 'fill-in-enum-switch-cases' action at [[@LINE-2]]:3
+  switch (anon) {
+  }
+// CHECK6: Initiated the 'fill-in-enum-switch-cases' action at [[@LINE-2]]:3
+}
+
+// RUN: clang-refactor-test initiate -action fill-in-enum-switch-cases -at=%s:95:3 %s -std=c++11 | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test initiate -action fill-in-enum-switch-cases -at=%s:98:3 %s | FileCheck --check-prefix=CHECK6 %s
+
+// Ensure that the operation can be initiated from a selection:
+
+// RUN: clang-refactor-test initiate -action fill-in-enum-switch-cases -selected=%s:9:3-12:4 -selected=%s:9:15-12:3 -selected=%s:9:15-12:3 -selected=%s:10:3-11:10  %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action fill-in-enum-switch-cases -selected=%s:15:3-16:4  %s | FileCheck --check-prefix=CHECK2 %s
+
+void dontInitiateSelectedBody(Shape shape) {
+  switch (shape) {
+  case Shape::Rectangle: {
+    break;
+  }
+  case Shape::Circle:
+    break;
+  }
+}
+
+// RUN: not clang-refactor-test initiate -action fill-in-enum-switch-cases -selected=%s:114:5-114:11 -selected=%s:117:5-117:10 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+enum IncompleteEnum : int;
+enum class IncompleteClassEnum : short;
+enum class IncompleteClassEnum2;
+void dontInitiateOnIncompleteEnum(IncompleteEnum e1, IncompleteClassEnum e2, IncompleteClassEnum2 e3) {
+  switch (e1) {
+  }
+  switch (e1) {
+  case 0:
+    break;
+  }
+  switch (e2) {
+  }
+  switch (e2) {
+  case (IncompleteClassEnum)0:
+    break;
+  }
+  switch (e3) {
+  }
+}
+
+// RUN: not clang-refactor-test initiate -action fill-in-enum-switch-cases -at=%s:127:3 -at=%s:129:3 -at=%s:133:3 -at=%s:135:3 -at=%s:139:3 %s -std=c++11 2>&1 | FileCheck --check-prefix=CHECK-NOT-COMPLETE %s
+// CHECK-NOT-COMPLETE: Failed to initiate the refactoring action (The enum type is incomplete)!
+
+void initiateWhenSelectionIsPartial() {
+  int partiallySelected = 0;
+}
+int global = 0;
+// RUN: not clang-refactor-test initiate -action fill-in-enum-switch-cases -selected=%s:147:1-150:1 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
diff --git a/test/Refactor/FillInEnumSwitchCases/fill-in-cases-neatly-ordered.cpp b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-neatly-ordered.cpp
new file mode 100644
index 0000000..97118ec
--- /dev/null
+++ b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-neatly-ordered.cpp
@@ -0,0 +1,157 @@
+
+enum Color {
+  Black,
+  Blue,
+  White,
+  Gold
+};
+
+void placeBeforeDefault(Color c) {
+  switch (c) {
+  case Black:
+    break;
+  case Blue:
+    break;
+  default:
+    break;
+  }
+// CHECK1: "case White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-3]]:3 -> [[@LINE-3]]:3
+
+  switch (c) {
+  default:
+    break;
+  }
+// CHECK1: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-3]]:3 -> [[@LINE-3]]:3
+}
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:10:3 -at=%s:20:3 %s | FileCheck --check-prefix=CHECK1 %s
+
+void dontPlaceBeforeDefault(Color c) {
+  switch (c) {
+  default:
+    break;
+  case Black:
+    break;
+  case Blue:
+    break;
+  }
+// CHECK2: "case White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+
+  switch (c) {
+  case Black:
+    break;
+  default:
+    break;
+  case Blue:
+    break;
+  }
+// CHECK2: "case White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+}
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:30:3 -at=%s:40:3 %s | FileCheck --check-prefix=CHECK2 %s
+
+void insertAtProperPlaces(Color c) {
+  switch (c) {
+  case Black:
+    break;
+  case White:
+    break;
+#ifdef USEDEFAULT
+  default:
+    break;
+#endif
+  }
+// CHECK3: "case Blue:\n<#code#>\nbreak;\n" [[@LINE-7]]:3 -> [[@LINE-7]]:3
+// CHECK3-NEXT: "case Gold:\n<#code#>\nbreak;\n" [[@LINE-2]]:3 -> [[@LINE-2]]:3
+// CHECK4: "case Blue:\n<#code#>\nbreak;\n" [[@LINE-9]]:3 -> [[@LINE-9]]:3
+// CHECK4-NEXT: "case Gold:\n<#code#>\nbreak;\n" [[@LINE-7]]:3 -> [[@LINE-7]]:3
+
+  switch (c) {
+  case White:
+    break;
+#ifdef USEDEFAULT
+  default:
+    break;
+#endif
+  }
+// CHECK3: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\n" [[@LINE-7]]:3 -> [[@LINE-7]]:3
+// CHECK3-NEXT: "case Gold:\n<#code#>\nbreak;\n" [[@LINE-2]]:3 -> [[@LINE-2]]:3
+// CHECK4: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\n" [[@LINE-9]]:3 -> [[@LINE-9]]:3
+// CHECK4-NEXT: "case Gold:\n<#code#>\nbreak;\n" [[@LINE-7]]:3 -> [[@LINE-7]]:3
+
+  switch (c) {
+  case Gold:
+    break;
+#ifdef USEDEFAULT
+  default:
+    break;
+#endif
+  }
+// CHECK3: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\n" [[@LINE-7]]:3 -> [[@LINE-7]]:3
+// CHECK4: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\n" [[@LINE-8]]:3 -> [[@LINE-8]]:3
+
+  switch (c) {
+  case Blue:
+    break;
+#ifdef USEDEFAULT
+  default:
+    break;
+#endif
+  }
+// CHECK3: "case Black:\n<#code#>\nbreak;\n" [[@LINE-7]]:3 -> [[@LINE-7]]:3
+// CHECK3-NEXT: "case White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-2]]:3 -> [[@LINE-2]]:3
+// CHECK4: "case Black:\n<#code#>\nbreak;\n" [[@LINE-9]]:3 -> [[@LINE-9]]:3
+// CHECK4-NEXT: "case White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-7]]:3 -> [[@LINE-7]]:3
+
+  switch (c) {
+  case White:
+    break;
+  case Gold:
+    break;
+#ifdef USEDEFAULT
+  default:
+    break;
+#endif
+  }
+// CHECK3: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\n" [[@LINE-9]]:3 -> [[@LINE-9]]:3
+// CHECK4: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\n" [[@LINE-10]]:3 -> [[@LINE-10]]:3
+}
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:54:3 -at=%s:69:3 -at=%s:82:3 -at=%s:93:3 -at=%s:106:3 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:54:3 -at=%s:69:3 -at=%s:82:3 -at=%s:93:3 -at=%s:106:3 %s -D USEDEFAULT | FileCheck --check-prefix=CHECK4 %s
+
+void insertAtEndIfOrderingIsUncertain(Color c) {
+  switch (c) {
+  case Gold:
+    break;
+  case White:
+    break;
+  }
+// CHECK5: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+
+  switch (c) {
+  case Blue:
+    break;
+  case Black:
+    break;
+  }
+// CHECK5: "case White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+
+  switch (c) {
+  case White:
+    break;
+  case Black:
+    break;
+  }
+// CHECK5: "case Blue:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+
+  switch (c) {
+  case Gold:
+    break;
+  case Blue:
+    break;
+  }
+// CHECK5: "case Black:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+}
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:124:3 -at=%s:132:3 -at=%s:140:3 -at=%s:148:3 %s | FileCheck --check-prefix=CHECK5 %s
diff --git a/test/Refactor/FillInEnumSwitchCases/fill-in-cases-opaque-decl.cpp b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-opaque-decl.cpp
new file mode 100644
index 0000000..c1a4040
--- /dev/null
+++ b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-opaque-decl.cpp
@@ -0,0 +1,33 @@
+enum IncompleteEnum : int;
+
+enum IncompleteEnum : int {
+  A, B
+};
+
+enum class IncompleteClassEnum : short;
+
+enum class IncompleteClassEnum : short {
+  B, C
+};
+
+enum class IncompleteClassEnum2;
+
+enum class IncompleteClassEnum2 {
+  D, E
+};
+
+void dontInitiateOnIncompleteEnum(IncompleteEnum e1, IncompleteClassEnum e2, IncompleteClassEnum2 e3) {
+  switch (e1) {
+  }
+// CHECK: "case A:\n<#code#>\nbreak;\ncase B:\n<#code#>\nbreak;\n" [[@LINE-1]]:3
+
+  switch (e2) {
+  }
+// CHECK: "case IncompleteClassEnum::B:\n<#code#>\nbreak;\ncase IncompleteClassEnum::C:\n<#code#>\nbreak;\n" [[@LINE-1]]:3
+
+  switch (e3) {
+  }
+// CHECK: "case IncompleteClassEnum2::D:\n<#code#>\nbreak;\ncase IncompleteClassEnum2::E:\n<#code#>\nbreak;\n" [[@LINE-1]]:3
+}
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:20:3 -at=%s:24:3 -at=%s:28:3 %s -std=c++11 | FileCheck %s
diff --git a/test/Refactor/FillInEnumSwitchCases/fill-in-cases-perform.cpp b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-perform.cpp
new file mode 100644
index 0000000..70aa585
--- /dev/null
+++ b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-perform.cpp
@@ -0,0 +1,93 @@
+#ifdef NESTEDANON
+namespace {
+#endif
+#ifdef NESTED1
+namespace foo {
+struct Struct {
+#endif
+
+#ifdef ENUMCLASS
+enum class Color {
+#else
+enum Color {
+#endif
+  Black,
+  Blue,
+  White,
+  Gold
+};
+
+#ifdef NESTED1
+#define PREFIX foo::Struct::
+#else
+#define PREFIX
+#endif
+
+#ifdef ENUMCLASS
+#define CASE(x) PREFIX Color::x
+#else
+#define CASE(x) PREFIX x
+#endif
+
+#ifdef NESTED1
+}
+#ifndef NESTED1NS
+}
+#endif
+#endif
+#ifdef NESTEDANON
+}
+#endif
+
+void perform1(PREFIX Color c) {
+  switch (c) {
+  case CASE(Black):
+    break;
+  }
+// CHECK1: "case Blue:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+// CHECK2: "case Color::Blue:\n<#code#>\nbreak;\ncase Color::White:\n<#code#>\nbreak;\ncase Color::Gold:\n<#code#>\nbreak;\n" [[@LINE-2]]:3 -> [[@LINE-2]]:3
+// CHECK3: "case foo::Struct::Blue:\n<#code#>\nbreak;\ncase foo::Struct::White:\n<#code#>\nbreak;\ncase foo::Struct::Gold:\n<#code#>\nbreak;\n" [[@LINE-3]]:3 -> [[@LINE-3]]:3
+// CHECK4: "case foo::Struct::Color::Blue:\n<#code#>\nbreak;\ncase foo::Struct::Color::White:\n<#code#>\nbreak;\ncase foo::Struct::Color::Gold:\n<#code#>\nbreak;\n" [[@LINE-4]]:3 -> [[@LINE-4]]:3
+// CHECK5: "case Struct::Blue:\n<#code#>\nbreak;\ncase Struct::White:\n<#code#>\nbreak;\ncase Struct::Gold:\n<#code#>\nbreak;\n" [[@LINE-5]]:3 -> [[@LINE-5]]:3
+// CHECK6: "case Struct::Color::Blue:\n<#code#>\nbreak;\ncase Struct::Color::White:\n<#code#>\nbreak;\ncase Struct::Color::Gold:\n<#code#>\nbreak;\n" [[@LINE-6]]:3 -> [[@LINE-6]]:3
+
+  switch (c) {
+  case CASE(Black):
+    break;
+  case (Color)1: // Blue
+    break;
+  }
+// CHECK1: "case White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+// CHECK2: "case Color::White:\n<#code#>\nbreak;\ncase Color::Gold:\n<#code#>\nbreak;\n" [[@LINE-2]]:3 -> [[@LINE-2]]:3
+
+  switch (c) {
+  }
+// CHECK1: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+// CHECK2: "case Color::Black:\n<#code#>\nbreak;\ncase Color::Blue:\n<#code#>\nbreak;\ncase Color::White:\n<#code#>\nbreak;\ncase Color::Gold:\n<#code#>\nbreak;\n" [[@LINE-2]]:3 -> [[@LINE-2]]:3
+}
+
+#ifdef NESTED1NS
+}
+#endif
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:43:3 -at=%s:54:3 -at=%s:63:3 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:43:3 -at=%s:54:3 -at=%s:63:3 %s -std=c++11 -D ENUMCLASS | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:43:3 %s -std=c++11 -D NESTED1 | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:43:3 %s -std=c++11 -D NESTED1 -D ENUMCLASS | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:43:3 %s -std=c++11 -D NESTED1 -D NESTED1NS | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:43:3 %s -std=c++11 -D NESTED1 -D NESTED1NS -D ENUMCLASS | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:43:3 -at=%s:54:3 -at=%s:63:3 %s -std=c++11 -D NESTEDANON | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:43:3 -at=%s:54:3 -at=%s:63:3 %s -std=c++11 -D NESTEDANON -D ENUMCLASS | FileCheck --check-prefix=CHECK2 %s
+
+#define MACROARG(X) X
+
+void macroArg(PREFIX Color c) {
+  // macro-arg: +2:12
+  // macro-arg-range-begin: +1:12
+  MACROARG(switch (c) {
+  }); // MACRO-ARG: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE]]
+  // macro-arg-range-end: -1:4
+}
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=macro-arg %s | FileCheck --check-prefix=MACRO-ARG %s
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -selected=macro-arg-range %s | FileCheck --check-prefix=MACRO-ARG %s
diff --git a/test/Refactor/FillInEnumSwitchCases/fill-in-cases-wrap-in-compound.cpp b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-wrap-in-compound.cpp
new file mode 100644
index 0000000..3e1f9fe
--- /dev/null
+++ b/test/Refactor/FillInEnumSwitchCases/fill-in-cases-wrap-in-compound.cpp
@@ -0,0 +1,63 @@
+
+enum Color {
+  Black,
+  Blue,
+  White,
+  Gold
+};
+
+// Wrap the inserted case bodies in '{' '}' when the majority of others are
+// wrapped as well.
+void wrapInBraces(Color c) {
+  switch (c) {
+  case Black: {
+    int x = 0;
+    break;
+  }
+  }
+// CHECK1: "case Blue: {\n<#code#>\nbreak;\n}\ncase White: {\n<#code#>\nbreak;\n}\ncase Gold: {\n<#code#>\nbreak;\n}\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+
+  switch (c) {
+  case Black: {
+    int x = 0;
+    break;
+  }
+  case Blue: {
+    int y = 0;
+    break;
+  }
+  }
+// CHECK1: "case White: {\n<#code#>\nbreak;\n}\ncase Gold: {\n<#code#>\nbreak;\n}\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+}
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:12:3 -at=%s:20:3 %s | FileCheck --check-prefix=CHECK1 %s
+
+void dontWrapInBraces(Color c) {
+  switch (c) {
+  case Black: {
+    int x = 0;
+    break;
+  }
+  case Blue:
+    break;
+  }
+// CHECK2: "case White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+
+  switch (c) {
+  case Black: {
+    int x = 0;
+    break;
+  }
+  case Blue:
+    break;
+  case White:
+    break;
+  }
+// CHECK2: "case Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+
+  switch (c) {
+  }
+// CHECK2: "case Black:\n<#code#>\nbreak;\ncase Blue:\n<#code#>\nbreak;\ncase White:\n<#code#>\nbreak;\ncase Gold:\n<#code#>\nbreak;\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+}
+
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=%s:36:3 -at=%s:46:3 -at=%s:58:3 %s | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/FillInEnumSwitchCases/initiate-on-enum-constant.c b/test/Refactor/FillInEnumSwitchCases/initiate-on-enum-constant.c
new file mode 100644
index 0000000..891b4bf
--- /dev/null
+++ b/test/Refactor/FillInEnumSwitchCases/initiate-on-enum-constant.c
@@ -0,0 +1,12 @@
+// RUN: clang-refactor-test perform -action fill-in-enum-switch-cases -at=enum-c %s | FileCheck %s
+
+enum Enum {
+  Enum_a,
+  Enum_b,
+};
+void testEnumConstantInCWithIntType() {
+// enum-c: +1:1
+switch (Enum_a) {
+case Enum_a: break;
+} // CHECK: "case Enum_b:\n<#code#>\nbreak;\n" [[@LINE]]:1 -> [[@LINE]]:1
+}
diff --git a/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-initiate.cpp b/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-initiate.cpp
new file mode 100644
index 0000000..7990cc5
--- /dev/null
+++ b/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-initiate.cpp
@@ -0,0 +1,68 @@
+struct AbstractClass {
+  virtual void method() = 0;
+  virtual void otherMethod() { }
+};
+
+struct Base {
+  virtual void nonAbstractClassMethod() { }
+};
+
+struct Target : Base, AbstractClass {
+  int field = 0;
+
+  union SubRecord {
+  };
+
+  void outerMethod() const;
+
+  void innerMethod() {
+    int x = 0;
+  }
+};
+// CHECK1: Initiated the 'fill-in-missing-abstract-methods' action at [[@LINE-12]]:1
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-abstract-methods -in=%s:10:1-end -in=%s:11:1-end -in=%s:12:1-end -in=%s:13:1-2 -in=%s:15:1-end -in=%s:16:1-2 -in=%s:17:1-end -in=%s:18:1-2 -in=%s:21:1-2 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-abstract-methods -in=%s:13:3-end -in=%s:14:1-2 -in=%s:16:3-27 -in=%s:18:3-end -in=%s:19:1-end -in=%s:20:1-3 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// CHECK-NO: Failed to initiate the refactoring action
+
+// RUN: clang-refactor-test list-actions -at=%s:10:1 %s | FileCheck --check-prefix=CHECK-ACTION %s
+// CHECK-ACTION: Add Missing Abstract Class Overrides
+
+
+void Target::outerMethod() const {
+}
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-abstract-methods -in=%s:33:1-end -in=%s:34:1-end %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+struct FinalTarget final : AbstractClass {
+};
+// CHECK2: Initiated the 'fill-in-missing-abstract-methods' action at [[@LINE-2]]:1
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-abstract-methods -in=%s:38:1-end -in=%s:39:1-2 %s | FileCheck --check-prefix=CHECK2 %s
+
+union Union { };
+// RUN: not clang-refactor-test initiate -action fill-in-missing-abstract-methods -in=%s:44:1-end %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+class NoAbstractParents : Base { };
+// RUN: not clang-refactor-test initiate -action fill-in-missing-abstract-methods -in=%s:47:1-35 %s 2>&1 | FileCheck --check-prefix=CHECK-NO-ABSTRACT-BASE %s
+// CHECK-NO-ABSTRACT-BASE: Failed to initiate the refactoring action (The class has no abstract bases)
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-abstract-methods -in=%s:1:1-end -in=%s:6:1-end %s 2>&1 | FileCheck --check-prefix=CHECK-NO-ABSTRACT-BASE %s
+
+// Check selection:
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-abstract-methods -selected=%s:10:1-21:2 -selected=%s:12:1-16:10 -selected=%s:11:1-20:2 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-abstract-methods -selected=%s:13:3-14:4 -selected=%s:16:3-16:27 -selected=%s:18:3-20:4 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+struct HasAllMethods: AbstractClass {
+   virtual void method() override { }
+};
+// RUN: not clang-refactor-test initiate -action fill-in-missing-abstract-methods -at=%s:58:1 %s 2>&1 | FileCheck --check-prefix=CHECK-NO-MISSING-METHODS %s
+// CHECK-NO-MISSING-METHODS: Failed to initiate the refactoring action (The class has no missing abstract class methods)
+
+// Shouldn't crash:
+// forward-decl: +1:1
+struct ForwardDecl;
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-abstract-methods -at=forward-decl %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
diff --git a/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-no-attributes.cpp b/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-no-attributes.cpp
new file mode 100644
index 0000000..e9f4404
--- /dev/null
+++ b/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-no-attributes.cpp
@@ -0,0 +1,10 @@
+
+struct AbstractClass {
+  __attribute__((annotate("test")))
+  virtual void pureMethod() = 0;
+};
+
+struct Target : AbstractClass {
+};
+// CHECK1: "void pureMethod() override;\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:7:1 %s | FileCheck --check-prefix=CHECK1 %s
diff --git a/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-perform.cpp b/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-perform.cpp
new file mode 100644
index 0000000..8ae223b
--- /dev/null
+++ b/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-perform.cpp
@@ -0,0 +1,126 @@
+template <typename T>
+struct Generic {  T x; };
+
+struct AbstractClass {
+  virtual void pureMethod() = 0;
+  virtual void aPureMethod(int (*fptr)(), Generic<int> y) = 0;
+  virtual int anotherPureMethod(const int &x) const = 0;
+  virtual int operator + (int) const = 0;
+  virtual void otherMethod() { }
+};
+
+struct Base {
+  virtual void nonAbstractClassMethod() { }
+};
+
+struct Target : Base, AbstractClass {
+};
+// CHECK1: "void pureMethod() override;\n\nvoid aPureMethod(int (*fptr)(), Generic<int> y) override;\n\nint anotherPureMethod(const int &x) const override;\n\nint operator+(int) const override;\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:16:1 %s | FileCheck --check-prefix=CHECK1 %s
+
+struct SubTarget : AbstractClass {
+  int anotherPureMethod(const int &) const { return 0; }
+#ifdef HAS_OP
+  int operator + (int) const override { return 2; }
+#endif
+};
+
+struct Target2 : SubTarget, Base {
+};
+// CHECK2: "void pureMethod() override;\n\nvoid aPureMethod(int (*fptr)(), Generic<int> y) override;\n\nint operator+(int) const override;\n\n" [[@LINE-1]]:1
+// CHECK3: "void pureMethod() override;\n\nvoid aPureMethod(int (*fptr)(), Generic<int> y) override;\n\n" [[@LINE-2]]:1
+
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:29:1 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:29:1 %s -DHAS_OP | FileCheck --check-prefix=CHECK3 %s
+
+struct Abstract2 {
+  virtual void firstMethod(int x, int y) = 0;
+  virtual void secondMethod(int, int) { }
+  virtual void thirdMethod(int a) = 0;
+  virtual void fourthMethod() = 0;
+};
+
+struct FillInGoodLocations : Base, Abstract2 {
+
+  void secondMethod(int, int) override; // comment
+
+  void unrelatedMethod();
+
+};
+// CHECK4: "\n\nvoid firstMethod(int x, int y) override;\n\nvoid thirdMethod(int a) override;\n\nvoid fourthMethod() override;\n" [[@LINE-5]]:51 -> [[@LINE-5]]:51
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:44:1 %s | FileCheck --check-prefix=CHECK4 %s
+
+struct FillInGoodLocations2 : FillInGoodLocations, AbstractClass {
+
+  void fourthMethod() override;
+
+  // comment
+  void unrelatedMethod();
+
+  int operator + (int) const override;
+};
+// CHECK5: "\n\nvoid firstMethod(int x, int y) override;\n\nvoid thirdMethod(int a) override;\n" [[@LINE-7]]:32 -> [[@LINE-7]]:32
+// CHECK5-NEXT: "\n\nvoid pureMethod() override;\n\nvoid aPureMethod(int (*fptr)(), Generic<int> y) override;\n\nint anotherPureMethod(const int &x) const override;\n" [[@LINE-3]]:39 -> [[@LINE-3]]:39
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:54:1 %s | FileCheck --check-prefix=CHECK5 %s
+
+struct FillInGoodLocations3 : Base, AbstractClass, Abstract2 {
+
+  // comment
+  void unrelatedMethod();
+
+  void thirdMethod(int a) override;
+
+  void firstMethod(int x, int y) override;
+
+};
+// CHECK6: "\n\nvoid fourthMethod() override;\n" [[@LINE-3]]:43 -> [[@LINE-3]]:43
+// CHECK6-NEXT: "void pureMethod() override;\n\nvoid aPureMethod(int (*fptr)(), Generic<int> y) override;\n\nint anotherPureMethod(const int &x) const override;\n\nint operator+(int) const override;\n\n" [[@LINE-2]]:1 -> [[@LINE-2]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:67:1 %s | FileCheck --check-prefix=CHECK6 %s
+
+struct FIllInGoodLocationsWithMacros : Abstract2 {
+#define METHOD(decl) void decl override;
+
+  METHOD(thirdMethod(int a))
+  METHOD(firstMethod(int x, int y)) void foo();
+};
+// CHECK7: "\n\nvoid fourthMethod() override;\n" [[@LINE-2]]:36 -> [[@LINE-2]]:36
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:81:1 %s | FileCheck --check-prefix=CHECK7 %s
+
+template<typename T>
+class GenericType : Abstract2 {
+
+};
+// CHECK8: "void firstMethod(int x, int y) override;\n\nvoid thirdMethod(int a) override;\n\nvoid fourthMethod() override;\n\n" [[@LINE-1]]:1
+
+struct GenericSubType : GenericType<int> {
+
+};
+// CHECK8: "void firstMethod(int x, int y) override;\n\nvoid thirdMethod(int a) override;\n\nvoid fourthMethod() override;\n\n" [[@LINE-1]]:1
+
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:91:1 -at=%s:96:1 %s | FileCheck --check-prefix=CHECK8 %s
+
+
+struct BaseClass2
+{
+    virtual ~BaseClass2();
+    virtual int load() = 0;
+};
+
+// correct-implicit-destructor-placement: +1:1
+struct DerivedImplicitDestructorClass2
+: public BaseClass2
+{
+
+}; // CHECK-DESTRUCTOR: "int load() override;\n\n" [[@LINE]]:1
+
+// Don't insert methods after the destructor:
+// correct-destructor-placement: +1:1
+struct DerivedExplicitDestructorClass2
+: public BaseClass2 {
+  ~DerivedImplicitDestructorClass2();
+
+
+}; // CHECK-DESTRUCTOR: "int load() override;\n\n" [[@LINE]]:1
+
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=correct-implicit-destructor-placement -at=correct-destructor-placement %s | FileCheck --check-prefix=CHECK-DESTRUCTOR %s
diff --git a/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-with-bodies.cpp b/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-with-bodies.cpp
new file mode 100644
index 0000000..2318a56
--- /dev/null
+++ b/test/Refactor/FillInMissingMethodStubsFromAbstractClasses/fill-in-missing-abstract-methods-with-bodies.cpp
@@ -0,0 +1,50 @@
+
+struct AbstractClass {
+  virtual void pureMethod() = 0;
+};
+
+#ifdef HAS_BODY
+  #define BODY { }
+#else
+  #define BODY ;
+#endif
+
+struct Target1 : AbstractClass {
+  void method1() BODY
+};
+// CHECK1: "void pureMethod() override;\n\n" [[@LINE-1]]:1
+// CHECK2: "void pureMethod() override { \n  <#code#>\n}\n\n" [[@LINE-2]]:1
+
+struct Target2 : AbstractClass {
+  void method1() BODY
+  void method2() BODY
+};
+// CHECK1: "void pureMethod() override;\n\n" [[@LINE-1]]:1
+// CHECK2: "void pureMethod() override { \n  <#code#>\n}\n\n" [[@LINE-2]]:1
+
+struct Target2_1 : AbstractClass {
+  void method1() BODY
+  void method2();
+};
+// CHECK1: "void pureMethod() override;\n\n" [[@LINE-1]]:1
+// CHECK2: "void pureMethod() override;\n\n" [[@LINE-2]]:1
+
+struct Target3 : AbstractClass {
+  void method1() BODY
+  void method2() BODY
+  void method3() BODY
+};
+// CHECK1: "void pureMethod() override;\n\n" [[@LINE-1]]:1
+// CHECK2: "void pureMethod() override { \n  <#code#>\n}\n\n" [[@LINE-2]]:1
+
+struct Target4 : AbstractClass {
+  void method1() BODY
+  void method2() BODY
+  void method3() BODY
+  void method4() BODY
+};
+// CHECK1: "void pureMethod() override;\n\n" [[@LINE-1]]:1
+// CHECK2: "void pureMethod() override { \n  <#code#>\n}\n\n" [[@LINE-2]]:1
+
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:12:1 -at=%s:18:1 -at=%s:25:1 -at=%s:32:1 -at=%s:40:1 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action fill-in-missing-abstract-methods -at=%s:12:1 -at=%s:18:1 -at=%s:25:1 -at=%s:32:1 -at=%s:40:1 %s -DHAS_BODY | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate-class-extension.m b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate-class-extension.m
new file mode 100644
index 0000000..ae785bc
--- /dev/null
+++ b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate-class-extension.m
@@ -0,0 +1,51 @@
+@protocol Proto
+
+@required
+-(void)method:(int)x;
+
+@end
+
+@protocol Proto2
+
+@required
+- (void)method2:(int)y;
+
+@end
+
+@interface Base
+@end
+
+// Initiate the action from extension if the @implementation is in the same TU.
+@interface WithExtension: Base<Proto>
+@end
+@interface WithExtension()
+@end
+@interface WithExtension() <Proto2>
+@end
+@implementation WithExtension
+// CHECK1: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-1]]:1
+@end
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:21:1-27 -in=%s:22:1-5 -in=%s:23:1-36 %s | FileCheck --check-prefix=CHECK1 %s
+
+@interface WithoutImplementation: Base<Proto>
+@end
+@interface WithoutImplementation()
+@end
+@interface WithoutImplementation() <Proto2>
+@end
+// CHECK-NO-IMPL: Failed to initiate the refactoring action (Class extension without suitable @implementation)!
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:32:1 -at=%s:34:1 %s 2>&1 | FileCheck --check-prefix=CHECK-NO-IMPL %s
+
+// Initiate from the implementation even when the class has no protocols, but
+// its extension does.
+
+@interface NoProtocols: Base
+@end
+@interface NoProtocols() <Proto2>
+@end
+@implementation NoProtocols
+@end
+// CHECK2: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-2]]:1
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:44:1 -at=%s:46:1 %s | FileCheck --check-prefix=CHECK2 %s
+// CHECK-NO-EXT-FROM-INTERFACE: Failed to initiate the refactoring action!
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:42:1 %s 2>&1 | FileCheck --check-prefix=CHECK-NO-EXT-FROM-INTERFACE %s
diff --git a/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate-required-only.m b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate-required-only.m
new file mode 100644
index 0000000..249e273
--- /dev/null
+++ b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate-required-only.m
@@ -0,0 +1,146 @@
+@protocol Proto
+
+#ifndef NO_REQUIRED
+@required
+-(void)ofCourseItisRequired:(int)x;
+#endif
+
+#ifndef NO_NOTHING
+- (void)nothingSpecified:(int)y;
+#endif
+
+#ifndef NO_OPTIONAL
+@optional;
+- (void)justOptional;
+#endif
+
+@end
+
+@protocol Proto2
+
+#ifndef NO_NOTHING
+// Effectively a @required.
+- (void)nothingSpecified2:(int)y;
+#endif
+
+#ifndef NO_REQUIRED
+@required
+-(void)ofCourseItisRequired2:(int)x;
+#endif
+
+#ifndef NO_OPTIONAL
+@optional;
+- (void)justOptional2;
+#endif
+
+@end
+
+@interface Base
+@end
+
+// Initiate in the @interface when the interface has missing @required
+// declarations.
+@interface I1 : Base<Proto>
+// CHECK1: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-1]]:1
+#ifdef DEF_REQUIRED
+-(void)ofCourseItisRequired:(int)x;
+#endif
+#ifdef DEF_NOTHING
+- (void)nothingSpecified:(int)y;
+#endif
+#ifdef DEF_OPTIONAL
+- (void)justOptional;
+#endif
+@end
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:43:1 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:43:1 %s -DNO_REQUIRED -DNO_OPTIONAL | FileCheck --check-prefix=CHECK1 %s
+// CHECK-NO: Failed to initiate the refactoring action (All of the @required methods are there)!
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:43:1 %s -DNO_REQUIRED -DNO_NOTHING -DNO_OPTIONAL 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:43:1 %s -DNO_REQUIRED -DNO_NOTHING 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:43:1 %s -DDEF_REQUIRED | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:43:1 %s -DDEF_NOTHING | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:43:1 %s -DDEF_OPTIONAL | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:43:1 %s -DDEF_REQUIRED -DDEF_NOTHING 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+@interface I1(Category) <Proto2>
+// CHECK2: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-1]]:1
+#ifdef DEF_REQUIRED
+-(void)ofCourseItisRequired2:(int)x;
+#endif
+#ifdef DEF_NOTHING
+- (void)nothingSpecified2:(int)y;
+#endif
+#ifdef DEF_OPTIONAL
+- (void)justOptional2;
+#endif
+@end
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:67:1 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:67:1 %s -DNO_REQUIRED -DNO_OPTIONAL | FileCheck --check-prefix=CHECK2 %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:67:1 %s -DNO_REQUIRED -DNO_NOTHING -DNO_OPTIONAL 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:67:1 %s -DNO_REQUIRED -DNO_NOTHING 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:67:1 %s -DDEF_REQUIRED | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:67:1 %s -DDEF_NOTHING | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:67:1 %s -DDEF_OPTIONAL | FileCheck --check-prefix=CHECK2 %s
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:67:1 %s -DDEF_REQUIRED -DDEF_NOTHING 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// Initiate in the @implementatino when the implementation has missing @required
+// methods.
+@implementation I1
+// CHECK3: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-1]]:1
+#ifdef IMPL_REQUIRED
+-(void)ofCourseItisRequired:(int)x { }
+#endif
+#ifdef IMPL_NOTHING
+- (void)nothingSpecified:(int)y { }
+#endif
+#ifdef IMPL_OPTIONAL
+- (void)justOptional { }
+#endif
+@end
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DNO_REQUIRED -DNO_OPTIONAL | FileCheck --check-prefix=CHECK3 %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DNO_REQUIRED -DNO_NOTHING -DNO_OPTIONAL 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DNO_REQUIRED -DNO_NOTHING 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DIMPL_REQUIRED | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DIMPL_NOTHING | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DIMPL_OPTIONAL | FileCheck --check-prefix=CHECK3 %s
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DIMPL_REQUIRED -DIMPL_NOTHING 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DDEF_REQUIRED -DDEF_NOTHING -DDEF_OPTIONAL | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DIMPL_REQUIRED -DDEF_REQUIRED -DDEF_NOTHING | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DIMPL_NOTHING -DDEF_REQUIRED -DDEF_NOTHING | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:92:1 %s -DIMPL_OPTIONAL -DDEF_REQUIRED -DDEF_NOTHING -DDEF_OPTIONAL | FileCheck --check-prefix=CHECK3 %s
+
+@implementation I1 (Category)
+// CHECK4: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-1]]:1
+#ifdef IMPL_REQUIRED
+-(void)ofCourseItisRequired2:(int)x { }
+#endif
+#ifdef IMPL_NOTHING
+- (void)nothingSpecified2:(int)y { }
+#endif
+#ifdef IMPL_OPTIONAL
+- (void)justOptional2 { }
+#endif
+@end
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DNO_REQUIRED -DNO_OPTIONAL | FileCheck --check-prefix=CHECK4 %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DNO_REQUIRED -DNO_NOTHING -DNO_OPTIONAL 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DNO_REQUIRED -DNO_NOTHING 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DIMPL_REQUIRED | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DIMPL_NOTHING | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DIMPL_OPTIONAL | FileCheck --check-prefix=CHECK4 %s
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DIMPL_REQUIRED -DIMPL_NOTHING 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DDEF_REQUIRED -DDEF_NOTHING -DDEF_OPTIONAL | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DIMPL_REQUIRED -DDEF_REQUIRED -DDEF_NOTHING | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DIMPL_NOTHING -DDEF_REQUIRED -DDEF_NOTHING | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:120:1 %s -DIMPL_OPTIONAL -DDEF_REQUIRED -DDEF_NOTHING -DDEF_OPTIONAL | FileCheck --check-prefix=CHECK4 %s
diff --git a/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate-when-protocoled.m b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate-when-protocoled.m
new file mode 100644
index 0000000..0957f8b
--- /dev/null
+++ b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate-when-protocoled.m
@@ -0,0 +1,97 @@
+@protocol Proto
+
+@required
+-(void)method:(int)x;
+
+@required
+- (void)method2:(int)y;
+
+@end
+
+@interface Base
+@end
+
+// Initiate when @implementation's interface has a suitable protocol.
+@interface I1 : Base<Proto>
+@end
+// CHECK1: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-2]]:1
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:15:1 %s | FileCheck --check-prefix=CHECK1 %s
+
+@implementation I1
+
+@end
+// CHECK2: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-3]]:1
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:20:1 %s | FileCheck --check-prefix=CHECK2 %s
+
+@interface I2 : I1
+
+@end
+// CHECK3: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-3]]:1
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:26:1 %s | FileCheck --check-prefix=CHECK3 %s
+
+@implementation I2
+@end
+// CHECK4: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-2]]:1
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:32:1 %s | FileCheck --check-prefix=CHECK4 %s
+
+// Shouldn't initiate when the @interface is a forward declaration.
+@class ForwardDecl;
+// CHECK-FORWARD: Failed to initiate the refactoring action!
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:38:1-19 %s 2>&1 | FileCheck --check-prefix=CHECK-FORWARD %s
+
+// Shouldn't initiate when the @interface has no protocols:
+
+@interface I3 : Base
+@end
+@implementation I3
+@end
+
+@implementation I4
+@end
+
+// CHECK-CLASS-NO-PROTO: Failed to initiate the refactoring action!
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:11:1-16 -in=%s:12:1-5 -at=%s:44:1 -at=%s:46:1 -at=%s:49:1 %s 2>&1 | FileCheck --check-prefix=CHECK-CLASS-NO-PROTO %s
+
+@protocol Proto2
+
+@required
+-(int)method3;
+
+@end
+
+// Initiate when the category has a suitable protocol:
+@interface I3 (Category) <Proto2>
+// CHECK5: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-1]]:1
+@end
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:63:1 %s | FileCheck --check-prefix=CHECK5 %s
+
+@implementation I3 (Category)
+// CHECK6: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-1]]:1
+@end
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:63:1 %s | FileCheck --check-prefix=CHECK5 %s
+
+@interface I1 (Category) <Proto2>
+// CHECK7: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-1]]:1
+@end
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:63:1 %s | FileCheck --check-prefix=CHECK5 %s
+
+@implementation I1 (Category)
+// CHECK8: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-1]]:1
+@end
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:63:1 %s | FileCheck --check-prefix=CHECK5 %s
+
+// Shouldn't initiate when the category has no protocols (even when the class has them):
+@interface I1 (Category2)
+@end
+
+@implementation I1 (Category2)
+@end
+
+@interface I3 (Category2)
+@end
+
+@implementation I3 (Category2)
+@end
+
+// CHECK-CAT-NO-PROTO: Failed to initiate the refactoring action!
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:84:1 -at=%s:87:1 -at=%s:90:1 -at=%s:93:1 %s 2>&1 | FileCheck --check-prefix=CHECK-CAT-NO-PROTO %s
diff --git a/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate.m b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate.m
new file mode 100644
index 0000000..066d737
--- /dev/null
+++ b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-initiate.m
@@ -0,0 +1,100 @@
+@protocol Proto
+
+@required
+-(void)method:(int)x;
+
+@end
+
+@interface Base
+@end
+
+@interface I : Base<Proto>
+@property int p1;
+@property int p2;
+@end
+
+// Initiate the action within the @implementation
+@implementation I
+
+@dynamic p1;
+@synthesize p2 = _p2;
+
+- (void)anotherMethod {
+  int x = 0;
+}
+
+void function(int x) {
+  int y = x;
+}
+
+@end
+
+// RUN: clang-refactor-test list-actions -at=%s:18:1 %s | FileCheck --check-prefix=CHECK-ACTION %s
+// CHECK-ACTION: Add Missing Protocol Requirements
+
+// Ensure the the action can be initiated in the @implementation / @interface:
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:11:1-27 -in=%s:12:1-18 -in=%s:13:1-18 -in=%s:14:1-5 %s | FileCheck --check-prefix=CHECKI1 %s
+// CHECKI1: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-27]]:1
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:17:1-18 -at=%s:18:1 -in=%s:19:1-13 -in=%s:20:1-22 -at=%s:21:1 -at=%s:25:1 -at=%s:29:1 -in=%s:30:1-5 %s | FileCheck --check-prefix=CHECK1 %s
+// CHECK1: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-23]]:1
+
+// Ensure that the action can't be initiated in other places:
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:1:1-10 -in=%s:4:1-21 -in=%s:6:1-5 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// CHECK-NO: Failed to initiate the refactoring action
+
+// Ensure that the action can't be initiated in methods/functions in @implementation:
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:22:1-24 -in=%s:23:1-13 -in=%s:24:1-2 -in=%s:26:1-23 -in=%s:27:1-13 -in=%s:28:1-2 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+@protocol P2
+
+-(void)method2:(int)y;
+
+@end
+
+@interface I (Category) <P2>
+
+@end
+
+@implementation I (Category)
+
+- (void)anotherMethod2:(int)x {
+  int x = 0;
+}
+
+void aFunction(int x) {
+  int y = x;
+}
+
+@end
+
+// Ensure the the action can be initiated in the category @implementation:
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:57:1-29 -at=%s:58:1 -in=%s:59:1-5 %s | FileCheck --check-prefix=CHECKI2 %s
+// CHECKI2: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-19]]:1
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:61:1-29 -at=%s:62:1 -at=%s:66:1 -at=%s:70:1 -in=%s:71:1-5 %s | FileCheck --check-prefix=CHECK2 %s
+// CHECK2: Initiated the 'fill-in-missing-protocol-stubs' action at [[@LINE-18]]:1
+
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=%s:60:1 -at=%s:72:1 -at=%s:73:1 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -in=%s:63:1-32 -in=%s:64:1-13 -in=%s:65:1-2 -in=%s:67:1-24 -in=%s:68:1-13 -in=%s:69:1-2 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+
+// Check that initiation works with selection as well:
+
+// RUN: clang-refactor-test initiate -action fill-in-missing-protocol-stubs -selected=%s:17:1-30:5 -selected=%s:18:1-29:1 -selected=%s:20:1-20:10 -selected=%s:17:1-23:3 -selected=%s:27:3-30:5 -selected=%s:23:3-27:3 %s | FileCheck --check-prefix=CHECK1 %s
+
+// Not when just one entire method is selected though!
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -selected=%s:22:1-24:2 -selected=%s:26:1-28:2 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// And not when the container is just partially selected!
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -selected=%s:15:1-30:1 -selected=%s:17:1-40:1 -selected=%s:15:1-40:1 -selected=%s:1:1-90:1 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+@class ForwardClass;
+
+// forward-class: +1:1
+@implementation ForwardClass (ForwardClassCategory)
+@end
+// RUN: not clang-refactor-test initiate -action fill-in-missing-protocol-stubs -at=forward-class %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
diff --git a/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-no-attributes.m b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-no-attributes.m
new file mode 100644
index 0000000..d2f3711
--- /dev/null
+++ b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-no-attributes.m
@@ -0,0 +1,28 @@
+@class AClass;
+
+@protocol Protocol
+
+- (void)methodAttribute __attribute__((availability(macos, introduced=10.10)));
+
+- (void)parameterTypeAttribute:(AClass * _Nullable)c;
+
+- (void)parameterTypeAttribute2:(AClass * _Nonnull)c;
+
+- (void)parameterAttribute:(int)p __attribute__((annotate("test")));
+
+@end
+
+@interface Base
+@end
+
+@interface I1 : Base<Protocol>
+
+@end
+// CHECK1: "- (void)methodAttribute;\n\n- (void)parameterAttribute:(int)p;\n\n- (void)parameterTypeAttribute2:(AClass * _Nonnull)c;\n\n- (void)parameterTypeAttribute:(AClass * _Nullable)c;\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+
+@implementation I1
+
+@end
+// CHECK1: "- (void)methodAttribute { \n  <#code#>\n}\n\n- (void)parameterAttribute:(int)p { \n  <#code#>\n}\n\n- (void)parameterTypeAttribute2:(AClass * _Nonnull)c { \n  <#code#>\n}\n\n- (void)parameterTypeAttribute:(AClass * _Nullable)c { \n  <#code#>\n}\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:18:1 -at=%s:23:1 %s | FileCheck --check-prefix=CHECK1 %s
+
diff --git a/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-perform.m b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-perform.m
new file mode 100644
index 0000000..900df30
--- /dev/null
+++ b/test/Refactor/FillInMissingProtocolStubs/fill-in-protocol-stubs-perform.m
@@ -0,0 +1,196 @@
+@protocol Proto1
+
+- (void)requiredInstanceMethod:(int)y;
+
++ (void)aRequiredInstanceMethod:(int (*)(void))function with:(Proto *)p;
+
+@optional;
+- (void)anOptionalMethod;
+
+@end
+
+@protocol Proto2
+
+- (void)a;
+
++ (void)b;
+
+@end
+
+@protocol Proto3
+
+- (void)otherProtocolMethod:(int (^)(id<Proto2>))takesBlock;
+
+@end
+
+@interface Base
+@end
+
+@interface I1 : Base<Proto3>
+
+@end
+// CHECK1: "- (void)otherProtocolMethod:(int (^)(id<Proto2>))takesBlock;\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:29:1 %s | FileCheck --check-prefix=CHECK1 %s
+
+@implementation I1
+
+@end
+// CHECK2: "- (void)otherProtocolMethod:(int (^)(id<Proto2>))takesBlock { \n  <#code#>\n}\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:35:1 %s | FileCheck --check-prefix=CHECK2 %s
+
+@interface I2 : I1<Proto1, Proto2>
+
+@end
+// CHECK3: "+ (void)aRequiredInstanceMethod:(int (*)(void))function with:(id)p;\n\n- (void)requiredInstanceMethod:(int)y;\n\n- (void)a;\n\n+ (void)b;\n\n- (void)otherProtocolMethod:(int (^)(id<Proto2>))takesBlock;\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:41:1 %s | FileCheck --check-prefix=CHECK3 %s
+
+@implementation I2
+
+@end
+// CHECK4: "+ (void)aRequiredInstanceMethod:(int (*)(void))function with:(id)p { \n  <#code#>\n}\n\n- (void)requiredInstanceMethod:(int)y { \n  <#code#>\n}\n\n- (void)a { \n  <#code#>\n}\n\n+ (void)b { \n  <#code#>\n}\n\n- (void)otherProtocolMethod:(int (^)(id<Proto2>))takesBlock { \n  <#code#>\n}\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:47:1 %s | FileCheck --check-prefix=CHECK4 %s
+
+@interface I1(Category) <Proto2>
+@end
+// CHECK5: "- (void)a;\n\n+ (void)b;\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+
+@implementation I1(Category)
+@end
+// CHECK5-NEXT: "- (void)a { \n  <#code#>\n}\n\n+ (void)b { \n  <#code#>\n}\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:53:1 -at=%s:57:1 %s | FileCheck --check-prefix=CHECK5 %s
+
+@interface I3 : I1<Proto1, Proto2>
+
+- (void)requiredInstanceMethod:(int)y;
+
++ (void)b;
+
+#ifdef HAS_OTHER
+- (void) otherProtocolMethod:(int (^)(id<Proto2>))takesBlock;
+#endif
+
+@end
+// CHECK6: "\n\n+ (void)aRequiredInstanceMethod:(int (*)(void))function with:(id)p;\n" [[@LINE-9]]:39 -> [[@LINE-9]]:39
+// CHECK6-NEXT: "\n\n- (void)a;\n" [[@LINE-8]]:11 -> [[@LINE-8]]:11
+// CHECK6-NEXT: "- (void)otherProtocolMethod:(int (^)(id<Proto2>))takesBlock;\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK7: "\n\n+ (void)aRequiredInstanceMethod:(int (*)(void))function with:(id)p;\n" [[@LINE-12]]:39 -> [[@LINE-12]]:39
+// CHECK7-NEXT: "\n\n- (void)a;\n" [[@LINE-11]]:11 -> [[@LINE-11]]:11
+
+@implementation I3
+
+- (void)requiredInstanceMethod:(int)y {
+}
+
++ (void)b {
+}
+
+#ifdef HAS_OTHER
+- (void) otherProtocolMethod:(int (^)(id<Proto2>))takesBlock { }
+#endif
+
+@end
+// CHECK6: "\n\n+ (void)aRequiredInstanceMethod:(int (*)(void))function with:(id)p { \n  <#code#>\n}\n" [[@LINE-10]]:2 -> [[@LINE-10]]:2
+// CHECK6-NEXT: "\n\n- (void)a { \n  <#code#>\n}\n" [[@LINE-8]]:2 -> [[@LINE-8]]:2
+// CHECK6-NEXT: "- (void)otherProtocolMethod:(int (^)(id<Proto2>))takesBlock { \n  <#code#>\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK7: "\n\n+ (void)aRequiredInstanceMethod:(int (*)(void))function with:(id)p { \n  <#code#>\n}\n" [[@LINE-13]]:2 -> [[@LINE-13]]:2
+// CHECK7-NEXT: "\n\n- (void)a { \n  <#code#>\n}\n" [[@LINE-11]]:2 -> [[@LINE-11]]:2
+
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:62:1 -at=%s:79:1 %s | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:62:1 -at=%s:79:1 %s -DHAS_OTHER | FileCheck --check-prefix=CHECK7 %s
+
+@protocol ProtoWith3Methods
+
+- (void)a;
+- (void)b;
+- (void)c;
+
+@end
+
+@interface I4 : Base<ProtoWith3Methods>
+
+#ifndef USE_MACRO
+- (void)b;
+
+- (void)a; // comment
+
+#else
+
+#define METHOD(name) -(void)name;
+
+METHOD(b)
+METHOD(c) - (void)d;
+
+#endif
+
+@end
+// CHECK8: "\n\n- (void)c;\n" [[@LINE-12]]:22 ->  [[@LINE-12]]:22
+// CHECK9: "\n\n- (void)a;\n" [[@LINE-6]]:10 -> [[@LINE-6]]:10
+
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:109:1 %s | FileCheck --check-prefix=CHECK8 %s
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:109:1 %s -D USE_MACRO | FileCheck --check-prefix=CHECK9 %s
+
+@protocol NSObject
+
+- (void)nsObjectMethod;
+
+@end
+
+@protocol SubProto
+
+- (void)sub1;
+- (id<SubProto>)sub2;
+
+@end
+
+@protocol SubProto2 <NSObject>
+
+- (void)sub11;
+
+@end
+
+@protocol SuperProto <SubProto, NSObject, SubProto2>
+
+@optional
+- (void)mySub;
+
+@end
+
+@interface HasSubProtocolMethods: Base <SuperProto, NSObject>
+
+@end
+// CHECK10: "- (void)sub1;\n\n- (id<SubProto>)sub2;\n\n- (void)sub11;\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:158:1 %s | FileCheck --check-prefix=CHECK10 %s
+
+
+
+@interface SuperClassWithSomeDecls : Base<SuperProto>
+
+- (void)sub1;
+
+@end
+
+@interface SubClassOfSuperClassWithSomeDecls : SuperClassWithSomeDecls
+
+#ifdef HAS_SUB1_OVERRIDE
+- (void)sub1;
+#endif
+#ifdef HAS_SUB11
+- (void)sub11;
+#endif
+
+@end
+// CHECK11: "- (id<SubProto>)sub2;\n\n- (void)sub11;\n\n" [[@LINE-1]]:1
+// CHECK12: "\n\n- (id<SubProto>)sub2;\n" [[@LINE-8]]:14
+// CHECK12-NEXT: "- (void)sub11;\n\n" [[@LINE-3]]:1
+// CHECK13: "- (id<SubProto>)sub2;\n\n" [[@LINE-4]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:172:1 %s | FileCheck --check-prefix=CHECK11 %s
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:172:1 %s -DHAS_SUB1_OVERRIDE | FileCheck --check-prefix=CHECK12 %s
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:172:1 %s -DHAS_SUB11 | FileCheck --check-prefix=CHECK13 %s
+
+@implementation SubClassOfSuperClassWithSomeDecls
+
+@end
+// CHECK14: "- (id<SubProto>)sub2 { \n  <#code#>\n}\n\n- (void)sub11 { \n  <#code#>\n}\n\n" [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:190:1 %s | FileCheck --check-prefix=CHECK14 %s
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:190:1 %s -DHAS_SUB1_OVERRIDE | FileCheck --check-prefix=CHECK14 %s
+// RUN: clang-refactor-test perform -action fill-in-missing-protocol-stubs -at=%s:190:1 %s -DHAS_SUB11 | FileCheck --check-prefix=CHECK14 %s
diff --git a/test/Refactor/IfSwitchConversion/if-switch-conversion-initiate.cpp b/test/Refactor/IfSwitchConversion/if-switch-conversion-initiate.cpp
new file mode 100644
index 0000000..e8d0631
--- /dev/null
+++ b/test/Refactor/IfSwitchConversion/if-switch-conversion-initiate.cpp
@@ -0,0 +1,566 @@
+void foo(); void foobar();
+
+void simpleCompoundBodyIf(int x) {
+  foo();
+
+  if (x == 2) {
+    int y = x;
+  } else if (x == 3) {
+    foo();
+  } else {
+    foobar();
+  }
+
+  foobar();
+}
+
+// RUN: clang-refactor-test list-actions -at=%s:6:3 %s | FileCheck --check-prefix=CHECK-ACTION %s
+// CHECK-ACTION: Convert to Switch
+
+// Ensure the the action can be initiated around the ifs:
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -in=%s:6:3-15 -in=%s:8:3-22 -in=%s:10:3-10 %s | FileCheck --check-prefix=CHECK1 %s
+// CHECK1: Initiated the 'if-switch-conversion' action at 6:3
+
+// Ensure that the action can't be initiated when not around the ifs:
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:1:1-10 -in=%s:3:1-18 -in=%s:4:1-9 -in=%s:6:1-2 -in=%s:14:1-12 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// CHECK-NO: Failed to initiate the refactoring action
+// CHECK-NO-NOT: Initiated the 'if-switch-conversion' action
+
+// Ensure that the action can't be initiated inside the ifs:
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:7:1-15 -in=%s:9:1-11 -in=%s:11:1-14 -in=%s:12:1-4 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void nestedIf(int x) {
+  if (x == 2) {
+    if (x == 3) {
+      foo();
+    } else {
+      foo();
+    }
+  } else {
+    foobar();
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -in=%s:35:3-15 -in=%s:35:3-10 %s | FileCheck --check-prefix=CHECK2 %s
+// CHECK2: Initiated the 'if-switch-conversion' action at 35:3
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -in=%s:36:5-17 -in=%s:38:5-12 %s | FileCheck --check-prefix=CHECK3 %s
+// CHECK3: Initiated the 'if-switch-conversion' action at 36:5
+
+
+
+
+
+void simpleFlatBodyIfs(int x) {
+  if (x == 2)
+    foo();
+  else if (x == 3)
+    foo();
+
+  else if (x == 4) foobar();
+
+  else foo();
+
+  if (x == 2)  foobar();
+  else
+    //comment
+    foo();
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -in=%s:57:3-14 -in=%s:59:3-19 -in=%s:62:3-19 -in=%s:64:3-7 %s | FileCheck --check-prefix=CHECK4 %s
+// CHECK4: Initiated the 'if-switch-conversion' action at 57:3
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:57:1-2 -in=%s:58:1-11 -in=%s:59:1-2 -in=%s:60:1-11 -in=%s:61:1-1 -in=%s:62:1-2 -in=%s:62:20-29 -in=%s:63:1-1 -in=%s:64:1-2 -in=%s:64:8-14 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -in=%s:66:3-15 -in=%s:67:3-7 -in=%s:68:1-14 %s | FileCheck --check-prefix=CHECK5 %s
+// CHECK5: Initiated the 'if-switch-conversion' action at 66:3
+
+void differentLineCompoundIf(int x) {
+  if (x == 2)
+  {
+    foo();
+  }
+
+  else if (x == 3)
+
+  {
+    foo();
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -in=%s:81:3-14 -in=%s:86:3-19 -in=%s:87:1-1 %s | FileCheck --check-prefix=CHECK6 %s
+// CHECK6: Initiated the 'if-switch-conversion' action at 81:3
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:81:1-2 -in=%s:82:1-4 -in=%s:84:1-4 -in=%s:85:1-1 -in=%s:86:1-2 -in=%s:88:1-4 -in=%s:90:1-4 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void simpleEmptyIf(int x) {
+  if (x == 1) ;
+  else if (x == 2) ;
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -in=%s:99:3-14 -in=%s:100:3-19 %s | FileCheck --check-prefix=CHECK7 %s
+// CHECK7: Initiated the 'if-switch-conversion' action at 99:3
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:99:15-16 -in=%s:100:20-21 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void sameLineIfElse(int x) {
+  if (x == 1) foo(); else foo();
+  if (x == 2) { foo(); } else if (x == 3) { foo(); }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -in=%s:109:3-14 -in=%s:109:22-26 %s | FileCheck --check-prefix=CHECK8 %s
+// CHECK8: Initiated the 'if-switch-conversion' action at 109:3
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:109:15-21 -in=%s:109:27-33 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -in=%s:110:3-15 -in=%s:110:24-43 %s | FileCheck --check-prefix=CHECK9 %s
+// CHECK9: Initiated the 'if-switch-conversion' action at 110:3
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:110:16-23 -in=%s:110:44-53 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void noIfsWithoutElses(int x) {
+  if (x == 1) {
+    foo();
+  }
+  if (x == 2) ;
+}
+
+// Ifs without any elses shouldn't be allowed:
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:124:1-16 -in=%s:127:1-16 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void noFancyIfs(const int *p) {
+  if (const int *x = p) {
+  }
+  else if (const int *y = p) {
+  }
+
+  if (const int *x = p; *x == 2) {
+  } else if (const int *y = p; *y == 3) {
+  }
+}
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:134:1-26 -in=%s:136:1-31 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -in=%s:139:1-35 -in=%s:140:1-42 %s -std=c++1z 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+void prohibitBreaksCasesDefaults(int x) {
+  while (x != 0) {
+    break;
+    // Allowed:
+    if (x == 1) foo();
+    else foo();
+    // Not allowed:
+    if (x == 2) break;
+    else foo();
+    if (x == 2) { foo(); }
+    else { break; }
+    if (x == 2) { foo(); }
+    else if (x == 1) { if (x == 2) { break; } }
+  }
+  switch (x) {
+  case 1:
+    // Allowed:
+    if (x == 1) foo();
+    else foo();
+    // Not allowed:
+    if (x == 2) foo();
+    else if (x == 3) {
+  case 2:
+      foo();
+    }
+    if (x == 3) foo();
+    else {
+  default:
+      foo();
+    }
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:151:5 %s | FileCheck --check-prefix=CHECK10 %s
+// CHECK10: Initiated the 'if-switch-conversion' action at 151:5
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:154:5 -at=%s:156:5 -at=%s:158:5 %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-STATEMENTS %s
+// CHECK-INVALID-STATEMENTS: Failed to initiate the refactoring action (if's body contains a 'break'/'default'/'case' statement)
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:164:5 %s | FileCheck --check-prefix=CHECK11 %s
+// CHECK11: Initiated the 'if-switch-conversion' action at 164:5
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:167:5 -at=%s:172:5 %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-STATEMENTS %s
+
+#ifdef DISALLOWED
+  #define DISALLOW(x) x
+#else
+  #define DISALLOW(x)
+#endif
+
+void allowBreaksInNestedLoops(int x) {
+  DISALLOW(while (true)) {
+  // Allowed:
+  if (x == 1) {
+    foo();
+  } else if (x == 2) {
+    while (x != 0) {
+      break;
+    }
+    DISALLOW(break;)
+  }
+
+  if (x == 1) {
+    foo();
+  } else {
+    for (int y = 0; y < x; ++y) {
+      break;
+    }
+    DISALLOW(break;)
+  }
+
+  if (x == 1) {
+    do {
+      break;
+    } while (x < 10);
+    DISALLOW(break;)
+  } else {
+    foo();
+  }
+
+  if (x == 1) {
+    do {
+      // nested loop.
+      while (true) {
+      }
+      break;
+    } while (x < 10);
+    DISALLOW(break;)
+  } else {
+    foo();
+  }
+
+  }
+
+  // Still care about cases and defaults in loops:
+  switch (x) {
+  case 0:
+    if (x == 1) {
+      while (true) {
+  case 1:
+      }
+    } else {
+      foo();
+    }
+    break;
+  }
+
+  switch (x) {
+  case 0:
+    if (x == 1) {
+      while (true) {
+  default:
+      }
+    } else {
+      foo();
+    }
+    break;
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:200:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// CHECK-YES: Initiated the 'if-switch-conversion' action
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:209:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:218:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:227:3 %s | FileCheck --check-prefix=CHECK-YES %s
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:200:3 -at=%s:209:3 -at=%s:218:3 -at=%s:227:3 -at=%s:244:5 -at=%s:256:5 %s 2>&1 -D DISALLOWED | FileCheck --check-prefix=CHECK-INVALID-STATEMENTS %s
+
+void allowBreakDefaultCaseInNestedSwitches(int x) {
+  DISALLOW(switch (x)) {
+  // Allowed:
+  if (x == 1) {
+    foo();
+  } else if (x == 2) {
+    switch (x) {
+    case 0:
+      foo();
+    }
+    DISALLOW(case 0: ;)
+  }
+
+  if (x == 1) {
+    foo();
+  } else {
+    switch (x) {
+    default:
+      foo();
+    }
+    DISALLOW(default: ;)
+  }
+
+  if (x == 1) {
+    switch (x) {
+      break;
+    }
+    DISALLOW(break;)
+  } else {
+    foo();
+  }
+
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:279:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:289:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:299:3 %s | FileCheck --check-prefix=CHECK-YES %s
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:279:3 -at=%s:289:3 -at=%s:299:3  %s 2>&1 -D DISALLOWED | FileCheck --check-prefix=CHECK-INVALID-STATEMENTS %s
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+bool isTrue();
+
+void allowOnlyEqualsOp(int x) {
+  if (x != 1) {
+  } else {
+  }
+
+  if (x == 1) {
+  } else if (x > 2) {
+  }
+
+  if (x == 3) {
+  } else if (x) {
+  }
+
+  if (isTrue()) {
+  } else {
+  }
+}
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:335:3 -at=%s:339:3 -at=%s:343:3 -at=%s:347:3  %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-COND %s
+// CHECK-INVALID-COND: Failed to initiate the refactoring action (unsupported conditional expression)!
+
+void allowEqualsOpInParens(int x) {
+  if ((x == 1)) {
+  } else {
+  }
+
+  if (x == 1) {
+  } else if (((x == 2))) {
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:356:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// RUN: clang-refactor-test initiate -action if-switch-conversion -at=%s:360:3 %s | FileCheck --check-prefix=CHECK-YES %s
+
+enum Switchable {
+  A, B
+};
+
+struct Struct {
+};
+
+bool operator == (const Struct &, int);
+
+void allowSwitchableTypes(int x, bool b, long l, char c, Switchable e,
+                          float f, double d, Struct s, int *ip) {
+  // Allowed:
+  if (b == true) {
+  } else {
+  }
+
+  if (1 == 1) {
+  } else {
+  }
+
+  if (l == 4) {
+  } else {
+  }
+
+  if (e == A) {
+  } else {
+  }
+
+  if (x == A) {
+  } else {
+  }
+
+  if (c == 'x') {
+  } else {
+  }
+
+  // Disallowed:
+  if (f == 0) {
+  } else {
+  }
+
+  if (d == 0) {
+  } else {
+  }
+
+  if (x == 0) {
+  } else if (x == 0.0) {
+  }
+
+  if (s == 0) {
+  } else {
+  }
+
+  if (ip == 0) {
+  } else {
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -location-agnostic -at=%s:380:3 -at=%s:384:3 -at=%s:388:3 -at=%s:392:3 -at=%s:396:3 -at=%s:400:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:405:3 -at=%s:409:3 -at=%s:413:3 -at=%s:417:3 -at=%s:421:3  %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-COND %s
+
+template<typename T>
+void prohibitDependentOperators(T x) {
+  if (x == 0) {
+  } else {
+  }
+}
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:431:3 %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-COND %s
+
+int integerFunction();
+
+void checkLHSSame(int x, int y) {
+  // Allowed:
+  if (integerFunction() == 1) {
+  } else if (integerFunction() == 2) {
+  }
+
+  // Disallowed:
+  if (x == 1) {
+  } else if (y == 2) {
+  }
+
+  if (x == 1) {
+  } else if (2 == 2) {
+  }
+
+  if (integerFunction() == 1) {
+  } else if (x == 2) {
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -location-agnostic -at=%s:442:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:447:3 -at=%s:451:3 -at=%s:455:3 %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-COND %s
+
+void checkRHSConstant(int x, int y, Switchable e) {
+  // Allowed:
+  if (x == (int)A) {
+  } else {
+  }
+
+  if (e == (Switchable)1) {
+  } else {
+  }
+
+  // Disallowed:
+  if (x == y) {
+  } else {
+  }
+
+  if (x == 1) {
+  } else if (x == integerFunction()) {
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -location-agnostic -at=%s:465:3 -at=%s:469:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:474:3 -at=%s:478:3 %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-COND %s
+
+void checkRHSUnique(int x, int y, Switchable e) {
+  // Disallowed:
+  if (x == 0) {
+  } else if (x == 0) {
+  }
+
+  if (e == A) {
+  } else if (e == (Switchable)0) {
+  }
+}
+
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:474:3 -at=%s:478:3 %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-COND %s
+
+void allowLHSParens(int x) {
+  if ((x) == 0) {
+  } else {
+  }
+}
+
+void allowRHSParens(int x) {
+  if (x == (0)) {
+  } else {
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -location-agnostic -at=%s:500:3 -at=%s:506:3 %s | FileCheck --check-prefix=CHECK-YES %s
+
+void allowLogicalOr(int x, int y) {
+  // Allowed:
+  if (x == 0 || x == 1) {
+  } else {
+  }
+
+  if (x == 0) {
+  } else if (x == 1 || x == 2) {
+  }
+
+  if (x == (0) || (x == 1)) {
+  } else {
+  }
+
+  if (x == 0) {
+  } else if ((x == 1 || x == 2)) {
+  }
+
+  // Disallowed:
+  if (x == 0 && x == 1) {
+  } else {
+  }
+
+  if (x == 0 | x == 1) {
+  } else {
+  }
+
+  if (x == 0 || isTrue()) {
+  } else if (y == 2) {
+  }
+
+  if (x == 0 || x == 1) {
+  } else if (y == 2) {
+  }
+
+  if (x == 0) {
+  } else if (x == 1 || x == integerFunction()) {
+  }
+
+  if (x == 1) {
+  } else if (x == 2 || x == 1) {
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -location-agnostic -at=%s:515:3 -at=%s:519:3 -at=%s:523:3 -at=%s:527:3 %s | FileCheck --check-prefix=CHECK-YES %s
+// RUN: not clang-refactor-test initiate -action if-switch-conversion -at=%s:532:3 -at=%s:536:3 -at=%s:540:3 -at=%s:544:3 -at=%s:548:3 -at=%s:552:3 %s 2>&1 | FileCheck --check-prefix=CHECK-INVALID-COND %s
+
+void parenImpCastsLHSEquivalence(int x) {
+  if ((x) == 1) {
+  } else if (x == 2) {
+  }
+}
+
+// RUN: clang-refactor-test initiate -action if-switch-conversion -location-agnostic -at=%s:561:3 %s | FileCheck --check-prefix=CHECK-YES %s
diff --git a/test/Refactor/IfSwitchConversion/if-switch-conversion-perform.cpp b/test/Refactor/IfSwitchConversion/if-switch-conversion-perform.cpp
new file mode 100644
index 0000000..9874795
--- /dev/null
+++ b/test/Refactor/IfSwitchConversion/if-switch-conversion-perform.cpp
@@ -0,0 +1,321 @@
+void foo();
+
+void simpleCompoundBodyIf(int x) {
+  foo();
+
+  if (x == 2) { // CHECK1: "switch (" [[@LINE]]:3 -> [[@LINE]]:7
+    (void)x;    // CHECK1-NEXT: ") {\ncase " [[@LINE-1]]:8 -> [[@LINE-1]]:12
+                // CHECK1-NEXT: ":" [[@LINE-2]]:13 -> [[@LINE-2]]:16
+  } else {      // CHECK1-NEXT: "break;\ndefault:" [[@LINE]]:3 -> [[@LINE]]:11
+    foo();
+  }
+
+  if (((x) == 22 || x == 3) || x == 4) { // CHECK1: "switch (" [[@LINE]]:3 -> [[@LINE]]:9
+    // CHECK1-NEXT: ") {\ncase " [[@LINE-1]]:10 -> [[@LINE-1]]:15
+    // CHECK1-NEXT: ":\ncase " [[@LINE-2]]:17 -> [[@LINE-2]]:26
+    // CHECK1-NEXT: ":\ncase " [[@LINE-3]]:27 -> [[@LINE-3]]:37
+    // CHECK1-NEXT: ":" [[@LINE-4]]:38 -> [[@LINE-4]]:41
+  } else {  // CHECK1-NEXT: "break;\ndefault:" [[@LINE]]:3 -> [[@LINE]]:11
+  }
+
+  foo();
+}
+
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=%s:6:3 -at=%s:13:3 %s | FileCheck --check-prefix=CHECK1 %s
+
+void colonInsertionCompoundBody(int x) {
+  if (x == 2) // CHECK2: ":" [[@LINE]]:13 -> [[@LINE+2]]:4
+
+  {
+
+  }
+  else {
+  }
+}
+
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=%s:27:3 %s | FileCheck --check-prefix=CHECK2 %s
+
+void colonInsertionNonCompoundBody(int x) {
+  if (x == 2) foo(); // CHECK3: ":" [[@LINE]]:13 -> [[@LINE]]:14
+  else {
+  }
+
+  if (x == 2) // CHECK3: ":" [[@LINE]]:13 -> [[@LINE]]:14
+    foo();
+  else {
+  }
+
+  if ((x == (2)) /*comment*/) // CHECK3: ":" [[@LINE]]:15 -> [[@LINE]]:30
+    foo();
+  else {
+  }
+
+  if (x == 2 // CHECK3: ":" [[@LINE]]:13 -> [[@LINE+1]]:8
+      )
+    // comment
+    foo();
+  else {
+  }
+}
+
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=%s:39:3 -at=%s:43:3 -at=%s:48:3 -at=%s:53:3 %s | FileCheck --check-prefix=CHECK3 %s
+
+void colonInsertionFailure(int x) {
+#define EMPTY_MACRO
+  if (x == 1 EMPTY_MACRO ) foo();
+  else {
+  }
+}
+
+// RUN: not clang-refactor-test perform -action if-switch-conversion -at=%s:65:3 %s 2>&1 | FileCheck --check-prefix=CHECK-ERR1 %s
+// CHECK-ERR1: failed to perform the refactoring operation (couldn't find the location of ')')
+
+void elseNonCompoundBody(int x) {
+#ifdef WITH_ELSEIF
+  if (x == 1) foo(); else
+#endif
+  if (x == 2)
+    foo();
+  else // CHECK4: "break;\ndefault:" [[@LINE]]:3 -> [[@LINE]]:7
+    foo();
+
+#ifdef WITH_ELSEIF
+  if (x == 1) foo(); else
+#endif
+  if (x == 2)
+    foo();
+  else foo(); // CHECK4: "break;\ndefault:" [[@LINE]]:3 -> [[@LINE]]:7
+
+#ifdef WITH_ELSEIF
+  if (x == 1) foo(); else
+#endif
+  if (x == 2) foo(); /*comment*/ else foo(); // CHECK4: "\nbreak;\ndefault:" [[@LINE]]:34 -> [[@LINE]]:38
+
+#ifdef WITH_ELSEIF
+  if (x == 1) foo(); else
+#endif
+  if (x == 2) ; else ; // CHECK4: "\nbreak;\ndefault:" [[@LINE]]:17 -> [[@LINE]]:21
+}
+
+void elseCompoundBody(int x) {
+#ifdef WITH_ELSEIF
+  if (x == 1) foo(); else
+#endif
+  if (x == 2) { foo(); } else { foo(); } // CHECK4: "\nbreak;\ndefault:" [[@LINE]]:24 -> [[@LINE]]:32
+
+#ifdef WITH_ELSEIF
+  if (x == 1) foo(); else
+#endif
+  if (x == 2) {
+    // comment.
+  }
+  else // CHECK4: "break;\ndefault:" [[@LINE-1]]:3 -> [[@LINE+1]]:4
+  {
+    foo();
+  }
+}
+
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=%s:77:3 -at=%s:85:3 -at=%s:92:3 -at=%s:97:3 -at=%s:104:3 -at=%s:109:3 %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=%s:77:3 -at=%s:85:3 -at=%s:92:3 -at=%s:97:3 -at=%s:104:3 -at=%s:109:3 %s -D WITH_ELSEIF | FileCheck --check-prefix=CHECK4 %s
+
+void elseIfCompoundBody(int x) {
+  if (x == 2) {
+    foo();
+  } else if (x == 3) { // CHECK5: "break;\ncase " [[@LINE]]:3 -> [[@LINE]]:19
+    foo();             // CHECK5-NEXT: ":" [[@LINE-1]]:20 -> [[@LINE-1]]:23
+  } else if (x == 4 || x == 55) { // CHECK5-NEXT: "break;\ncase " [[@LINE]]:3 -> [[@LINE]]:19
+    foo(); // CHECK5-NEXT: ":\ncase " [[@LINE-1]]:20 -> [[@LINE-1]]:29
+           // CHECK5-NEXT: ":" [[@LINE-2]]:31 -> [[@LINE-2]]:34
+  }
+
+  if (x == 2) { foo(); } else if (x == 3) { foo(); } // CHECK5: "\nbreak;\ncase " [[@LINE]]:24 -> [[@LINE]]:40
+  // CHECK5-NEXT: ":" [[@LINE-1]]:41 -> [[@LINE-1]]:44
+
+  if (x == 2) {
+    // comment.
+  }
+  else if (x == 3) // CHECK5: "break;\ncase " [[@LINE-1]]:3 -> [[@LINE]]:17
+  {                // CHECK5-NEXT: ":" [[@LINE-1]]:18 -> [[@LINE]]:4
+    foo();
+  }
+}
+
+void elseIfNonCompoundBody(int x) {
+  if (x == 2)
+    foo();
+  else if (x == 21) // CHECK5: "break;\ncase " [[@LINE]]:3 -> [[@LINE]]:17
+    foo();          // CHECK5-NEXT: ":" [[@LINE-1]]:19 -> [[@LINE-1]]:20
+  else if (x == 5) ;// CHECK5-NEXT: "break;\ncase " [[@LINE]]:3 -> [[@LINE]]:17
+                    // CHECK5-NEXT: ":" [[@LINE-1]]:18 -> [[@LINE-1]]:19
+
+  if (x == 2) foo(); /*comment*/ else if (x == 3) foo(); // CHECK5: "\nbreak;\ncase " [[@LINE]]:34 -> [[@LINE]]:48
+  // CHECK5-NEXT: ":" [[@LINE-1]]:49 -> [[@LINE-1]]:50
+
+  if (x == 2) ; else if (x == 3) ; // CHECK5: "\nbreak;\ncase " [[@LINE]]:17 -> [[@LINE]]:31
+}
+
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=%s:122:3 -at=%s:131:3 -at=%s:134:3 -at=%s:144:3 -at=%s:151:3 -at=%s:154:3 %s | FileCheck --check-prefix=CHECK5 %s
+
+void closingBraceInsertion(int x) {
+  if (x == 2) {
+  } else if (x == 3) {
+  } else {
+    foo();
+  } // CHECK6: "break;\n" [[@LINE]]
+
+  if (x == 3) {
+  } else if (x == 4) {
+  } // CHECK6: "break;\n" [[@LINE]]
+
+  if (x == 2)
+    foo();
+  else if (x == 3)
+    foo();
+  else if (x == 4) // CHECK6: "\nbreak;\n}" [[@LINE+1]]:11 -> [[@LINE+1]]:11
+    foo();
+
+  if (x == 2)
+    foo();
+  else // CHECK6: "\nbreak;\n}" [[@LINE+1]]:11 -> [[@LINE+1]]:11
+    foo();
+
+  if (x == 2) foo(); // CHECK6: "\nbreak;\n}" [[@LINE+1]]:35 -> [[@LINE+1]]:35
+  else foo(); // preserve comments
+
+  if (x == 2) foo();
+  else if (x == 3) // CHECK6: "\nbreak;\n}" [[@LINE+1]]:12 -> [[@LINE+1]]:12
+    foo() ; foo(); // no preserve
+
+  if (x == 2) foo(); // CHECK6: "\nbreak;\n}" [[@LINE+1]]:11 -> [[@LINE+1]]:11
+  else ; ;
+}
+
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=%s:160:3 -at=%s:166:3 -at=%s:170:3 -at=%s:177:3 -at=%s:182:3 -at=%s:185:3 -at=%s:189:3 %s | FileCheck --check-prefix=CHECK6 %s
+
+void needBreaks(int x) {
+  if (x == 2) {
+    return;
+    x = 3;
+  } else if (x == 3) { // CHECK7: "break;\ncase " [[@LINE]]
+    foo();
+    return;
+    foo();
+  } else { // CHECK7: "break;\ndefault:" [[@LINE]]
+    if (x == 1) {
+      return;
+    }
+  } // CHECK7: "break;\n" [[@LINE]]:3
+
+  if (x == 2)
+    if (x == 3)
+      return;
+    else ; else // CHECK7: "\nbreak;\ndefault:" [[@LINE]]
+    while (x < 2)
+      return; // CHECK7: "\nbreak;\n}" [[@LINE]]:52
+}
+
+void noNeedForBreaks(int x) {
+  if (x == 2) {
+    return;
+  } else if (x == 3) { // CHECK7: "case " [[@LINE]]
+    foo();
+    return;
+  } else { // CHECK7: "default:" [[@LINE]]
+    if (x == 1) {
+    }
+    {
+      return;
+    }
+  } // CHECK7-NOT: "{{.*}}break{{.*}}" [[@LINE]]
+
+  if (x == 2) return; else return; // CHECK7: "\ndefault:" [[@LINE]]
+  // CHECK7: "\n}" [[@LINE-1]]
+
+  // Invalid returns should work as well.
+  if (x == 2)
+    return 1;
+  else        // CHECK7: "default:" [[@LINE]]
+    return 2; // CHECK7: "\n}" [[@LINE]]
+}
+
+int noNeedForBreaksInvalidRets(int x) {
+  if (x == 2)
+    return; // This omits the 'break'.
+  // But this doesn't (should it?).
+  else { // CHECK7: "default:" [[@LINE]]
+    return "";
+  } // CHECK7: "break;\n" [[@LINE]]
+}
+
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=%s:196:3 -at=%s:209:3 -at=%s:218:3 -at=%s:231:3 -at=%s:235:3 -at=%s:242:3 %s | FileCheck --check-prefix=CHECK7 %s
+
+void needBraces(int x) {
+  if (x == 2) { // CHECK8: ": {" [[@LINE]]:13 -> [[@LINE]]:16
+    int a = x;
+  } else if (x == 1) { // CHECK8-NEXT: "break;\n}\ncase " [[@LINE]]:3
+    int a = 0, y = 1;  // CHECK8-NEXT: ": {" [[@LINE-1]]:20 -> [[@LINE-1]]:23
+    return;
+  } else if (x == 3 || x == 4) { // CHECK8-NEXT: "}\ncase " [[@LINE]]:3
+    int m = 2;                   // CHECK8-NEXT: ":\ncase " [[@LINE-1]]
+                                 // CHECK8-NEXT: ": {" [[@LINE-2]]:30 -> [[@LINE-2]]:33
+  } else if (x == 5) { // CHECK8-NEXT: "break;\n}\ncase " [[@LINE]]:3
+    return; // CHECK8-NEXT: ":" [[@LINE-1]]:20 -> [[@LINE-1]]:23
+  } else {  // CHECK8-NEXT: "default: {" [[@LINE]]:3 -> [[@LINE]]:11
+    foo();
+    int k = x;
+    foo();
+  } // CHECK8-NEXT: "break;\n}\n" [[@LINE]]:3 -> [[@LINE]]:3
+
+  if (x == 2) { // CHECK8: ": {" [[@LINE]]
+    int a = 2;
+  } else if (x == 3) { // CHECK8: "break;\n}\ncase " [[@LINE]]
+    int b = x;         // CHECK8-NEXT: ": {" [[@LINE-1]]
+  } // CHECK8-NEXT: "break;\n}\n" [[@LINE]]
+
+  if (x == 2) // CHECK8: ": {" [[@LINE]]:13 -> [[@LINE]]:14
+    int a = x;
+  else if (x == 1 || x == 3) // CHECK8-NEXT: "break;\n}\ncase " [[@LINE]]:3 -> [[@LINE]]:17
+    int b = 2; // CHECK8-NEXT: ":\ncase " [[@LINE-1]]
+               // CHECK8-NEXT: ": {" [[@LINE-2]]:28 -> [[@LINE-2]]:29
+  else if (x == 4) // CHECK8-NEXT: "break;\n}\ncase " [[@LINE]]:3 -> [[@LINE]]:17
+    foo();         // CHECK8-NEXT: ":" [[@LINE-1]]
+  else if (x == 5) // CHECK8-NEXT: "break;\ncase " [[@LINE]]
+    return;        // CHECK8-NEXT: ":" [[@LINE-1]]
+  else             // CHECK8-NEXT: "default: {" [[@LINE]]:3 -> [[@LINE]]:7
+    int c = x;
+  // CHECK8-NEXT: "\nbreak;\n}\n}" [[@LINE-1]]:15 -> [[@LINE-1]]:15
+
+  if (x == 2) int a = 1; else int k = x;
+  // CHECK8: ": {" [[@LINE-1]]:13 -> [[@LINE-1]]:14
+  // CHECK8-NEXT: "\nbreak;\n}\ndefault: {" [[@LINE-2]]:26 -> [[@LINE-2]]:30
+  // CHECK8-NEXT: "\nbreak;\n}\n}" [[@LINE-3]]:41 -> [[@LINE-3]]:41
+}
+
+void noBracesNeeded(int x) {
+  if (x == 2) { // CHECK8: ":" [[@LINE]]
+    if (int *z = p) {
+    }
+  } else if (x == 3) {  // CHECK8: "break;\ncase " [[@LINE]]
+    for (int z = 0; z < x ; ++z) ; // CHECK8: ":" [[@LINE-1]]
+  } else if (x == 4) { // CHECK8: "break;\ncase " [[@LINE]]
+    { // CHECK8: ":" [[@LINE-1]]
+      int a = 1;
+    }
+  }
+}
+
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=%s:253:3 -at=%s:269:3 -at=%s:275:3 -at=%s:288:3 -at=%s:295:3 %s | FileCheck --check-prefix=CHECK8 %s
+
+#define MACRO(X) X
+
+void macroArg(int x) {
+  // macro-arg: +1:9
+  MACRO(if (x == 2) { // MACRO-ARG: "switch (" [[@LINE]]:9 -> [[@LINE]]:13
+    ;                 // MACRO-ARG: ") {\ncase " [[@LINE-1]]:14 -> [[@LINE-1]]:18
+                      // MACRO-ARG: ":" [[@LINE-2]]:19 -> [[@LINE-2]]:22
+  } else if (x == 3) { // MACRO-ARG: "break;\ncase " [[@LINE]]:3 -> [[@LINE]]:19
+    ;                 // MACRO-ARG: ":" [[@LINE-1]]:20 -> [[@LINE-1]]:23
+  }); // MACRO-ARG: "break;\n" [[@LINE]]:3 -> [[@LINE]]:3
+}
+
+// RUN: clang-refactor-test perform -action if-switch-conversion -at=macro-arg %s | FileCheck --check-prefix=MACRO-ARG %s
diff --git a/test/Refactor/ImplementDeclaredMethods/Inputs/class.cpp b/test/Refactor/ImplementDeclaredMethods/Inputs/class.cpp
new file mode 100644
index 0000000..f6389e2
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/Inputs/class.cpp
@@ -0,0 +1,25 @@
+
+struct Class {
+  int field;
+
+  Class();
+
+  Class(int x) { }
+
+  ~Class();
+
+  // commment
+  static void method(const int &value, int defaultParam = 20);
+
+  virtual int voidMethod(int y) const;
+  void implementedMethod() const {
+
+  }
+
+  void outOfLineImpl(int x);
+
+  void anotherImplementedMethod() {
+
+  }
+};
+// CHECK1: "{{.*}}class.cpp" "\n\nClass::Class() { \n  <#code#>;\n}\n\nvoid Class::method(const int &value, int defaultParam) { \n  <#code#>;\n}\n" [[@LINE-1]]:3
diff --git a/test/Refactor/ImplementDeclaredMethods/Inputs/classInHeader.cpp b/test/Refactor/ImplementDeclaredMethods/Inputs/classInHeader.cpp
new file mode 100644
index 0000000..6c16bdf
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/Inputs/classInHeader.cpp
@@ -0,0 +1,69 @@
+#include "classInHeader.h"
+
+#ifndef NO_IMPL
+
+#define PREFIX
+
+#ifdef USE_NAMESPACE
+#ifdef USE_NAMESPACE_PREFIX
+#define PREFIX ns::ns2::
+#else
+#ifdef USE_NAMESPACE_USING
+using namespace ns::ns2;
+#else
+namespace ns {
+namespace ns2 {
+#define CLOSE_NAMESPACES
+#endif
+#endif
+#endif
+
+void PREFIX ClassInHeader::implementedToo() {
+
+}
+
+void PREFIX ClassInHeader::implemented() {
+
+}
+// CHECK1: "{{.*}}classInHeader.cpp" "\n\nvoid ClassInHeader::pleaseImplement() { \n  <#code#>;\n}\n\nvoid ClassInHeader::pleaseImplementThisAsWell() { \n  <#code#>;\n}\n" [[@LINE-1]]:2
+// CHECK1-NS-PREFIX: "{{.*}}classInHeader.cpp" "\n\nvoid ns::ns2::ClassInHeader::pleaseImplement() { \n  <#code#>;\n}\n\nvoid ns::ns2::ClassInHeader::pleaseImplementThisAsWell() { \n  <#code#>;\n}\n" [[@LINE-2]]:2
+
+#ifdef CLOSE_NAMESPACES
+}
+}
+#endif
+
+#endif
+
+namespace other {
+#ifndef USE_NAMESPACE_USING
+using namespace ns::ns2;
+#else
+}
+
+void usingCanBeHidden() {
+#ifndef USE_NAMESPACE_USING
+using namespace ns::ns2;
+#else
+}
+
+#ifdef USE_NAMESPACE_USING
+using namespace ns::ns2;
+#else
+// We still want to insert 'using namespace ns::ns2' if the outer is already
+// used.
+using namespace ns;
+#endif
+
+using namespace other;
+
+namespace ns {
+namespace ns2 {
+// Prefer to insert the methods at the end using 'using' instead of into a
+// namespace.
+}
+}
+
+// CHECK1-NO-IMPL-USING-NS-IN-RECORD: "{{.*}}classInHeader.cpp" "\nusing namespace ns::ns2;\n\nvoid OuterRecord::ClassInHeader::pleaseImplement() { \n  <#code#>;\n}\n\nvoid OuterRecord::ClassInHeader::pleaseImplementThisAsWell() { \n  <#code#>;\n}\n" [[@LINE+3]]:1
+// CHECK1-NO-IMPL-USING-NS: "{{.*}}classInHeader.cpp" "\nusing namespace ns::ns2;\n\nvoid ClassInHeader::pleaseImplement() { \n  <#code#>;\n}\n\nvoid ClassInHeader::pleaseImplementThisAsWell() { \n  <#code#>;\n}\n" [[@LINE+2]]:1
+// CHECK1-NO-IMPL: "{{.*}}classInHeader.cpp" "\n\nvoid ClassInHeader::pleaseImplement() { \n  <#code#>;\n}\n\nvoid ClassInHeader::pleaseImplementThisAsWell() { \n  <#code#>;\n}\n" [[@LINE+1]]:1 -> [[@LINE+1]]:1
diff --git a/test/Refactor/ImplementDeclaredMethods/Inputs/classInHeader.h b/test/Refactor/ImplementDeclaredMethods/Inputs/classInHeader.h
new file mode 100644
index 0000000..89c01bd
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/Inputs/classInHeader.h
@@ -0,0 +1,31 @@
+
+#ifdef USE_NAMESPACE
+namespace ns {
+namespace ns2 {
+#endif
+
+#ifdef USE_ENCLOSING_RECORD
+struct OuterRecord {
+#endif
+
+struct ClassInHeader {
+  void pleaseImplement();
+  void implemented();
+  void pleaseImplementThisAsWell();
+  void implementedToo();
+  void anotherMethod();
+};
+
+#ifdef USE_ENCLOSING_RECORD
+}
+#endif
+
+void ClassInHeader::anotherMethod() {
+}
+// CHECK: "{{.*}}classInHeader.h" "\n\nvoid ClassInHeader::pleaseImplement() { \n  <#code#>;\n}\n\nvoid ClassInHeader::pleaseImplementThisAsWell() { \n  <#code#>;\n}\n" [[@LINE-1]]:2 -> [[@LINE-1]]:2
+
+#ifdef USE_NAMESPACE
+}
+}
+#endif
+
diff --git a/test/Refactor/ImplementDeclaredMethods/Inputs/empty.cpp b/test/Refactor/ImplementDeclaredMethods/Inputs/empty.cpp
new file mode 100644
index 0000000..8d1c8b6
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/Inputs/empty.cpp
@@ -0,0 +1 @@
+ 
diff --git a/test/Refactor/ImplementDeclaredMethods/Inputs/objcClass.m b/test/Refactor/ImplementDeclaredMethods/Inputs/objcClass.m
new file mode 100644
index 0000000..318b7b7
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/Inputs/objcClass.m
@@ -0,0 +1,15 @@
+#include "objcHeader.h"
+
+@implementation MyClass
+
+#ifdef MIX_IMPL
++ (void)classMethod { }
+
+- (void)method:(int)x with:(int)y { }
+#endif
+
+@end
+// CHECK1: "{{.*}}objcClass.m" "- (void)method { \n  <#code#>;\n}\n\n+ (void)classMethod { \n  <#code#>;\n}\n\n- (void)implementedMethod { \n  <#code#>;\n}\n\n- (void)method:(int)x with:(int)y { \n  <#code#>;\n}\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// CHECK2: "{{.*}}objcClass.m" "- (void)method { \n  <#code#>;\n}\n\n- (void)implementedMethod { \n  <#code#>;\n}\n\n" [[@LINE-2]]:1
+
+// CHECK-CAT-NO-IMPL: "{{.*}}objcClass.m" "- (void)thisCategoryMethodShouldBeInTheClassImplementation { \n  <#code#>;\n}\n\n" 11:1 -> 11:1
diff --git a/test/Refactor/ImplementDeclaredMethods/Inputs/objcHeader.h b/test/Refactor/ImplementDeclaredMethods/Inputs/objcHeader.h
new file mode 100644
index 0000000..8d79abe
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/Inputs/objcHeader.h
@@ -0,0 +1,13 @@
+
+@interface MyClass
+
+- (void)method;
+
++ (void)classMethod;
+
+- (void)implementedMethod;
+
+- (void)method:(int)x with:(int)y;
+
+@end
+
diff --git a/test/Refactor/ImplementDeclaredMethods/implement-declared-methods-initiate.cpp b/test/Refactor/ImplementDeclaredMethods/implement-declared-methods-initiate.cpp
new file mode 100644
index 0000000..b94d92b
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/implement-declared-methods-initiate.cpp
@@ -0,0 +1,64 @@
+
+struct Class {
+  int field;
+
+  Class();
+
+  Class(int x) { }
+
+  ~Class();
+
+  // commment
+  void method();
+
+  virtual voidMethod(int y) const;
+  void implementedMethod() const {
+
+  }
+
+  void outOfLineImpl(int x);
+
+  void anotherImplementedMethod() {
+
+  }
+};
+// CHECK1: Initiated the 'implement-declared-methods' action at [[@LINE-20]]:3
+// CHECK2: Initiated the 'implement-declared-methods' action at [[@LINE-17]]:3
+// CHECK3: Initiated the 'implement-declared-methods' action at [[@LINE-15]]:3
+// CHECK4: Initiated the 'implement-declared-methods' action at [[@LINE-14]]:3
+
+void function();
+
+void function() {
+
+}
+
+void Class::outOfLineImpl(int x) {
+
+}
+
+// RUN: clang-refactor-test initiate -action implement-declared-methods -in=%s:5:3-10 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action implement-declared-methods -in=%s:9:3-11 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test initiate -action implement-declared-methods -in=%s:12:3-16 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test initiate -action implement-declared-methods -in=%s:14:3-34 %s | FileCheck --check-prefix=CHECK4 %s
+
+// RUN: not clang-refactor-test initiate -action implement-declared-methods -in=%s:2:1-end -in=%s:3:1-end -in=%s:4:1-end -in=%s:5:1-2 -in=%s:7:1-end -in=%s:9:1-2 -in=%s:11:1-end -in=%s:15:1-end -in=%s:16:1-end -in=%s:17:1-end -in=%s:19:1-end %s -in=%s:30:1-end 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// CHECK-NO: Failed to initiate the refactoring action
+
+// RUN: clang-refactor-test list-actions -at=%s:5:3 %s | FileCheck --check-prefix=CHECK-ACTION %s
+// CHECK-ACTION: Generate Missing Function Definitions
+
+// Class, ~Class, method, voidMethod:
+// CHECK5: Initiated the 'implement-declared-methods' action at [[@LINE-48]]:3 -> [[@LINE-39]]:34
+// RUN: clang-refactor-test initiate -action implement-declared-methods -selected=%s:2:1-24:3 -selected=%s:3:1-23:1 -selected=%s:4:1-23:3 -selected=%s:5:1-14:35 -selected=%s:5:9-14:4  %s | FileCheck --check-prefix=CHECK5 %s
+
+// ~Class, method
+// CHECK6: Initiated the 'implement-declared-methods' action at [[@LINE-48]]:3 -> [[@LINE-45]]:16
+// RUN: clang-refactor-test initiate -action implement-declared-methods -selected=%s:9:1-12:16 -selected=%s:7:1-13:1 -selected=%s:7:17-12:4  %s | FileCheck --check-prefix=CHECK6 %s
+
+// voidMethod
+// CHECK7: Initiated the 'implement-declared-methods' action at [[@LINE-47]]:3
+// RUN: clang-refactor-test initiate -action implement-declared-methods -selected=%s:14:3-14:10 -selected=%s:14:22-14:27 %s | FileCheck --check-prefix=CHECK7 %s
+
+// RUN: not clang-refactor-test initiate -action implement-declared-methods -selected=%s:2:1-30:10 -selected=%s:15:1-15:10 -selected=%s:16:1-16:3 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
diff --git a/test/Refactor/ImplementDeclaredMethods/implement-declared-methods-initiate.m b/test/Refactor/ImplementDeclaredMethods/implement-declared-methods-initiate.m
new file mode 100644
index 0000000..626926b
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/implement-declared-methods-initiate.m
@@ -0,0 +1,106 @@
+
+@protocol P
+
+- (void)method;
+
+@end
+
+@interface MyClass {
+  int ivar;
+}
+
+@property int prop;
+
+- (void)method;
+
+// comment
++ (void)classMethod;
+
+- (void)implementedMethod;
+
+- (void)method:(int)x with:(int)y;
+
+@end
+
+@implementation MyClass
+
+- (void)implementedMethod {
+
+}
+
+@end
+
+
+// CHECK1: Initiated the 'implement-declared-methods' action at [[@LINE-20]]:1
+// CHECK2: Initiated the 'implement-declared-methods' action at [[@LINE-18]]:1
+// CHECK3: Initiated the 'implement-declared-methods' action at [[@LINE-15]]:1
+
+// RUN: clang-refactor-test initiate -action implement-declared-methods -in=%s:14:1-14 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test initiate -action implement-declared-methods -in=%s:17:1-20 %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test initiate -action implement-declared-methods -in=%s:21:1-34 %s | FileCheck --check-prefix=CHECK3 %s
+
+// RUN: not clang-refactor-test initiate -action implement-declared-methods -in=%s:4:1-end -in=%s:27:1-end -in=%s:8:1-end -in=%s:9:1-end -in=%s:12:1-end -in=%s:16:1-end -in=%s:19:1-end -in=%s:23:1-end %s  2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// CHECK-NO: Failed to initiate the refactoring action
+
+// method, classMethod, method:with: :
+// CHECK4: Initiated the 'implement-declared-methods' action at [[@LINE-33]]:1 -> [[@LINE-26]]:35
+// RUN: clang-refactor-test initiate -action implement-declared-methods -selected=%s:8:1-24:3 -selected=%s:9:1-23:3 -selected=%s:14:1-21:35 -selected=%s:14:14-21:2  %s | FileCheck --check-prefix=CHECK4 %s
+
+// classMethod, method:with:
+// CHECK5: Initiated the 'implement-declared-methods' action at [[@LINE-34]]:1 -> [[@LINE-30]]:35
+// RUN: clang-refactor-test initiate -action implement-declared-methods -selected=%s:17:1-21:35 -selected=%s:16:1-22:1 -selected=%s:17:20-21:2 %s | FileCheck --check-prefix=CHECK5 %s
+
+// classMethod
+// CHECK6: Initiated the 'implement-declared-methods' action at [[@LINE-38]]:1
+// RUN: clang-refactor-test initiate -action implement-declared-methods -selected=%s:17:1-17:10 -selected=%s:17:20-18:1 %s | FileCheck --check-prefix=CHECK6 %s
+
+// RUN: not clang-refactor-test initiate -action implement-declared-methods -selected=%s:2:1-30:10 -selected=%s:2:1-6:10 -selected=%s:6:1-25:2 -selected=%s:27:1-29:1 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// Methods declared in class extensions / categories should be supported:
+
+@interface I2
+
+@end
+
+@interface I2 ()
+
+- (void)method;
++ (void)classMethod;
+- (void)implementedMethod;
+
+@end
+// CHECK7: Initiated the 'implement-declared-methods' action at [[@LINE-5]]:1
+// RUN: clang-refactor-test initiate -action implement-declared-methods -at=%s:68:1 %s | FileCheck --check-prefix=CHECK7 %s
+// RUN: not clang-refactor-test initiate -action implement-declared-methods -at=%s:70:1 %s  2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// CHECK8: Initiated the 'implement-declared-methods' action at [[@LINE-9]]:1 -> [[@LINE-8]]:21
+// RUN: clang-refactor-test initiate -action implement-declared-methods -selected=%s:68:1-71:1 %s | FileCheck --check-prefix=CHECK8 %s
+
+@implementation I2
+
+- (void)implementedMethod {
+}
+
+@end
+
+@interface I2 (Extension)
+
+- (void)methodExt;
++ (void)classMethodExt;
+- (void)implementedMethodExt;
+
+@end
+// CHECK9: Initiated the 'implement-declared-methods' action at [[@LINE-5]]:1
+// RUN: clang-refactor-test initiate -action implement-declared-methods -at=%s:89:1 %s | FileCheck --check-prefix=CHECK9 %s
+// RUN: not clang-refactor-test initiate -action implement-declared-methods -at=%s:91:1 %s  2>&1 | FileCheck --check-prefix=CHECK-NO %s
+
+// CHECK10: Initiated the 'implement-declared-methods' action at [[@LINE-9]]:1 -> [[@LINE-8]]:24
+// RUN: clang-refactor-test initiate -action implement-declared-methods -selected=%s:89:1-92:1 %s | FileCheck --check-prefix=CHECK10 %s
+
+@implementation I2 (Extension)
+
+- (void)implementedMethodExt {
+}
+
+@end
diff --git a/test/Refactor/ImplementDeclaredMethods/implement-declared-methods.cpp b/test/Refactor/ImplementDeclaredMethods/implement-declared-methods.cpp
new file mode 100644
index 0000000..3d8164f
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/implement-declared-methods.cpp
@@ -0,0 +1,168 @@
+
+struct Class {
+  int field;
+
+  Class();
+
+  Class(int x) { }
+
+  ~Class();
+
+  // commment middle-methods-begin: +1:1
+  static void method(const int &value, int defaultParam = 20);
+
+  virtual int voidMethod(int y) const;
+  void implementedMethod() const { // middle-methods-end: -1:40
+
+  }
+
+  void outOfLineImpl(int x);
+
+  void anotherImplementedMethod() {
+
+  }
+};
+// CHECK1: "{{.*}}implement-declared-methods.cpp" "\n\nvoid Class::method(const int &value, int defaultParam) { \n  <#code#>;\n}\n\nint Class::voidMethod(int y) const { \n  <#code#>;\n}\n" [[@LINE+5]]:37 -> [[@LINE+5]]:37
+// CHECK2: "{{.*}}implement-declared-methods.cpp" "\n\nClass::Class() { \n  <#code#>;\n}\n\nClass::~Class() { \n  <#code#>;\n}\n\nvoid Class::method(const int &value, int defaultParam) { \n  <#code#>;\n}\n\nint Class::voidMethod(int y) const { \n  <#code#>;\n}\n"  [[@LINE+4]]:37
+// CHECK3: "{{.*}}implement-declared-methods.cpp" "\n\nClass::~Class() { \n  <#code#>;\n}\n\nvoid Class::method(const int &value, int defaultParam) { \n  <#code#>;\n}\n" [[@LINE+3]]:37
+// CHECK4: "{{.*}}implement-declared-methods.cpp" "\n\nClass::Class() { \n  <#code#>;\n}\n\nvoid Class::method(const int &value, int defaultParam) { \n  <#code#>;\n}\n" [[@LINE+2]]:37
+
+void Class::outOfLineImpl(int x) { }
+
+// query-all-impl: [ { name: ast.producer.query, filenameResult: "%s" } , { name: decl.query , predicateResults: [{name: decl.isDefined, intValues: [0, 0, 0, 0] }] }]
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=middle-methods -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=%s:5:1-20:1 -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=%s:8:1-12:10 -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK3 %s
+
+// Implement the constructor and method:
+// query-mix-impl: [ { name: ast.producer.query, filenameResult: "%s" } , { name: decl.query , predicateResults: [{name: decl.isDefined, intValues: [0, 1, 0, 1] }] }]
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=%s:5:1-20:1 -continuation-file=%s -query-results=query-mix-impl %s | FileCheck --check-prefix=CHECK4 %s
+
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=%s:5:1-20:1 -continuation-file=%S/Inputs/class.cpp -query-results=query-mix-impl %s | FileCheck --check-prefix=CHECK1 %S/Inputs/class.cpp
+
+// Empty continuation TU should produce an error:
+// RUN: not clang-refactor-test perform -action implement-declared-methods -selected=%s:5:1-20:1 -continuation-file=%S/Inputs/empty.cpp -query-results=query-mix-impl %s 2>&1 | FileCheck --check-prefix=CHECK-EMPTY-ERR %s
+// CHECK-EMPTY-ERR: failed to perform the refactoring continuation (the target class is not defined in the continuation AST unit)!
+
+#ifdef USE_NAMESPACE
+namespace ns {
+namespace ns2 {
+#endif
+
+#ifdef USE_ENCLOSING_RECORD
+struct OuterRecord {
+#endif
+
+struct ClassInHeader {
+// class-in-header-begin: +1:1
+  void pleaseImplement();
+  void implemented();
+  void pleaseImplementThisAsWell();
+  void implementedToo();
+// class-in-header-end: +1:1
+};
+
+#ifdef USE_ENCLOSING_RECORD
+struct }
+#endif
+
+#ifdef USE_NAMESPACE
+}
+}
+#endif
+
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-mix-impl %s | FileCheck --check-prefix=CHECK1 %S/Inputs/classInHeader.cpp
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-mix-impl %s -DUSE_NAMESPACE | FileCheck --check-prefix=CHECK1 %S/Inputs/classInHeader.cpp
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-mix-impl %s -DUSE_NAMESPACE -DUSE_NAMESPACE_USING | FileCheck --check-prefix=CHECK1 %S/Inputs/classInHeader.cpp
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-mix-impl %s -DUSE_NAMESPACE -DUSE_NAMESPACE_PREFIX | FileCheck --check-prefix=CHECK1-NS-PREFIX %S/Inputs/classInHeader.cpp
+
+// Test when the implementation file has no out-of-line definitions.
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-mix-impl %s -DNO_IMPL | FileCheck --check-prefix=CHECK1-NO-IMPL %S/Inputs/classInHeader.cpp
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-mix-impl %s -DNO_IMPL -DUSE_NAMESPACE | FileCheck --check-prefix=CHECK1-NO-IMPL-USING-NS %S/Inputs/classInHeader.cpp
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-mix-impl %s -DNO_IMPL -DUSE_NAMESPACE -DUSE_ENCLOSING_RECORD | FileCheck --check-prefix=CHECK1-NO-IMPL-USING-NS-IN-RECORD %S/Inputs/classInHeader.cpp
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-mix-impl %s -DNO_IMPL -DUSE_NAMESPACE -DUSE_NAMESPACE_USING | FileCheck --check-prefix=CHECK1-NO-IMPL %S/Inputs/classInHeader.cpp
+
+// query-mix-impl-header: [ { name: ast.producer.query, filenameResult: "%S/classInHeader.h" } , { name: decl.query , predicateResults: [{name: decl.isDefined, intValues: [0, 1, 0, 1] }] }]
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-mix-impl-header %s | FileCheck %S/Inputs/classInHeader.h
+
+// query-no-impl: [ { name: ast.producer.query, filenameResult: "%s" } , { name: decl.query , predicateResults: [{name: decl.isDefined, intValues: [1, 1, 1, 1] }] }]
+// RUN: not clang-refactor-test perform -action implement-declared-methods -selected=class-in-header -continuation-file=%S/Inputs/classInHeader.cpp -query-results=query-no-impl %s 2>&1 | FileCheck --check-prefix=ALL-IMPLEMENTED-ERROR %s
+// ALL-IMPLEMENTED-ERROR: error: continuation failed: the selected methods are already implemented
+
+// Ensure that the methods which are placed right after the record are placed
+// after the outermost record:
+namespace ns {
+
+struct AfterRecordOuterOuter {
+struct AfterRecordOuter {
+  struct AfterRecordInner {
+// after-record-inner-begin: +1:1
+    void pleaseImplement();
+// after-record-inner-end: +0:1
+  };
+
+  AfterRecordOuter();
+};
+// comment
+};
+// CHECK-OUTERMOST: "{{.*}}implement-declared-methods.cpp" "\n\nvoid AfterRecordOuterOuter::AfterRecordOuter::AfterRecordInner::pleaseImplement() { \n  <#code#>;\n}\n" [[@LINE-1]]:3 -> [[@LINE-1]]:3
+
+}
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=after-record-inner -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK-OUTERMOST %s
+
+#ifdef INNER_TEMPLATE
+template<typename T>
+struct OuterTemplateRecord {
+#else
+  template<typename U>
+#endif
+  struct InnerTemplate {
+// inner-template-begin: +0:1
+    InnerTemplate();
+    void function();
+// inner-template-end: +1:1
+  };
+#ifdef INNER_TEMPLATE
+};
+#endif
+
+// RUN: not clang-refactor-test perform -action implement-declared-methods -selected=inner-template %s 2>&1 | FileCheck --check-prefix=CHECK-TEMPLATE-NO %s
+// RUN: not clang-refactor-test perform -action implement-declared-methods -selected=inner-template %s -DINNER_TEMPLATE 2>&1 | FileCheck --check-prefix=CHECK-TEMPLATE-NO %s
+
+// CHECK-TEMPLATE-NO: Failed to initiate the refactoring action (templates are unsupported)!
+
+template<int x, typename T>
+class TemplateSpecialization {
+};
+
+template<>
+class TemplateSpecialization<0, int> {
+// template-specialization-begin: +0:1
+  TemplateSpecialization();
+  void function();
+  void operator ()(int) const;
+  operator int() const;
+// template-specialization-end: +0:1
+};
+// CHECK-SPECIALIZATION: "{{.*}}implement-declared-methods.cpp" "\n\nTemplateSpecialization<0, int>::TemplateSpecialization() { \n  <#code#>;\n}\n\nvoid TemplateSpecialization<0, int>::function() { \n  <#code#>;\n}\n\nvoid TemplateSpecialization<0, int>::operator()(int) const { \n  <#code#>;\n}\n\nTemplateSpecialization<0, int>::operator int() const { \n  <#code#>;\n}\n" [[@LINE-1]]:3
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=template-specialization -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK-SPECIALIZATION %s
+
+template<int x>
+class TemplateSpecialization<x, int> {
+// template-partial-specialization-begin: +0:1
+  void function();
+// template-partial-specialization-end: +0:1
+};
+
+// RUN: not clang-refactor-test perform -action implement-declared-methods -selected=template-partial-specialization %s -DINNER_TEMPLATE 2>&1 | FileCheck --check-prefix=CHECK-TEMPLATE-NO %s
+
+struct ProhibitTemplateFunctions {
+// template-function-begin: +0:1
+  void function();
+  template<typename T>
+  void functionTemplate(const T &);
+  void anotherFunction();
+// template-function-end: +0:1
+};
+// CHECK-FUNCTION-TEMPLATE: "{{.*}}implement-declared-methods.cpp" "\n\nvoid ProhibitTemplateFunctions::function() { \n  <#code#>;\n}\n\nvoid ProhibitTemplateFunctions::anotherFunction() { \n  <#code#>;\n}\n" [[@LINE-1]]:3
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=template-function -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK-FUNCTION-TEMPLATE %s
diff --git a/test/Refactor/ImplementDeclaredMethods/implement-declared-methods.m b/test/Refactor/ImplementDeclaredMethods/implement-declared-methods.m
new file mode 100644
index 0000000..834e20f
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/implement-declared-methods.m
@@ -0,0 +1,85 @@
+
+@interface MyClass
+
+// all-methods-begin: +1:1
+- (void)method;
+
++ (void)classMethod;
+
+- (void)implementedMethod;
+
+- (void)method:(int)x with:(int)y;
+// all-methods-end: +0:1
+
+@end
+
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=all-methods -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK1 %s
+
+@interface MyClass ()
+
+// extension-methods-begin: +1:1
+- (void)anExtensionMethod;
+// extension-methods-end: +0:1
+
+@end
+
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=extension-methods -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK-EXT %s
+
+#ifndef NO_IMPL
+@implementation MyClass
+
+- (void)someOtherMethod { }
+
+@end
+// CHECK1: "{{.*}}implement-declared-methods.m" "- (void)method { \n  <#code#>;\n}\n\n+ (void)classMethod { \n  <#code#>;\n}\n\n- (void)implementedMethod { \n  <#code#>;\n}\n\n- (void)method:(int)x with:(int)y { \n  <#code#>;\n}\n\n" [[@LINE-1]]:1 -> [[@LINE-1]]:1
+// CHECK2: "{{.*}}implement-declared-methods.m" "- (void)method { \n  <#code#>;\n}\n\n- (void)implementedMethod { \n  <#code#>;\n}\n\n" [[@LINE-2]]:1
+// CHECK-EXT: "{{.*}}implement-declared-methods.m" "- (void)anExtensionMethod { \n  <#code#>;\n}\n\n" [[@LINE-3]]:1
+// CHECK-CAT-NO-IMPL: "{{.*}}implement-declared-methods.m" "- (void)thisCategoryMethodShouldBeInTheClassImplementation { \n  <#code#>;\n}\n\n" [[@LINE-4]]:1 -> [[@LINE-4]]:1
+#endif
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=all-methods -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=all-methods -continuation-file=%s -query-results=query-mix-impl %s | FileCheck --check-prefix=CHECK2 %s
+
+// query-all-impl: [ { name: ast.producer.query, filenameResult: "%s" } , { name: decl.query , predicateResults: [{name: decl.isDefined, intValues: [0, 0, 0, 0] }] }]
+// query-mix-impl: [ { name: ast.producer.query, filenameResult: "%s" } , { name: decl.query , predicateResults: [{name: decl.isDefined, intValues: [0, 1, 0, 1] }] }]
+
+// Empty continuation TU or TU without @implementation should produce an error:
+// RUN: not clang-refactor-test perform -action implement-declared-methods -selected=all-methods -continuation-file=%S/Inputs/empty.cpp -query-results=query-all-impl %s 2>&1 | FileCheck --check-prefix=CHECK-EMPTY-ERR %s
+// RUN: not clang-refactor-test perform -action implement-declared-methods -selected=all-methods -continuation-file=%s -query-results=query-all-impl %s -DNO_IMPL 2>&1 | FileCheck --check-prefix=CHECK-EMPTY-ERR %s
+// CHECK-EMPTY-ERR: failed to perform the refactoring continuation (the target @interface is not implemented in the continuation AST unit)!
+
+// query-no-file-all-impl: [ { name: ast.producer.query, filenameResult: "" } , { name: decl.query , predicateResults: [{name: decl.isDefined, intValues: [0, 0, 0, 0] }] }]
+// RUN: not clang-refactor-test perform -action implement-declared-methods -selected=all-methods -continuation-file=%s -query-results=query-no-file-all-impl %s -DNO_IMPL 2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLEMENTATION-ERROR %s
+// CHECK-NO-IMPLEMENTATION-ERROR: error: continuation failed: no @implementation declaration for the selected @interface 'MyClass'; please add one and run the refactoring action again
+
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=all-methods -continuation-file=%S/Inputs/objcClass.m -query-results=query-all-impl %s -DNO_IMPL | FileCheck --check-prefix=CHECK1 %S/Inputs/objcClass.m
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=all-methods -continuation-file=%S/Inputs/objcClass.m -query-results=query-mix-impl %s -DNO_IMPL -DMIX_IMPL | FileCheck --check-prefix=CHECK2 %S/Inputs/objcClass.m
+
+@interface MyClass (Category)
+
+// all-category-methods-begin: +1:1
+- (void)categoryMethod;
++ (MyClass *)classCategoryMethod;
+// all-category-methods-end: +0:1
+
+@end
+
+@implementation MyClass (Category)
+
+- (void)anotherMethod {
+}
+
+@end
+// CHECK3: "{{.*}}implement-declared-methods.m" "- (void)categoryMethod { \n  <#code#>;\n}\n\n+ (MyClass *)classCategoryMethod { \n  <#code#>;\n}\n\n" [[@LINE-1]]:1
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=all-category-methods -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK3 %s
+
+@interface MyClass (NoCategoryImplementation)
+
+// category-no-impl-begin: +1:1
+- (void)thisCategoryMethodShouldBeInTheClassImplementation;
+// category-no-impl-end: +0:1
+
+@end
+
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=category-no-impl -continuation-file=%s -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK-CAT-NO-IMPL %s
+// It should work even in another TU!
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=category-no-impl -continuation-file=%S/Inputs/objcClass.m -query-results=query-all-impl %s | FileCheck --check-prefix=CHECK-CAT-NO-IMPL %S/Inputs/objcClass.m
diff --git a/test/Refactor/ImplementDeclaredMethods/local-record.cpp b/test/Refactor/ImplementDeclaredMethods/local-record.cpp
new file mode 100644
index 0000000..6fbc3e4
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/local-record.cpp
@@ -0,0 +1,30 @@
+void function() {
+struct Class {
+  // one-method: +2:3
+  // all-methods-begin: +1:1
+  Class();
+
+  ~Class(); // comment
+
+  int constOverride() const override;
+
+  // comment
+  void method(const int &value, int defaultParam = 20)
+      ;
+
+  void implementedMethod() const {
+
+  }
+};
+// all-methods-end: -1:1
+}
+// CHECK1: " { \n  <#code#>;\n}" [[@LINE-16]]:10 -> [[@LINE-16]]:11
+// RUN: clang-refactor-test perform -action implement-declared-methods -at=one-method  %s | FileCheck --check-prefix=CHECK1 %s
+
+// CHECK2: " { \n  <#code#>;\n}" [[@LINE-19]]:10 -> [[@LINE-19]]:11
+// CHECK2-NEXT: "" [[@LINE-18]]:11 -> [[@LINE-18]]:12
+// CHECK2-NEXT: " { \n  <#code#>;\n}" [[@LINE-19]]:23 -> [[@LINE-19]]:23
+// CHECK2-NEXT: " { \n  <#code#>;\n}" [[@LINE-18]]:37 -> [[@LINE-18]]:38
+// CHECK2-NEXT: " { \n  <#code#>;\n}" [[@LINE-15]]:7 -> [[@LINE-15]]:8
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=all-methods  %s | FileCheck --check-prefix=CHECK2 %s
+
diff --git a/test/Refactor/ImplementDeclaredMethods/prohibited-methods.cpp b/test/Refactor/ImplementDeclaredMethods/prohibited-methods.cpp
new file mode 100644
index 0000000..6f434d0
--- /dev/null
+++ b/test/Refactor/ImplementDeclaredMethods/prohibited-methods.cpp
@@ -0,0 +1,19 @@
+// RUN: clang-refactor-test perform -action implement-declared-methods -selected=all-methods %s -std=c++11 | FileCheck %s
+// default, deleted and pure methods should not be implemented!
+
+void function() {
+struct Class {
+// all-methods-begin: +1:1
+  Class();
+// CHECK: " { \n  <#code#>;\n}" [[@LINE-1]]:10 -> [[@LINE-1]]:11
+
+  Class(const Class &Other) = default;
+  Class(const Class &&Other) = delete;
+
+  virtual void pureMethod(int x) = 0;
+
+  virtual void method() const;
+// CHECK-NEXT: " { \n  <#code#>;\n}" [[@LINE-1]]:30 -> [[@LINE-1]]:31
+};
+// all-methods-end: -1:1
+}
diff --git a/test/Refactor/LocalizeObjCStringLiteral/localize-objc-initiate.m b/test/Refactor/LocalizeObjCStringLiteral/localize-objc-initiate.m
new file mode 100644
index 0000000..335608e
--- /dev/null
+++ b/test/Refactor/LocalizeObjCStringLiteral/localize-objc-initiate.m
@@ -0,0 +1,26 @@
+@class NSString;
+
+void initiate() {
+  NSString *string = @"hello";
+  const char *cString = "world";
+}
+
+// RUN: clang-refactor-test list-actions -at=%s:4:25 %s | FileCheck --check-prefix=CHECK-ACTION %s
+// CHECK-ACTION: Wrap in NSLocalizedString
+
+// Ensure the the action can be initiated in the string literal:
+
+// RUN: clang-refactor-test initiate -action localize-objc-string-literal -in=%s:4:22-30 %s | FileCheck --check-prefix=CHECK1 %s
+// CHECK1: Initiated the 'localize-objc-string-literal' action at 4:22
+
+// Ensure that the action can't be initiated in other places:
+
+// RUN: not clang-refactor-test initiate -action localize-objc-string-literal -in=%s:1:1-10 -in=%s:3:1-18 -in=%s:4:1-21 -in=%s:5:1-32 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
+// CHECK-NO: Failed to initiate the refactoring action
+
+// Ensure that the action can be initiated using a selection, and only when that
+// selection doesn't go out of the string.
+
+// RUN: clang-refactor-test initiate -action localize-objc-string-literal -selected=%s:4:22-4:30 -selected=%s:4:25-4:30 -selected=%s:4:22-4:27 -selected=%s:4:25-4:27 -selected=%s:4:24-4:29 -selected=%s:4:23-4:30 %s | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: not clang-refactor-test initiate -action localize-objc-string-literal -selected=%s:4:20-4:30 -selected=%s:4:1-4:25 -selected=%s:4:25-5:5 -selected=%s:3:17-6:2 %s 2>&1 | FileCheck --check-prefix=CHECK-NO %s
diff --git a/test/Refactor/LocalizeObjCStringLiteral/localize-objc-perform.m b/test/Refactor/LocalizeObjCStringLiteral/localize-objc-perform.m
new file mode 100644
index 0000000..96095de
--- /dev/null
+++ b/test/Refactor/LocalizeObjCStringLiteral/localize-objc-perform.m
@@ -0,0 +1,20 @@
+@class NSString;
+
+void perform() {
+  NSString *string = @"hello";
+}
+// CHECK1: "NSLocalizedString(" [[@LINE-2]]:22 -> [[@LINE-2]]:22
+// CHECK1-NEXT: ", @"")" [[@LINE-3]]:30 -> [[@LINE-3]]:30
+// RUN: clang-refactor-test perform -action localize-objc-string-literal -at=%s:4:22 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test perform -action localize-objc-string-literal -selected=%s:4:23-4:30 %s | FileCheck --check-prefix=CHECK1 %s
+
+#define MACRO(x, y) x
+
+void performInMacroArgument() {
+  // macro-arg: +2:9
+  // macro-arg-range-begin: +1:9
+  MACRO(@"hello", 1);           // CHECK2: "NSLocalizedString(" [[@LINE]]:9 -> [[@LINE]]:9
+  // macro-arg-range-end: -1:17 // CHECK2: ", @"")" [[@LINE-1]]:17 -> [[@LINE-1]]:17
+}
+// RUN: clang-refactor-test perform -action localize-objc-string-literal -at=macro-arg %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test perform -action localize-objc-string-literal -selected=macro-arg-range %s | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Rename/CanonicalizeInstantiatedDecls.cpp b/test/Refactor/Rename/CanonicalizeInstantiatedDecls.cpp
new file mode 100644
index 0000000..f520a2e
--- /dev/null
+++ b/test/Refactor/Rename/CanonicalizeInstantiatedDecls.cpp
@@ -0,0 +1,86 @@
+
+template<typename T>
+class BaseTemplate {
+public:
+  T baseTemplateFunction();
+
+  T baseTemplateField;
+
+  struct NestedBaseType { };
+};
+
+template<typename T, typename S>
+class TemplateClass: public BaseTemplate<T> {
+public:
+  T function() { return T(); }
+
+  static void staticFunction() { }
+
+  T field;
+
+  struct NestedType {
+    T nestedField;
+
+    class SubNestedType {
+    public:
+      SubNestedType(int);
+    };
+    using TypeAlias = T;
+
+    typedef int Typedef;
+
+    enum Enum {
+      EnumCase
+    };
+  };
+};
+
+void canonicalizeInstaniationReferences(TemplateClass<int, float> &object) {
+  (void)object.function();
+// CHECK1: 'c:@ST>2#T#T@TemplateClass@F@function#'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):16 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK1 %s
+  (void)object.field;
+// CHECK2: 'c:@ST>2#T#T@TemplateClass@FI@field'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):16 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK2 %s
+  (void)object.baseTemplateFunction();
+// CHECK3: 'c:@ST>1#T@BaseTemplate@F@baseTemplateFunction#'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):16 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK3 %s
+  (void)object.baseTemplateField;
+// CHECK4: 'c:@ST>1#T@BaseTemplate@FI@baseTemplateField'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):16 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK4 %s
+
+  TemplateClass<int, float>::staticFunction();
+// CHECK5: 'c:@ST>2#T#T@TemplateClass@F@staticFunction#S'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):30 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK5 %s
+
+  TemplateClass<int, float>::NestedBaseType nestedBaseType;
+// CHECK6: 'c:@ST>1#T@BaseTemplate@S@NestedBaseType'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):30 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK6 %s
+  TemplateClass<int, float>::NestedType nestedSubType;
+// CHECK7: 'c:@ST>2#T#T@TemplateClass@S@NestedType'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):30 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK7 %s
+  (void)nestedSubType.nestedField;
+// CHECK8: 'c:@ST>2#T#T@TemplateClass@S@NestedType@FI@nestedField'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):23 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK8 %s
+
+  typedef TemplateClass<int, float> TT;
+  TT::NestedType::SubNestedType subNestedType(0);
+// CHECK9: 'c:@ST>2#T#T@TemplateClass@S@NestedType'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):7 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK9 %s
+// CHECK10: 'c:@ST>2#T#T@TemplateClass@S@NestedType@S@SubNestedType'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-4):19 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK10 %s
+
+  TT::NestedType::TypeAlias nestedTypeAlias;
+// CHECK11: 'c:@ST>2#T#T@TemplateClass@S@NestedType@TypeAlias'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):19 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK11 %s
+  TT::NestedType::Typedef nestedTypedef;
+// CHECK12: 'c:{{.*}}CanonicalizeInstantiatedDecls.cpp@ST>2#T#T@TemplateClass@S@NestedType@T@Typedef'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):19 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK12 %s
+
+  TT::NestedType::Enum nestedEnum;
+// CHECK13: 'c:@ST>2#T#T@TemplateClass@S@NestedType@E@Enum'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):19 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK13 %s
+  (void)TT::NestedType::Enum::EnumCase;
+// CHECK14: 'c:@ST>2#T#T@TemplateClass@S@NestedType@E@Enum@EnumCase'
+// RUN: clang-refactor-test rename-initiate -at=%s:%(line-2):31 -new-name=x -dump-symbols %s | FileCheck --check-prefix=CHECK14 %s
+}
diff --git a/test/Refactor/Rename/ClassAsTemplateArgument.cpp b/test/Refactor/Rename/ClassAsTemplateArgument.cpp
new file mode 100644
index 0000000..6310780
--- /dev/null
+++ b/test/Refactor/Rename/ClassAsTemplateArgument.cpp
@@ -0,0 +1,20 @@
+class Foo /* Test 1 */ {};    // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+
+template <typename T>
+void func() {}
+
+template <typename T>
+class Baz {};
+
+int main() {
+  func<Foo>(); /* Test 2 */   // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:11
+  Baz<Foo> /* Test 3 */ obj;  // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+  return 0;
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:1:7 -new-name=Bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:10:8 -new-name=Bar %s | FileCheck %s
+// Test 3.
+// RUN: clang-refactor-test rename-initiate -at=%s:11:7 -new-name=Bar %s | FileCheck %s
diff --git a/test/Refactor/Rename/ClassSimpleRenaming.cpp b/test/Refactor/Rename/ClassSimpleRenaming.cpp
new file mode 100644
index 0000000..78d213c
--- /dev/null
+++ b/test/Refactor/Rename/ClassSimpleRenaming.cpp
@@ -0,0 +1,38 @@
+class Foo /* Test 1 */ {              // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+public:
+  void foo(int x);
+};
+
+void Foo::foo(int x) /* Test 2 */ {}  // CHECK: rename [[@LINE]]:6 -> [[@LINE]]:9
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:1:7 -new-name=Bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:6:6 -new-name=Bar %s | FileCheck %s
+
+struct ForwardDeclaration; // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:26
+
+ForwardDeclaration *variable; // CHECK2: rename [[@LINE]]:1 -> [[@LINE]]:19
+
+// RUN: clang-refactor-test rename-initiate -at=%s:13:8 -at=%s:15:1 -new-name=Bar %s | FileCheck --check-prefix=CHECK2 %s
+
+template<typename T>
+struct SpecializationWithoutDefinition { }; // CHECK3: rename [[@LINE]]:8 -> [[@LINE]]:39
+
+template<>
+struct SpecializationWithoutDefinition<int> { }; // CHECK3: rename [[@LINE]]:8 -> [[@LINE]]:39
+
+template<>
+struct SpecializationWithoutDefinition<float>; // CHECK3: rename [[@LINE]]:8 -> [[@LINE]]:39
+
+// RUN: clang-refactor-test rename-initiate -at=%s:20:8 -at=%s:23:8 -new-name=Bar %s | FileCheck --check-prefix=CHECK3 %s
+
+template<typename T>
+struct Class {
+  void method();
+};
+
+template<typename T>        // CHECK4: [[@LINE]]:19 -> [[@LINE]]:20
+void Class<T>::method() { } // CHECK4: [[@LINE]]:12 -> [[@LINE]]:13
+
+// RUN: clang-refactor-test rename-initiate -at=%s:35:19 -new-name=Bar %s | FileCheck --check-prefix=CHECK4 %s
diff --git a/test/Refactor/Rename/ComplexFunctionOverride.cpp b/test/Refactor/Rename/ComplexFunctionOverride.cpp
new file mode 100644
index 0000000..52f09e8
--- /dev/null
+++ b/test/Refactor/Rename/ComplexFunctionOverride.cpp
@@ -0,0 +1,76 @@
+struct A {
+  virtual void foo() {} /* Test 1 */    // CHECK: rename [[@LINE]]:16 -> [[@LINE]]:19
+};
+
+struct B : A {
+  void foo() override {} /* Test 2 */   // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:11
+};
+
+struct C : B {
+  void foo() override {} /* Test 3 */   // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:11
+};
+
+struct D : B {
+  void foo() override {} /* Test 4 */   // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:11
+};
+
+struct E : D {
+  void foo() override {} /* Test 5 */   // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:11
+};
+
+int main() {
+  A a;
+  a.foo();                              // CHECK: rename [[@LINE]]:5 -> [[@LINE]]:8
+  B b;
+  b.foo();                              // CHECK: rename [[@LINE]]:5 -> [[@LINE]]:8
+  C c;
+  c.foo();                              // CHECK: rename [[@LINE]]:5 -> [[@LINE]]:8
+  D d;
+  d.foo();                              // CHECK: rename [[@LINE]]:5 -> [[@LINE]]:8
+  E e;
+  e.foo();                              // CHECK: rename [[@LINE]]:5 -> [[@LINE]]:8
+  return 0;
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:2:16 -new-name=bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:6:8 -new-name=bar %s | FileCheck %s
+// Test 3.
+// RUN: clang-refactor-test rename-initiate -at=%s:10:8 -new-name=bar %s | FileCheck %s
+// Test 4.
+// RUN: clang-refactor-test rename-initiate -at=%s:14:8 -new-name=bar %s | FileCheck %s
+// Test 5.
+// RUN: clang-refactor-test rename-initiate -at=%s:18:8 -new-name=bar %s | FileCheck %s
+
+// Check virtual inheritance
+
+struct A2 {
+  virtual void foo() {}   // CHECK-VIRT: rename [[@LINE]]:16 -> [[@LINE]]:19
+};
+struct B2 : virtual A2 {
+  void foo() { }          // CHECK-VIRT: rename [[@LINE]]:8 -> [[@LINE]]:11
+};
+struct C2 : virtual A2 {
+  void foo() override { } // CHECK-VIRT: rename [[@LINE]]:8 -> [[@LINE]]:11
+};
+struct D2 : B2, C2 {
+  void foo() override {  // CHECK-VIRT: rename [[@LINE]]:8 -> [[@LINE]]:11
+    A2::foo();           // CHECK-VIRT: rename [[@LINE]]:9 -> [[@LINE]]:12
+  }
+};
+
+int bar() {
+  A2 a;
+  a.foo(); // CHECK-VIRT: rename [[@LINE]]:5 -> [[@LINE]]:8
+  D2 d;
+  d.foo(); // CHECK-VIRT: rename [[@LINE]]:5 -> [[@LINE]]:8
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:49:16 -new-name=bar %s | FileCheck --check-prefix=CHECK-VIRT %s
+// RUN: clang-refactor-test rename-initiate -at=%s:52:8 -new-name=bar %s | FileCheck --check-prefix=CHECK-VIRT %s
+// RUN: clang-refactor-test rename-initiate -at=%s:55:8 -new-name=bar %s | FileCheck --check-prefix=CHECK-VIRT %s
+// RUN: clang-refactor-test rename-initiate -at=%s:58:8 -new-name=bar %s | FileCheck --check-prefix=CHECK-VIRT %s
+// RUN: clang-refactor-test rename-initiate -at=%s:59:9 -new-name=bar %s | FileCheck --check-prefix=CHECK-VIRT %s
+// RUN: clang-refactor-test rename-initiate -at=%s:65:5 -new-name=bar %s | FileCheck --check-prefix=CHECK-VIRT %s
+// RUN: clang-refactor-test rename-initiate -at=%s:67:5 -new-name=bar %s | FileCheck --check-prefix=CHECK-VIRT %s
diff --git a/test/Refactor/Rename/ComplicatedClassType.cpp b/test/Refactor/Rename/ComplicatedClassType.cpp
new file mode 100644
index 0000000..eb0fea8
--- /dev/null
+++ b/test/Refactor/Rename/ComplicatedClassType.cpp
@@ -0,0 +1,62 @@
+// Forward declaration.
+class Foo; /* Test 1 */               // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+
+class Baz {
+  virtual int getValue() const = 0;
+};
+
+class Foo : public Baz  { /* Test 2 */// CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+public:
+  Foo(int value = 0) : x(value) {}    // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+
+  Foo &operator++(int) {              // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+    x++;
+    return *this;
+  }
+
+  bool operator<(Foo const &rhs) {    // CHECK: rename [[@LINE]]:18 -> [[@LINE]]:21
+    return this->x < rhs.x;
+  }
+
+  int getValue() const {
+    return 0;
+  }
+
+private:
+  int x;
+};
+
+int main() {
+  Foo *Pointer = 0;                   // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+  Foo Variable = Foo(10);             // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+                                      // CHECK: rename [[@LINE-1]]:18 -> [[@LINE-1]]:21
+  for (Foo it; it < Variable; it++) { // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:11
+  }
+  const Foo *C = new Foo();           // CHECK: rename [[@LINE]]:9 -> [[@LINE]]:12
+                                      // CHECK: rename [[@LINE-1]]:22 -> [[@LINE-1]]:25
+  const_cast<Foo *>(C)->getValue();   // CHECK: rename [[@LINE]]:14 -> [[@LINE]]:17
+  Foo foo;                            // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+  const Baz &BazReference = foo;
+  const Baz *BazPointer = &foo;
+  dynamic_cast<const Foo &>(BazReference).getValue();     /* Test 3 */ // CHECK: rename [[@LINE]]:22 -> [[@LINE]]:25
+  dynamic_cast<const Foo *>(BazPointer)->getValue();      /* Test 4 */ // CHECK: rename [[@LINE]]:22 -> [[@LINE]]:25
+  reinterpret_cast<const Foo *>(BazPointer)->getValue();  /* Test 5 */ // CHECK: rename [[@LINE]]:26 -> [[@LINE]]:29
+  static_cast<const Foo &>(BazReference).getValue();      /* Test 6 */ // CHECK: rename [[@LINE]]:21 -> [[@LINE]]:24
+  static_cast<const Foo *>(BazPointer)->getValue();       /* Test 7 */ // CHECK: rename [[@LINE]]:21 -> [[@LINE]]:24
+  return 0;
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:2:7 -new-name=Bar %s -frtti | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:8:7 -new-name=Bar %s -frtti | FileCheck %s
+// Test 3.
+// RUN: clang-refactor-test rename-initiate -at=%s:41:22 -new-name=Bar %s -frtti | FileCheck %s
+// Test 4.
+// RUN: clang-refactor-test rename-initiate -at=%s:42:22 -new-name=Bar %s -frtti | FileCheck %s
+// Test 5.
+// RUN: clang-refactor-test rename-initiate -at=%s:43:26 -new-name=Bar %s -frtti | FileCheck %s
+// Test 6.
+// RUN: clang-refactor-test rename-initiate -at=%s:44:21 -new-name=Bar %s -frtti | FileCheck %s
+// Test 7.
+// RUN: clang-refactor-test rename-initiate -at=%s:45:21 -new-name=Bar %s -frtti | FileCheck %s
diff --git a/test/Refactor/Rename/Ctor.cpp b/test/Refactor/Rename/Ctor.cpp
new file mode 100644
index 0000000..73ac020
--- /dev/null
+++ b/test/Refactor/Rename/Ctor.cpp
@@ -0,0 +1,29 @@
+class Foo {                  // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+public:
+  Foo();                     // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+  Foo(int x, int y);         // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+  ~Foo();                    // CHECK: rename [[@LINE]]:4 -> [[@LINE]]:7
+};
+
+Foo::Foo() {}               // CHECK: rename [[@LINE]]:1 -> [[@LINE]]:4
+// CHECK: rename [[@LINE-1]]:6 -> [[@LINE-1]]:9
+
+Foo::Foo(int x, int y) { }  // CHECK: rename [[@LINE]]:1 -> [[@LINE]]:4
+// CHECK: rename [[@LINE-1]]:6 -> [[@LINE-1]]:9
+
+Foo::~Foo() {}              // CHECK: rename [[@LINE]]:1 -> [[@LINE]]:4
+// CHECK: rename [[@LINE-1]]:7 -> [[@LINE-1]]:10
+
+Foo f(const Foo &Other) {   // CHECK: rename [[@LINE]]:1 -> [[@LINE]]:4
+                            // CHECK: rename [[@LINE-1]]:13 -> [[@LINE-1]]:16
+  return Foo(Other);        // CHECK: rename [[@LINE]]:10 -> [[@LINE]]:13
+}
+
+// Declarations.
+// RUN: clang-refactor-test rename-initiate -at=%s:3:3 -at=%s:4:3 -at=%s:5:4 -new-name=Bar %s | FileCheck %s
+
+// Definitions.
+// RUN: clang-refactor-test rename-initiate -at=%s:8:6 -at=%s:11:6 -at=%s:14:7 -new-name=Bar %s | FileCheck %s
+
+// Implicit copy constructor.
+// RUN: clang-refactor-test rename-initiate -at=%s:19:10 -new-name=Bar %s | FileCheck %s
diff --git a/test/Refactor/Rename/CtorInitializer.cpp b/test/Refactor/Rename/CtorInitializer.cpp
new file mode 100644
index 0000000..fe5b609
--- /dev/null
+++ b/test/Refactor/Rename/CtorInitializer.cpp
@@ -0,0 +1,14 @@
+class Baz {};
+
+class Qux {
+  Baz Foo;         /* Test 1 */     // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+public:
+  Qux();
+};
+
+Qux::Qux() : Foo() /* Test 2 */ {}  // CHECK: rename [[@LINE]]:14 -> [[@LINE]]:17
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:4:7 -new-name=Bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:9:14 -new-name=Bar %s | FileCheck %s
diff --git a/test/Refactor/Rename/DeclRefExpr.cpp b/test/Refactor/Rename/DeclRefExpr.cpp
new file mode 100644
index 0000000..3808343
--- /dev/null
+++ b/test/Refactor/Rename/DeclRefExpr.cpp
@@ -0,0 +1,21 @@
+class C {
+public:
+  static int Foo; /* Test 1 */  // CHECK: rename [[@LINE]]:14 -> [[@LINE]]:17
+};
+
+int foo(int x) { return 0; }
+#define MACRO(a) foo(a)
+
+int main() {
+  C::Foo = 1;     /* Test 2 */  // CHECK: rename [[@LINE]]:6 -> [[@LINE]]:9
+  MACRO(C::Foo);                // CHECK: rename [[@LINE]]:12 -> [[@LINE]]:15
+  int y = C::Foo; /* Test 3 */  // CHECK: rename [[@LINE]]:14 -> [[@LINE]]:17
+  return 0;
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:3:14 -new-name=Bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:10:6 -new-name=Bar %s | FileCheck %s
+// Test 3.
+// RUN: clang-refactor-test rename-initiate -at=%s:12:14 -new-name=Bar %s | FileCheck %s
diff --git a/test/Refactor/Rename/DependentExpressions.cpp b/test/Refactor/Rename/DependentExpressions.cpp
new file mode 100644
index 0000000..0c7612c
--- /dev/null
+++ b/test/Refactor/Rename/DependentExpressions.cpp
@@ -0,0 +1,72 @@
+int invalid;
+
+class Base {
+  void baseFunction(); // CHECK3: [[@LINE]]:8 -> [[@LINE]]:20
+
+  int baseField;
+
+  static void staticBaseFunction(); // CHECK7: [[@LINE]]:15 -> [[@LINE]]:33
+};
+
+template<typename T>
+class BaseTemplate {
+public:
+  T baseTemplateFunction();
+
+  T baseTemplateField; // CHECK4: [[@LINE]]:5 -> [[@LINE]]:22
+
+  static T baseTemplateVariable; // CHECK8: [[@LINE]]:12 -> [[@LINE]]:32
+};
+
+template<typename T, typename S>
+class TemplateClass: public Base , public BaseTemplate<T> {
+public:
+  ~TemplateClass();
+
+  T function() { } // CHECK1: [[@LINE]]:5 -> [[@LINE]]:13
+
+  static void staticFunction() { } // CHECK5: [[@LINE]]:15 -> [[@LINE]]:29
+
+  T field; // CHECK2: [[@LINE]]:5 -> [[@LINE]]:10
+
+  static T variable; // CHECK6: [[@LINE]]:12 -> [[@LINE]]:20
+
+  struct Struct { }; // CHECK9: [[@LINE]]:10 -> [[@LINE]]:16
+
+  enum Enum { EnumValue }; // CHECK10: [[@LINE]]:8 -> [[@LINE]]:12
+
+  using TypeAlias = S; // CHECK11: [[@LINE]]:9 -> [[@LINE]]:18
+  typedef T Typedef;
+
+  void overload1(const T &);
+  void overload1(const S &);
+};
+
+template<typename T, typename S>
+void renameSimpleDependentDeclarations(const TemplateClass<T, S> &object) {
+
+  object.function(); // CHECK1: [[@LINE]]:10 -> [[@LINE]]:18
+// RUN: clang-refactor-test rename-initiate -at=%s:26:5 -at=%s:48:10 -new-name=x %s | FileCheck --check-prefix=CHECK1 %s
+  object.field; // CHECK2: [[@LINE]]:10 -> [[@LINE]]:15
+// RUN: clang-refactor-test rename-initiate -at=%s:30:5 -at=%s:50:10 -new-name=x %s | FileCheck --check-prefix=CHECK2 %s
+  object.baseFunction(); // CHECK3: [[@LINE]]:10 -> [[@LINE]]:22
+// RUN: clang-refactor-test rename-initiate -at=%s:4:8 -at=%s:52:10 -new-name=x %s | FileCheck --check-prefix=CHECK3 %s
+  object.baseTemplateField; // CHECK4: [[@LINE]]:10 -> [[@LINE]]:27
+// RUN: clang-refactor-test rename-initiate -at=%s:16:5 -at=%s:54:10 -new-name=x %s | FileCheck --check-prefix=CHECK4 %s
+
+  TemplateClass<T, S>::staticFunction(); // CHECK5: [[@LINE]]:24 -> [[@LINE]]:38
+// RUN: clang-refactor-test rename-initiate -at=%s:28:15 -at=%s:57:24 -new-name=x %s | FileCheck --check-prefix=CHECK5 %s
+  TemplateClass<T, S>::variable; // CHECK6: [[@LINE]]:24 -> [[@LINE]]:32
+// RUN: clang-refactor-test rename-initiate -at=%s:32:12 -at=%s:59:24 -new-name=x %s | FileCheck --check-prefix=CHECK6 %s
+  TemplateClass<T, S>::staticBaseFunction(); // CHECK7: [[@LINE]]:24 -> [[@LINE]]:42
+// RUN: clang-refactor-test rename-initiate -at=%s:8:15 -at=%s:61:24 -new-name=x %s | FileCheck --check-prefix=CHECK7 %s
+  TemplateClass<T, S>::baseTemplateVariable; // CHECK8: [[@LINE]]:24 -> [[@LINE]]:44
+// RUN: clang-refactor-test rename-initiate -at=%s:18:12 -at=%s:63:24 -new-name=x %s | FileCheck --check-prefix=CHECK8 %s
+
+  typename TemplateClass<T, S>::Struct Val; // CHECK9: [[@LINE]]:33 -> [[@LINE]]:39
+// RUN: clang-refactor-test rename-initiate -at=%s:34:10 -at=%s:66:33 -new-name=x %s | FileCheck --check-prefix=CHECK9 %s
+  typename TemplateClass<T, S>::Enum EnumVal; // CHECK10: [[@LINE]]:33 -> [[@LINE]]:37
+// RUN: clang-refactor-test rename-initiate -at=%s:36:8 -at=%s:68:33 -new-name=x %s | FileCheck --check-prefix=CHECK10 %s
+  typename TemplateClass<T, S>::TypeAlias Val2; // CHECK11: [[@LINE]]:33 -> [[@LINE]]:42
+// RUN: clang-refactor-test rename-initiate -at=%s:38:9 -at=%s:70:33 -new-name=x %s | FileCheck --check-prefix=CHECK11 %s
+}
diff --git a/test/Refactor/Rename/Field.cpp b/test/Refactor/Rename/Field.cpp
new file mode 100644
index 0000000..94b144a
--- /dev/null
+++ b/test/Refactor/Rename/Field.cpp
@@ -0,0 +1,12 @@
+class Baz {
+  int Foo; /* Test 1 */ // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+public:
+  Baz();
+};
+
+Baz::Baz() : Foo(0) /* Test 2 */ {}  // CHECK: rename [[@LINE]]:14 -> [[@LINE]]:17
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:2:7 -new-name=Bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:7:14 -new-name=Bar %s | FileCheck %s
diff --git a/test/Refactor/Rename/FunctionMacro.cpp b/test/Refactor/Rename/FunctionMacro.cpp
new file mode 100644
index 0000000..946c4d1
--- /dev/null
+++ b/test/Refactor/Rename/FunctionMacro.cpp
@@ -0,0 +1,17 @@
+#define moo foo
+
+int foo() /* Test 1 */ {  // CHECK: rename [[@LINE]]:5 -> [[@LINE]]:8
+  return 42;
+}
+
+void boo(int value) {}
+
+void qoo() {
+  foo();                  // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+  boo(foo());             // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+  moo();                  // CHECK: macro [[@LINE]]:3 -> [[@LINE]]:3
+  boo(moo());             // CHECK: macro [[@LINE]]:7 -> [[@LINE]]:7
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:3:5 -new-name=macro_function %s | FileCheck %s
diff --git a/test/Refactor/Rename/FunctionOverride.cpp b/test/Refactor/Rename/FunctionOverride.cpp
new file mode 100644
index 0000000..9c6fc34
--- /dev/null
+++ b/test/Refactor/Rename/FunctionOverride.cpp
@@ -0,0 +1,10 @@
+class A { virtual void foo();     /* Test 1 */ }; // CHECK: rename [[@LINE]]:24 -> [[@LINE]]:27
+class B : public A { void foo();  /* Test 2 */ }; // CHECK: rename [[@LINE]]:27 -> [[@LINE]]:30
+class C : public B { void foo();  /* Test 3 */ }; // CHECK: rename [[@LINE]]:27 -> [[@LINE]]:30
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:1:24 -new-name=bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:2:27 -new-name=bar %s | FileCheck %s
+// Test 3.
+// RUN: clang-refactor-test rename-initiate -at=%s:3:27 -new-name=bar %s | FileCheck %s
diff --git a/test/Refactor/Rename/IndexedObjCMessageSend.mm b/test/Refactor/Rename/IndexedObjCMessageSend.mm
new file mode 100644
index 0000000..1fd6070
--- /dev/null
+++ b/test/Refactor/Rename/IndexedObjCMessageSend.mm
@@ -0,0 +1,882 @@
++(BOOL) onEntity {
+  call() = [_undef_ivar name: @"string literal" method: @"string literal"];
+  // CHECK1: [[@LINE-1]]:25 -> [[@LINE-1]]:29, [[@LINE-1]]:49 -> [[@LINE-1]]:55
+}
+// RUN: clang-refactor-test rename-indexed-file -name=name:method -new-name=object:world -indexed-file=%s -indexed-at=2:25 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK1 %s
+
+-(const Object &) a_200 {
+  some_type_t world = @"string literal";
+  [self withSomething: [] () {
+   some_type_t foo = [super struct: @"string literal"
+ world: [] () {
+  } name: []  {
+
+
+ } a_200: 12 a_200: globalArray[i]];
+  // CHECK2: [[@LINE-6]]:29 -> [[@LINE-6]]:35, [[@LINE-5]]:2 -> [[@LINE-5]]:7, [[@LINE-4]]:5 -> [[@LINE-4]]:9, [[@LINE-1]]:4 -> [[@LINE-1]]:9, [[@LINE-1]]:14 -> [[@LINE-1]]:19
+
+ } onEntity: ']' perform: "]"];
+  // CHECK3: [[@LINE-10]]:9 -> [[@LINE-10]]:22, [[@LINE-1]]:4 -> [[@LINE-1]]:12, [[@LINE-1]]:18 -> [[@LINE-1]]:25
+}
+// RUN: clang-refactor-test rename-indexed-file -name=struct:world:name:a_200:a_200 -new-name=withSomething:foo:part:struct:method -indexed-file=%s -indexed-at=10:29 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:onEntity:perform -new-name=method:foo:name -indexed-file=%s -indexed-at=9:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK3 %s
+
+-(int) struct {
+  // comment
+}
+
+-(int) bar {
+  return ']';
+}
+
+-(int) part {
+  call() = [self test: 12 method: globalArray[i] test: globalArray[i] world: ']'];
+  // CHECK4: [[@LINE-1]]:18 -> [[@LINE-1]]:22, [[@LINE-1]]:27 -> [[@LINE-1]]:33, [[@LINE-1]]:50 -> [[@LINE-1]]:54, [[@LINE-1]]:71 -> [[@LINE-1]]:76
+  [_undef_ivar withSomething: @{ @1, @3 } onEntity: [] () {    ([self foo: "]" piece:  foo: (']')]);
+  // CHECK5: [[@LINE-1]]:71 -> [[@LINE-1]]:74, [[@LINE-1]]:80 -> [[@LINE-1]]:85, [[@LINE-1]]:88 -> [[@LINE-1]]:91
+  }];
+  // CHECK6: [[@LINE-3]]:16 -> [[@LINE-3]]:29, [[@LINE-3]]:43 -> [[@LINE-3]]:51
+  int bar = [self name: ']' z_Z_42: [] () {    [globalObject send: [self perform: globalArray[i] * "string" a_200: 12 class: 12 perform: ']' object: [] () {
+  }] other: 42];
+  // CHECK7: [[@LINE-2]]:74 -> [[@LINE-2]]:81, [[@LINE-2]]:109 -> [[@LINE-2]]:114, [[@LINE-2]]:119 -> [[@LINE-2]]:124, [[@LINE-2]]:129 -> [[@LINE-2]]:136, [[@LINE-2]]:142 -> [[@LINE-2]]:148
+  } bar: ^  {
+   [globalObject message] = ([self onEntity: globalArray[i] class: 12 foo: "string"]);
+  // CHECK8: [[@LINE-1]]:36 -> [[@LINE-1]]:44, [[@LINE-1]]:61 -> [[@LINE-1]]:66, [[@LINE-1]]:71 -> [[@LINE-1]]:74
+
+ } bar: ^ () {
+   some_type_t foo = [self perform: 12 bar: (^ () {
+  }) bar: ^  {
+  } perform: @"string literal" test: "]" + 12];
+  // CHECK9: [[@LINE-3]]:28 -> [[@LINE-3]]:35, [[@LINE-3]]:40 -> [[@LINE-3]]:43, [[@LINE-2]]:6 -> [[@LINE-2]]:9, [[@LINE-1]]:5 -> [[@LINE-1]]:12, [[@LINE-1]]:32 -> [[@LINE-1]]:36
+
+ }];
+  // CHECK10: [[@LINE-14]]:19 -> [[@LINE-14]]:23, [[@LINE-14]]:29 -> [[@LINE-14]]:35, [[@LINE-11]]:5 -> [[@LINE-11]]:8, [[@LINE-7]]:4 -> [[@LINE-7]]:7
+  [self piece: @"string literal" method: globalArray[i] method: "string" class: globalArray[i]];
+  // CHECK11: [[@LINE-1]]:9 -> [[@LINE-1]]:14, [[@LINE-1]]:34 -> [[@LINE-1]]:40, [[@LINE-1]]:57 -> [[@LINE-1]]:63, [[@LINE-1]]:74 -> [[@LINE-1]]:79
+}
+// RUN: clang-refactor-test rename-indexed-file -name=test:method:test:world -new-name=a_200:struct:perform:piece -indexed-file=%s -indexed-at=33:18 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:piece:foo -new-name=world:onEntity:name -indexed-file=%s -indexed-at=35:71 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:onEntity -new-name=class:object -indexed-file=%s -indexed-at=35:16 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:a_200:class:perform:object -new-name=method:perform:class:foo:name -indexed-file=%s -indexed-at=39:74 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK7 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:class:foo -new-name=piece:onEntity:bar -indexed-file=%s -indexed-at=43:36 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK8 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:bar:bar:perform:test -new-name=foo:world:class:struct:z_Z_42 -indexed-file=%s -indexed-at=47:28 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK9 %s
+// RUN: clang-refactor-test rename-indexed-file -name=name:z_Z_42:bar:bar -new-name=world:piece:perform:test -indexed-file=%s -indexed-at=39:19 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK10 %s
+// RUN: clang-refactor-test rename-indexed-file -name=piece:method:method:class -new-name=a_200:withSomething:onEntity:onEntity -indexed-file=%s -indexed-at=54:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK11 %s
+
++(int) struct {
+  call() = [self name: ^ () {    const Object & piece = 12;
+  } perform: @{ @1, @3 } a_200: ^  {
+   some_type_t foo = [self name: ']' name: ^ () {
+  } method: ']'];
+  // CHECK12: [[@LINE-2]]:28 -> [[@LINE-2]]:32, [[@LINE-2]]:38 -> [[@LINE-2]]:42, [[@LINE-1]]:5 -> [[@LINE-1]]:11
+
+ }];
+  // CHECK13: [[@LINE-7]]:18 -> [[@LINE-7]]:22, [[@LINE-6]]:5 -> [[@LINE-6]]:12, [[@LINE-6]]:26 -> [[@LINE-6]]:31
+}
+// RUN: clang-refactor-test rename-indexed-file -name=name:name:method -new-name=part:bar:usingThing -indexed-file=%s -indexed-at=69:28 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK12 %s
+// RUN: clang-refactor-test rename-indexed-file -name=name:perform:a_200 -new-name=a_200:piece:class -indexed-file=%s -indexed-at=67:18 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK13 %s
+
++(BOOL) world {
+  int bar = ([_undef_ivar world: "string" struct: @"string literal" world: globalArray[i]
+ perform: ^  {    // comment
+  } < "string" name: [] () {
+   int bar = [self a_200: "string" * 12 method: globalArray[i] usingThing: @"string literal" part: ']'];
+  // CHECK14: [[@LINE-1]]:20 -> [[@LINE-1]]:25, [[@LINE-1]]:41 -> [[@LINE-1]]:47, [[@LINE-1]]:64 -> [[@LINE-1]]:74, [[@LINE-1]]:94 -> [[@LINE-1]]:98
+
+ }]);
+  // CHECK15: [[@LINE-7]]:27 -> [[@LINE-7]]:32, [[@LINE-7]]:43 -> [[@LINE-7]]:49, [[@LINE-7]]:69 -> [[@LINE-7]]:74, [[@LINE-6]]:2 -> [[@LINE-6]]:9, [[@LINE-5]]:16 -> [[@LINE-5]]:20
+  [self perform: [self object: globalArray[i] onEntity: /*]*/ [] () {
+   ; ;[self.undef_property test: [] () {
+
+
+ } onEntity: @"string literal"
+];
+  // CHECK16: [[@LINE-5]]:28 -> [[@LINE-5]]:32, [[@LINE-2]]:4 -> [[@LINE-2]]:12
+
+ } method: "]"] world: "]" withSomething: @"string literal"];
+  // CHECK17: [[@LINE-9]]:24 -> [[@LINE-9]]:30, [[@LINE-9]]:47 -> [[@LINE-9]]:55, [[@LINE-1]]:4 -> [[@LINE-1]]:10
+  // CHECK18: [[@LINE-10]]:9 -> [[@LINE-10]]:16, [[@LINE-2]]:17 -> [[@LINE-2]]:22, [[@LINE-2]]:28 -> [[@LINE-2]]:41
+  [self usingThing: ^  {
+   ;
+
+ } world: "string" test: "]"];
+  // CHECK19: [[@LINE-4]]:9 -> [[@LINE-4]]:19, [[@LINE-1]]:4 -> [[@LINE-1]]:9, [[@LINE-1]]:20 -> [[@LINE-1]]:24
+  call() = [self bar: []  {    globalArray[12] = [self onEntity: ^ () { ] } foo: "string" piece: @{ @1, @3 } bar: ']'];
+  // CHECK20: [[@LINE-1]]:56 -> [[@LINE-1]]:64, [[@LINE-1]]:77 -> [[@LINE-1]]:80, [[@LINE-1]]:91 -> [[@LINE-1]]:96, [[@LINE-1]]:110 -> [[@LINE-1]]:113
+  }
+//comment
+ struct: []  {    return ^ () {
+  };
+  } piece: "string" onEntity: ^ () { ] }];
+  // CHECK21: [[@LINE-7]]:18 -> [[@LINE-7]]:21, [[@LINE-3]]:2 -> [[@LINE-3]]:8, [[@LINE-1]]:5 -> [[@LINE-1]]:10, [[@LINE-1]]:21 -> [[@LINE-1]]:29
+  some_type_t foo = [_undef_ivar world: 12
+ bar: [] () {
+   [globalObject send: [super class: 12 world: [self perform: 12 perform: @{ @1, @3 }
+ object: "string"] class: "string" z_Z_42: @{ @1, @3 }] other: 42];
+  // CHECK22: [[@LINE-2]]:54 -> [[@LINE-2]]:61, [[@LINE-2]]:66 -> [[@LINE-2]]:73, [[@LINE-1]]:2 -> [[@LINE-1]]:8
+  // CHECK23: [[@LINE-3]]:31 -> [[@LINE-3]]:36, [[@LINE-3]]:41 -> [[@LINE-3]]:46, [[@LINE-2]]:20 -> [[@LINE-2]]:25, [[@LINE-2]]:36 -> [[@LINE-2]]:42
+
+ }];
+  // CHECK24: [[@LINE-8]]:34 -> [[@LINE-8]]:39, [[@LINE-7]]:2 -> [[@LINE-7]]:5
+}
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:method:usingThing:part -new-name=foo:bar:bar:class -indexed-file=%s -indexed-at=83:20 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK14 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:struct:world:perform:name -new-name=perform:bar:object:foo:object -indexed-file=%s -indexed-at=80:27 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK15 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:onEntity -new-name=name:class -indexed-file=%s -indexed-at=89:28 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK16 %s
+// RUN: clang-refactor-test rename-indexed-file -name=object:onEntity:method -new-name=usingThing:a_200:onEntity -indexed-file=%s -indexed-at=88:24 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK17 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:world:withSomething -new-name=onEntity:method:part -indexed-file=%s -indexed-at=88:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK18 %s
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:world:test -new-name=name:object:onEntity -indexed-file=%s -indexed-at=99:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK19 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:foo:piece:bar -new-name=test:foo:test:name -indexed-file=%s -indexed-at=104:56 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK20 %s
+// RUN: clang-refactor-test rename-indexed-file -name=bar:struct:piece:onEntity -new-name=usingThing:method:part:piece -indexed-file=%s -indexed-at=104:18 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK21 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:perform:object -new-name=usingThing:withSomething:withSomething -indexed-file=%s -indexed-at=114:54 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK22 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:world:class:z_Z_42 -new-name=bar:piece:class:z_Z_42 -indexed-file=%s -indexed-at=114:31 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK23 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:bar -new-name=foo:bar -indexed-file=%s -indexed-at=112:34 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK24 %s
+
+-(void) test {
+  call() = [self name: globalArray[i] onEntity: "]" bar: ^  {    return [self withSomething: [] () {
+
+
+ } name: ']' part: 12];
+  // CHECK25: [[@LINE-4]]:79 -> [[@LINE-4]]:92, [[@LINE-1]]:4 -> [[@LINE-1]]:8, [[@LINE-1]]:14 -> [[@LINE-1]]:18
+  } usingThing: "]" object: ];
+  // CHECK26: [[@LINE-6]]:18 -> [[@LINE-6]]:22, [[@LINE-6]]:39 -> [[@LINE-6]]:47, [[@LINE-6]]:53 -> [[@LINE-6]]:56, [[@LINE-1]]:5 -> [[@LINE-1]]:15, [[@LINE-1]]:21 -> [[@LINE-1]]:27
+  [globalObject message] = [self a_200: globalArray[i] struct: @{ @1, @3 }
+];
+  // CHECK27: [[@LINE-2]]:34 -> [[@LINE-2]]:39, [[@LINE-2]]:56 -> [[@LINE-2]]:62
+}
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:name:part -new-name=z_Z_42:object:test -indexed-file=%s -indexed-at=135:79 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK25 %s
+// RUN: clang-refactor-test rename-indexed-file -name=name:onEntity:bar:usingThing:object -new-name=foo:method:perform:onEntity:perform -indexed-file=%s -indexed-at=135:18 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK26 %s
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:struct -new-name=bar:perform -indexed-file=%s -indexed-at=142:34 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK27 %s
+
+-(int) class {
+  return /*]*/ [] () {
+   call() = [self struct: (@"string literal") method: ^ () {
+  } foo: @"string literal" onEntity: []  {
+
+
+ } < globalArray[i] method: ']'];
+  // CHECK28: [[@LINE-5]]:19 -> [[@LINE-5]]:25, [[@LINE-5]]:47 -> [[@LINE-5]]:53, [[@LINE-4]]:5 -> [[@LINE-4]]:8, [[@LINE-4]]:28 -> [[@LINE-4]]:36, [[@LINE-1]]:21 -> [[@LINE-1]]:27
+
+ };
+  [self name: [] () {    if ([]  {
+
+
+ }) {
+      BOOL class = @{ @1, @3 };
+
+  }
+  } perform: 12 onEntity: @"string literal"];
+  // CHECK29: [[@LINE-8]]:9 -> [[@LINE-8]]:13, [[@LINE-1]]:5 -> [[@LINE-1]]:12, [[@LINE-1]]:17 -> [[@LINE-1]]:25
+  return globalArray[i] * [self withSomething: [self part: 12 name: ^  {    [globalObject send: [super withSomething: [self test: [] () {
+
+
+ } world: [_undef_ivar piece: 12 class: @"string literal" test: "string" bar: /*]*/ globalArray[i]]
+] withSomething: 12 name: ']' test: "]" usingThing: @"string literal"] other: 42];
+  // CHECK30: [[@LINE-2]]:24 -> [[@LINE-2]]:29, [[@LINE-2]]:34 -> [[@LINE-2]]:39, [[@LINE-2]]:59 -> [[@LINE-2]]:63, [[@LINE-2]]:74 -> [[@LINE-2]]:77
+  // CHECK31: [[@LINE-6]]:125 -> [[@LINE-6]]:129, [[@LINE-3]]:4 -> [[@LINE-3]]:9
+  // CHECK32: [[@LINE-7]]:104 -> [[@LINE-7]]:117, [[@LINE-3]]:3 -> [[@LINE-3]]:16, [[@LINE-3]]:21 -> [[@LINE-3]]:25, [[@LINE-3]]:31 -> [[@LINE-3]]:35, [[@LINE-3]]:41 -> [[@LINE-3]]:51
+  } part: @{ @1, @3 }] withSomething: ']' foo: globalArray[i]];
+  // CHECK33: [[@LINE-9]]:54 -> [[@LINE-9]]:58, [[@LINE-9]]:63 -> [[@LINE-9]]:67, [[@LINE-1]]:5 -> [[@LINE-1]]:9
+  // CHECK34: [[@LINE-10]]:33 -> [[@LINE-10]]:46, [[@LINE-2]]:24 -> [[@LINE-2]]:37, [[@LINE-2]]:43 -> [[@LINE-2]]:46
+}
+// RUN: clang-refactor-test rename-indexed-file -name=struct:method:foo:onEntity:method -new-name=object:piece:struct:foo:name -indexed-file=%s -indexed-at=152:19 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK28 %s
+// RUN: clang-refactor-test rename-indexed-file -name=name:perform:onEntity -new-name=z_Z_42:bar:z_Z_42 -indexed-file=%s -indexed-at=160:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK29 %s
+// RUN: clang-refactor-test rename-indexed-file -name=piece:class:test:bar -new-name=world:bar:object:perform -indexed-file=%s -indexed-at=172:24 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK30 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:world -new-name=a_200:bar -indexed-file=%s -indexed-at=169:125 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK31 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:withSomething:name:test:usingThing -new-name=bar:class:class:perform:perform -indexed-file=%s -indexed-at=169:104 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK32 %s
+// RUN: clang-refactor-test rename-indexed-file -name=part:name:part -new-name=class:perform:name -indexed-file=%s -indexed-at=169:54 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK33 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:withSomething:foo -new-name=test:object:withSomething -indexed-file=%s -indexed-at=169:33 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK34 %s
+
++(Object *) usingThing {
+  return "string";
+}
+
++(void) class {
+  if (@{ @1, @3 }) {
+      globalArray[12] = [self foo: []  {    [globalObject message] = [self object: @{ @1, @3 } usingThing: globalArray[i] perform: "]"];
+  // CHECK35: [[@LINE-1]]:76 -> [[@LINE-1]]:82, [[@LINE-1]]:96 -> [[@LINE-1]]:106, [[@LINE-1]]:123 -> [[@LINE-1]]:130
+  } class:  usingThing: "]" perform: [self.undef_property name: ^ () { ] } piece: 12 name: ^ () {
+   globalArray[12] = [_undef_ivar foo: ']' foo: []  {
+  }
+ bar: ^  {
+  } + []  {
+
+
+ }
+];
+  // CHECK36: [[@LINE-8]]:35 -> [[@LINE-8]]:38, [[@LINE-8]]:44 -> [[@LINE-8]]:47, [[@LINE-6]]:2 -> [[@LINE-6]]:5
+
+ }]];
+  // CHECK37: [[@LINE-12]]:59 -> [[@LINE-12]]:63, [[@LINE-12]]:76 -> [[@LINE-12]]:81, [[@LINE-12]]:86 -> [[@LINE-12]]:90
+  // CHECK38: [[@LINE-15]]:31 -> [[@LINE-15]]:34, [[@LINE-13]]:5 -> [[@LINE-13]]:10, [[@LINE-13]]:13 -> [[@LINE-13]]:23, [[@LINE-13]]:29 -> [[@LINE-13]]:36
+
+  }
+}
+// RUN: clang-refactor-test rename-indexed-file -name=object:usingThing:perform -new-name=test:object:z_Z_42 -indexed-file=%s -indexed-at=195:76 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK35 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:foo:bar -new-name=method:part:class -indexed-file=%s -indexed-at=198:35 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK36 %s
+// RUN: clang-refactor-test rename-indexed-file -name=name:piece:name -new-name=perform:onEntity:struct -indexed-file=%s -indexed-at=197:59 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK37 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:class:usingThing:perform -new-name=name:z_Z_42:method:test -indexed-file=%s -indexed-at=195:31 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK38 %s
+
+-(some_type_t) struct {
+  globalArray[12] = [super a_200: globalArray[i]
+ name: globalArray[i] world: []  {
+   [globalObject send: [self part: ']' z_Z_42: ^  {
+  } + "]" struct: "string"
+ bar: [] () {
+
+
+ }] other: 42];
+  // CHECK39: [[@LINE-6]]:30 -> [[@LINE-6]]:34, [[@LINE-6]]:40 -> [[@LINE-6]]:46, [[@LINE-5]]:11 -> [[@LINE-5]]:17, [[@LINE-4]]:2 -> [[@LINE-4]]:5
+
+ } onEntity: ']' == globalArray[i]];
+  // CHECK40: [[@LINE-11]]:28 -> [[@LINE-11]]:33, [[@LINE-10]]:2 -> [[@LINE-10]]:6, [[@LINE-10]]:23 -> [[@LINE-10]]:28, [[@LINE-1]]:4 -> [[@LINE-1]]:12
+  [self a_200: [] () {    BOOL class = 12;
+  } part: ']' test: ^ () {    int z_Z_42 = [self struct: "]" perform: "]" method: globalArray[i]];
+  // CHECK41: [[@LINE-1]]:50 -> [[@LINE-1]]:56, [[@LINE-1]]:62 -> [[@LINE-1]]:69, [[@LINE-1]]:75 -> [[@LINE-1]]:81
+  }];
+  // CHECK42: [[@LINE-4]]:9 -> [[@LINE-4]]:14, [[@LINE-3]]:5 -> [[@LINE-3]]:9, [[@LINE-3]]:15 -> [[@LINE-3]]:19
+}
+// RUN: clang-refactor-test rename-indexed-file -name=part:z_Z_42:struct:bar -new-name=world:a_200:a_200:test -indexed-file=%s -indexed-at=222:30 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK39 %s
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:name:world:onEntity -new-name=object:object:perform:z_Z_42 -indexed-file=%s -indexed-at=220:28 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK40 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:perform:method -new-name=perform:test:bar -indexed-file=%s -indexed-at=233:50 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK41 %s
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:part:test -new-name=class:method:test -indexed-file=%s -indexed-at=232:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK42 %s
+
++(some_type_t) piece {
+  call() = [self class: "string" part: 12];
+  // CHECK43: [[@LINE-1]]:18 -> [[@LINE-1]]:23, [[@LINE-1]]:34 -> [[@LINE-1]]:38
+  [self struct: globalArray[i] part: "]" part: [self method: @"string literal" == globalArray[i] + [self onEntity: ^  {    [_undef_ivar piece: @{ @1, @3 } world: globalArray[i]];
+  // CHECK44: [[@LINE-1]]:137 -> [[@LINE-1]]:142, [[@LINE-1]]:156 -> [[@LINE-1]]:161
+  } object: (^ () {    [self class: 12 object: []  {
+
+
+ } == ^ () {
+
+
+ }];
+  // CHECK45: [[@LINE-7]]:30 -> [[@LINE-7]]:35, [[@LINE-7]]:40 -> [[@LINE-7]]:46
+  }) piece: ']' world: 12 part: (12)] struct: /*]*/ globalArray[i] foo: [self object: ^  {    // comment
+  // CHECK46: [[@LINE-11]]:106 -> [[@LINE-11]]:114, [[@LINE-9]]:5 -> [[@LINE-9]]:11, [[@LINE-1]]:6 -> [[@LINE-1]]:11, [[@LINE-1]]:17 -> [[@LINE-1]]:22, [[@LINE-1]]:27 -> [[@LINE-1]]:31
+  } world: (^  {
+   int bar = [_undef_ivar test: globalArray[i] + "string" == ']' class: 12];
+  // CHECK47: [[@LINE-1]]:27 -> [[@LINE-1]]:31, [[@LINE-1]]:66 -> [[@LINE-1]]:71
+
+ }) part: ']'
+] perform: "]"] perform: @{ @1, @3 }];
+  // CHECK48: [[@LINE-8]]:79 -> [[@LINE-8]]:85, [[@LINE-6]]:5 -> [[@LINE-6]]:10, [[@LINE-2]]:5 -> [[@LINE-2]]:9
+  // CHECK49: [[@LINE-19]]:54 -> [[@LINE-19]]:60, [[@LINE-9]]:39 -> [[@LINE-9]]:45, [[@LINE-9]]:68 -> [[@LINE-9]]:71, [[@LINE-2]]:3 -> [[@LINE-2]]:10
+  // CHECK50: [[@LINE-20]]:9 -> [[@LINE-20]]:15, [[@LINE-20]]:32 -> [[@LINE-20]]:36, [[@LINE-20]]:42 -> [[@LINE-20]]:46, [[@LINE-3]]:17 -> [[@LINE-3]]:24
+  some_type_t foo = [self.undef_property class: "]" part: []  {
+   [self bar: [] () {
+  } z_Z_42: "]" name: globalArray[i]];
+  // CHECK51: [[@LINE-2]]:10 -> [[@LINE-2]]:13, [[@LINE-1]]:5 -> [[@LINE-1]]:11, [[@LINE-1]]:17 -> [[@LINE-1]]:21
+
+ }
+ onEntity: ^  {    return [super withSomething: "string" usingThing: @"string literal" test: @"string literal" withSomething: ']' world: [] () {
+
+
+ }
+];
+  // CHECK52: [[@LINE-5]]:34 -> [[@LINE-5]]:47, [[@LINE-5]]:58 -> [[@LINE-5]]:68, [[@LINE-5]]:88 -> [[@LINE-5]]:92, [[@LINE-5]]:112 -> [[@LINE-5]]:125, [[@LINE-5]]:131 -> [[@LINE-5]]:136
+  } class: 12 struct: @"string literal" == globalArray[i]];
+  // CHECK53: [[@LINE-13]]:42 -> [[@LINE-13]]:47, [[@LINE-13]]:53 -> [[@LINE-13]]:57, [[@LINE-7]]:2 -> [[@LINE-7]]:10, [[@LINE-1]]:5 -> [[@LINE-1]]:10, [[@LINE-1]]:15 -> [[@LINE-1]]:21
+}
+// RUN: clang-refactor-test rename-indexed-file -name=class:part -new-name=a_200:class -indexed-file=%s -indexed-at=244:18 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK43 %s
+// RUN: clang-refactor-test rename-indexed-file -name=piece:world -new-name=part:name -indexed-file=%s -indexed-at=246:137 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK44 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:object -new-name=onEntity:z_Z_42 -indexed-file=%s -indexed-at=248:30 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK45 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:object:piece:world:part -new-name=onEntity:piece:a_200:class:struct -indexed-file=%s -indexed-at=246:106 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK46 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:class -new-name=a_200:test -indexed-file=%s -indexed-at=259:27 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK47 %s
+// RUN: clang-refactor-test rename-indexed-file -name=object:world:part -new-name=class:z_Z_42:onEntity -indexed-file=%s -indexed-at=256:79 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK48 %s
+// RUN: clang-refactor-test rename-indexed-file -name=method:struct:foo:perform -new-name=onEntity:bar:part:test -indexed-file=%s -indexed-at=246:54 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK49 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:part:part:perform -new-name=piece:object:world:usingThing -indexed-file=%s -indexed-at=246:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK50 %s
+// RUN: clang-refactor-test rename-indexed-file -name=bar:z_Z_42:name -new-name=bar:test:struct -indexed-file=%s -indexed-at=268:10 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK51 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:usingThing:test:withSomething:world -new-name=foo:test:usingThing:piece:piece -indexed-file=%s -indexed-at=273:34 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK52 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:part:onEntity:class:struct -new-name=z_Z_42:onEntity:onEntity:a_200:class -indexed-file=%s -indexed-at=267:42 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK53 %s
+
++(void) z_Z_42 {
+  int a_200 = @{ @1, @3 };
+  // comment
+  [globalObject send: ([self onEntity: [] () {    [super onEntity: ^  {
+  } class: @"string literal" perform: @"string literal"] other: 42];
+  // CHECK54: [[@LINE-2]]:58 -> [[@LINE-2]]:66, [[@LINE-1]]:5 -> [[@LINE-1]]:10, [[@LINE-1]]:30 -> [[@LINE-1]]:37
+  } class: globalArray[i] a_200: ^ () { ] }
+]);
+  // CHECK55: [[@LINE-5]]:30 -> [[@LINE-5]]:38, [[@LINE-2]]:5 -> [[@LINE-2]]:10, [[@LINE-2]]:27 -> [[@LINE-2]]:32
+  globalArray[12] = [super method: @"string literal" test: ^ () {    [self struct: "]" method: globalArray[i]];
+  // CHECK56: [[@LINE-1]]:76 -> [[@LINE-1]]:82, [[@LINE-1]]:88 -> [[@LINE-1]]:94
+  } name: globalArray[i]];
+  // CHECK57: [[@LINE-3]]:28 -> [[@LINE-3]]:34, [[@LINE-3]]:54 -> [[@LINE-3]]:58, [[@LINE-1]]:5 -> [[@LINE-1]]:9
+  BOOL struct = 12;
+}
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:class:perform -new-name=bar:z_Z_42:onEntity -indexed-file=%s -indexed-at=297:58 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK54 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:class:a_200 -new-name=withSomething:piece:foo -indexed-file=%s -indexed-at=297:30 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK55 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:method -new-name=onEntity:struct -indexed-file=%s -indexed-at=303:76 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK56 %s
+// RUN: clang-refactor-test rename-indexed-file -name=method:test:name -new-name=name:z_Z_42:object -indexed-file=%s -indexed-at=303:28 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK57 %s
+
++(int) onEntity {
+  call() = [self piece: []  {    return "string";
+  } foo: ']' bar: globalArray[i]];
+  // CHECK58: [[@LINE-2]]:18 -> [[@LINE-2]]:23, [[@LINE-1]]:5 -> [[@LINE-1]]:8, [[@LINE-1]]:14 -> [[@LINE-1]]:17
+  [globalObject send: [self usingThing: []  {
+   [_undef_ivar test: globalArray[i] part: 12 world: "string" onEntity: 12] other: 42];
+  // CHECK59: [[@LINE-1]]:17 -> [[@LINE-1]]:21, [[@LINE-1]]:38 -> [[@LINE-1]]:42, [[@LINE-1]]:47 -> [[@LINE-1]]:52, [[@LINE-1]]:63 -> [[@LINE-1]]:71
+
+ } a_200: @"string literal" a_200: "string" object: ("string")
+//comment
+];
+  // CHECK60: [[@LINE-7]]:29 -> [[@LINE-7]]:39, [[@LINE-3]]:4 -> [[@LINE-3]]:9, [[@LINE-3]]:29 -> [[@LINE-3]]:34, [[@LINE-3]]:45 -> [[@LINE-3]]:51
+  [globalObject send: [super object: ']' name: ^  {
+   [globalObject send: [self.undef_property bar:  == [self name: "string" bar: ']']
+ part: @"string literal" z_Z_42: ']' part: ']' test: "string"] other: 42] other: 42];
+  // CHECK61: [[@LINE-2]]:60 -> [[@LINE-2]]:64, [[@LINE-2]]:75 -> [[@LINE-2]]:78
+  // CHECK62: [[@LINE-3]]:45 -> [[@LINE-3]]:48, [[@LINE-2]]:2 -> [[@LINE-2]]:6, [[@LINE-2]]:26 -> [[@LINE-2]]:32, [[@LINE-2]]:38 -> [[@LINE-2]]:42, [[@LINE-2]]:48 -> [[@LINE-2]]:52
+
+ }
+ object: globalArray[i] foo: (']')];
+  // CHECK63: [[@LINE-8]]:30 -> [[@LINE-8]]:36, [[@LINE-8]]:42 -> [[@LINE-8]]:46, [[@LINE-1]]:2 -> [[@LINE-1]]:8, [[@LINE-1]]:25 -> [[@LINE-1]]:28
+  [self.undef_property world: globalArray[i] onEntity: ']' object: @"string literal" == 12 struct: []  {
+   int bar = [self onEntity: "]" piece: [] () {
+  }];
+  // CHECK64: [[@LINE-2]]:20 -> [[@LINE-2]]:28, [[@LINE-2]]:34 -> [[@LINE-2]]:39
+
+ } struct: @"string literal"];
+  // CHECK65: [[@LINE-6]]:24 -> [[@LINE-6]]:29, [[@LINE-6]]:46 -> [[@LINE-6]]:54, [[@LINE-6]]:60 -> [[@LINE-6]]:66, [[@LINE-6]]:92 -> [[@LINE-6]]:98, [[@LINE-1]]:4 -> [[@LINE-1]]:10
+}
+// RUN: clang-refactor-test rename-indexed-file -name=piece:foo:bar -new-name=class:onEntity:method -indexed-file=%s -indexed-at=315:18 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK58 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:part:world:onEntity -new-name=z_Z_42:bar:piece:perform -indexed-file=%s -indexed-at=319:17 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK59 %s
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:a_200:a_200:object -new-name=a_200:object:method:perform -indexed-file=%s -indexed-at=318:29 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK60 %s
+// RUN: clang-refactor-test rename-indexed-file -name=name:bar -new-name=z_Z_42:z_Z_42 -indexed-file=%s -indexed-at=327:60 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK61 %s
+// RUN: clang-refactor-test rename-indexed-file -name=bar:part:z_Z_42:part:test -new-name=name:a_200:bar:name:z_Z_42 -indexed-file=%s -indexed-at=327:45 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK62 %s
+// RUN: clang-refactor-test rename-indexed-file -name=object:name:object:foo -new-name=z_Z_42:object:usingThing:world -indexed-file=%s -indexed-at=326:30 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK63 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:piece -new-name=struct:piece -indexed-file=%s -indexed-at=336:20 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK64 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:onEntity:object:struct:struct -new-name=withSomething:test:foo:object:bar -indexed-file=%s -indexed-at=335:24 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK65 %s
+
++(const Object &) object {
+  globalArray[12] = [self world: globalArray[i] object: ']' usingThing:  usingThing: globalArray[i]];
+  // CHECK66: [[@LINE-1]]:27 -> [[@LINE-1]]:32, [[@LINE-1]]:49 -> [[@LINE-1]]:55, [[@LINE-1]]:61 -> [[@LINE-1]]:71, [[@LINE-1]]:74 -> [[@LINE-1]]:84
+  globalArray[12] = ([self.undef_property struct: ']' usingThing: "string"]);
+  // CHECK67: [[@LINE-1]]:43 -> [[@LINE-1]]:49, [[@LINE-1]]:55 -> [[@LINE-1]]:65
+}
+// RUN: clang-refactor-test rename-indexed-file -name=world:object:usingThing:usingThing -new-name=a_200:struct:test:z_Z_42 -indexed-file=%s -indexed-at=353:27 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK66 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:usingThing -new-name=struct:a_200 -indexed-file=%s -indexed-at=355:43 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK67 %s
+
+-(void) part {
+  [self.undef_property withSomething: "string" method: []  {    call() = [self.undef_property object: @"string literal" test: 12
+ test: globalArray[i]];
+  // CHECK68: [[@LINE-2]]:95 -> [[@LINE-2]]:101, [[@LINE-2]]:121 -> [[@LINE-2]]:125, [[@LINE-1]]:2 -> [[@LINE-1]]:6
+  }];
+  // CHECK69: [[@LINE-4]]:24 -> [[@LINE-4]]:37, [[@LINE-4]]:48 -> [[@LINE-4]]:54
+}
+// RUN: clang-refactor-test rename-indexed-file -name=object:test:test -new-name=piece:bar:a_200 -indexed-file=%s -indexed-at=362:95 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK68 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:method -new-name=withSomething:test -indexed-file=%s -indexed-at=362:24 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK69 %s
+
++(BOOL) method {
+  [self object: ^ () { ] } a_200: "]" foo: @{ @1, @3 } piece: []  {    [self.undef_property a_200: 12 foo: 12 withSomething: globalArray[i] onEntity: ']' struct: 12];
+  // CHECK70: [[@LINE-1]]:93 -> [[@LINE-1]]:98, [[@LINE-1]]:103 -> [[@LINE-1]]:106, [[@LINE-1]]:111 -> [[@LINE-1]]:124, [[@LINE-1]]:141 -> [[@LINE-1]]:149, [[@LINE-1]]:155 -> [[@LINE-1]]:161
+  }
+//comment
+];
+  // CHECK71: [[@LINE-5]]:9 -> [[@LINE-5]]:15, [[@LINE-5]]:28 -> [[@LINE-5]]:33, [[@LINE-5]]:39 -> [[@LINE-5]]:42, [[@LINE-5]]:56 -> [[@LINE-5]]:61
+  [super method: 12 struct: ^  {    /*comment*/[super foo: [self bar: @"string literal" method: "string" test: 12 test: "string" world: ']']
+ onEntity: globalArray[i] method: ^  {
+  }];
+  // CHECK72: [[@LINE-3]]:66 -> [[@LINE-3]]:69, [[@LINE-3]]:89 -> [[@LINE-3]]:95, [[@LINE-3]]:106 -> [[@LINE-3]]:110, [[@LINE-3]]:115 -> [[@LINE-3]]:119, [[@LINE-3]]:130 -> [[@LINE-3]]:135
+  // CHECK73: [[@LINE-4]]:55 -> [[@LINE-4]]:58, [[@LINE-3]]:2 -> [[@LINE-3]]:10, [[@LINE-3]]:27 -> [[@LINE-3]]:33
+  } a_200: "string"];
+  // CHECK74: [[@LINE-6]]:10 -> [[@LINE-6]]:16, [[@LINE-6]]:21 -> [[@LINE-6]]:27, [[@LINE-1]]:5 -> [[@LINE-1]]:10
+  if (12) {
+      [self world: "]" usingThing: @"string literal" + [] () {    call() = [_undef_ivar part: "]" usingThing: 12
+];
+  // CHECK75: [[@LINE-2]]:89 -> [[@LINE-2]]:93, [[@LINE-2]]:99 -> [[@LINE-2]]:109
+  } foo: 12];
+  // CHECK76: [[@LINE-4]]:13 -> [[@LINE-4]]:18, [[@LINE-4]]:24 -> [[@LINE-4]]:34, [[@LINE-1]]:5 -> [[@LINE-1]]:8
+
+  }
+  [super test: (12) foo: "string" name: []  {
+   return @{ @1, @3 };
+
+ } object: "]"];
+  // CHECK77: [[@LINE-4]]:10 -> [[@LINE-4]]:14, [[@LINE-4]]:21 -> [[@LINE-4]]:24, [[@LINE-4]]:35 -> [[@LINE-4]]:39, [[@LINE-1]]:4 -> [[@LINE-1]]:10
+  return ']';
+}
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:foo:withSomething:onEntity:struct -new-name=world:bar:class:perform:z_Z_42 -indexed-file=%s -indexed-at=372:93 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK70 %s
+// RUN: clang-refactor-test rename-indexed-file -name=object:a_200:foo:piece -new-name=part:withSomething:name:foo -indexed-file=%s -indexed-at=372:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK71 %s
+// RUN: clang-refactor-test rename-indexed-file -name=bar:method:test:test:world -new-name=withSomething:perform:usingThing:usingThing:method -indexed-file=%s -indexed-at=378:66 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK72 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:onEntity:method -new-name=foo:name:a_200 -indexed-file=%s -indexed-at=378:55 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK73 %s
+// RUN: clang-refactor-test rename-indexed-file -name=method:struct:a_200 -new-name=method:z_Z_42:struct -indexed-file=%s -indexed-at=378:10 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK74 %s
+// RUN: clang-refactor-test rename-indexed-file -name=part:usingThing -new-name=withSomething:name -indexed-file=%s -indexed-at=386:89 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK75 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:usingThing:foo -new-name=usingThing:method:class -indexed-file=%s -indexed-at=386:13 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK76 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:foo:name:object -new-name=z_Z_42:world:name:object -indexed-file=%s -indexed-at=393:10 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK77 %s
+
+-(BOOL) object {
+  [self part: @{ @1, @3 } foo: "]" method: ([self a_200: @"string literal" test:  part: globalArray[i] object: "]"]) usingThing: @{ @1, @3 }];
+  // CHECK78: [[@LINE-1]]:51 -> [[@LINE-1]]:56, [[@LINE-1]]:76 -> [[@LINE-1]]:80, [[@LINE-1]]:83 -> [[@LINE-1]]:87, [[@LINE-1]]:104 -> [[@LINE-1]]:110
+  // CHECK79: [[@LINE-2]]:9 -> [[@LINE-2]]:13, [[@LINE-2]]:27 -> [[@LINE-2]]:30, [[@LINE-2]]:36 -> [[@LINE-2]]:42, [[@LINE-2]]:118 -> [[@LINE-2]]:128
+  [self onEntity: [] () {    int bar = [self test: "string"/*comment*/ bar: globalArray[i] method: [] () {
+  }];
+  // CHECK80: [[@LINE-2]]:46 -> [[@LINE-2]]:50, [[@LINE-2]]:72 -> [[@LINE-2]]:75, [[@LINE-2]]:92 -> [[@LINE-2]]:98
+  } part: @"string literal" perform: [self.undef_property onEntity: globalArray[i] test: []  {
+   if ("]") {
+      [super foo: "string" z_Z_42: 12];
+  // CHECK81: [[@LINE-1]]:14 -> [[@LINE-1]]:17, [[@LINE-1]]:28 -> [[@LINE-1]]:34
+
+  }
+
+ } method: @"string literal" usingThing: ^ () {
+   Object * method = globalArray[i];
+
+ }]];
+  // CHECK82: [[@LINE-11]]:59 -> [[@LINE-11]]:67, [[@LINE-11]]:84 -> [[@LINE-11]]:88, [[@LINE-4]]:4 -> [[@LINE-4]]:10, [[@LINE-4]]:30 -> [[@LINE-4]]:40
+  // CHECK83: [[@LINE-15]]:9 -> [[@LINE-15]]:17, [[@LINE-12]]:5 -> [[@LINE-12]]:9, [[@LINE-12]]:29 -> [[@LINE-12]]:36
+  [self usingThing: ^ () {    int bar = [self onEntity: [self.undef_property perform: "]"
+ struct: [self name: "string" withSomething: ^ () {
+
+
+ }]] foo: ']' object: [_undef_ivar world: [super withSomething: (@{ @1, @3 }) name: @"string literal"
+] onEntity: [super perform: "string" class: @"string literal"]] usingThing: 12 == @"string literal"
+];
+  // CHECK84: [[@LINE-6]]:16 -> [[@LINE-6]]:20, [[@LINE-6]]:31 -> [[@LINE-6]]:44
+  // CHECK85: [[@LINE-8]]:78 -> [[@LINE-8]]:85, [[@LINE-7]]:2 -> [[@LINE-7]]:8
+  // CHECK86: [[@LINE-5]]:50 -> [[@LINE-5]]:63, [[@LINE-5]]:79 -> [[@LINE-5]]:83
+  // CHECK87: [[@LINE-5]]:20 -> [[@LINE-5]]:27, [[@LINE-5]]:38 -> [[@LINE-5]]:43
+  // CHECK88: [[@LINE-7]]:36 -> [[@LINE-7]]:41, [[@LINE-6]]:3 -> [[@LINE-6]]:11
+  // CHECK89: [[@LINE-12]]:47 -> [[@LINE-12]]:55, [[@LINE-8]]:6 -> [[@LINE-8]]:9, [[@LINE-8]]:15 -> [[@LINE-8]]:21, [[@LINE-7]]:65 -> [[@LINE-7]]:75
+  } withSomething: "string" world: "string"];
+  // CHECK90: [[@LINE-14]]:9 -> [[@LINE-14]]:19, [[@LINE-1]]:5 -> [[@LINE-1]]:18, [[@LINE-1]]:29 -> [[@LINE-1]]:34
+  globalArray[12] = [self.undef_property bar: "string" z_Z_42: ^  {
+   [self class: ']' struct: @{ @1, @3 }
+ withSomething: ']' class: (']') world: @{ @1, @3 }];
+  // CHECK91: [[@LINE-2]]:10 -> [[@LINE-2]]:15, [[@LINE-2]]:21 -> [[@LINE-2]]:27, [[@LINE-1]]:2 -> [[@LINE-1]]:15, [[@LINE-1]]:21 -> [[@LINE-1]]:26, [[@LINE-1]]:34 -> [[@LINE-1]]:39
+
+ }
+ a_200: [] () {    ; ;[_undef_ivar class: ']' struct: ^  {
+  } z_Z_42: [super withSomething: ^  {
+
+
+ } foo: globalArray[i] perform: (@"string literal") perform: 12]];
+  // CHECK92: [[@LINE-4]]:20 -> [[@LINE-4]]:33, [[@LINE-1]]:4 -> [[@LINE-1]]:7, [[@LINE-1]]:24 -> [[@LINE-1]]:31, [[@LINE-1]]:53 -> [[@LINE-1]]:60
+  // CHECK93: [[@LINE-6]]:36 -> [[@LINE-6]]:41, [[@LINE-6]]:47 -> [[@LINE-6]]:53, [[@LINE-5]]:5 -> [[@LINE-5]]:11
+  }
+];
+  // CHECK94: [[@LINE-15]]:42 -> [[@LINE-15]]:45, [[@LINE-15]]:56 -> [[@LINE-15]]:62, [[@LINE-9]]:2 -> [[@LINE-9]]:7
+}
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:test:part:object -new-name=object:a_200:object:object -indexed-file=%s -indexed-at=410:51 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK78 %s
+// RUN: clang-refactor-test rename-indexed-file -name=part:foo:method:usingThing -new-name=world:onEntity:foo:a_200 -indexed-file=%s -indexed-at=410:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK79 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:bar:method -new-name=object:method:withSomething -indexed-file=%s -indexed-at=413:46 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK80 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:z_Z_42 -new-name=foo:class -indexed-file=%s -indexed-at=418:14 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK81 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:test:method:usingThing -new-name=class:a_200:class:object -indexed-file=%s -indexed-at=416:59 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK82 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:part:perform -new-name=name:z_Z_42:class -indexed-file=%s -indexed-at=413:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK83 %s
+// RUN: clang-refactor-test rename-indexed-file -name=name:withSomething -new-name=withSomething:z_Z_42 -indexed-file=%s -indexed-at=430:16 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK84 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:struct -new-name=usingThing:struct -indexed-file=%s -indexed-at=429:78 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK85 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:name -new-name=name:foo -indexed-file=%s -indexed-at=433:50 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK86 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:class -new-name=test:z_Z_42 -indexed-file=%s -indexed-at=434:20 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK87 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:onEntity -new-name=foo:z_Z_42 -indexed-file=%s -indexed-at=433:36 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK88 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:foo:object:usingThing -new-name=test:part:struct:object -indexed-file=%s -indexed-at=429:47 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK89 %s
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:withSomething:world -new-name=a_200:test:struct -indexed-file=%s -indexed-at=429:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK90 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:struct:withSomething:class:world -new-name=test:bar:foo:usingThing:usingThing -indexed-file=%s -indexed-at=445:10 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK91 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:foo:perform:perform -new-name=onEntity:struct:piece:withSomething -indexed-file=%s -indexed-at=451:20 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK92 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:struct:z_Z_42 -new-name=onEntity:method:a_200 -indexed-file=%s -indexed-at=450:36 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK93 %s
+// RUN: clang-refactor-test rename-indexed-file -name=bar:z_Z_42:a_200 -new-name=withSomething:class:z_Z_42 -indexed-file=%s -indexed-at=444:42 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK94 %s
+
++(BOOL) world {
+  ; ;[self struct: []  {    call() = [self part: 12 class: ^  {
+
+
+ } test: ^ () {
+
+
+ } a_200: "string"];
+  // CHECK95: [[@LINE-7]]:44 -> [[@LINE-7]]:48, [[@LINE-7]]:53 -> [[@LINE-7]]:58, [[@LINE-4]]:4 -> [[@LINE-4]]:8, [[@LINE-1]]:4 -> [[@LINE-1]]:9
+  } piece: "string" z_Z_42: []  {    [self onEntity:  struct: ^ () {
+  } world: [_undef_ivar withSomething: globalArray[i] piece: ^  {
+
+
+ } method:
+ part: @"string literal" world: @"string literal"
+]];
+  // CHECK96: [[@LINE-6]]:25 -> [[@LINE-6]]:38, [[@LINE-6]]:55 -> [[@LINE-6]]:60, [[@LINE-3]]:4 -> [[@LINE-3]]:10, [[@LINE-2]]:2 -> [[@LINE-2]]:6, [[@LINE-2]]:26 -> [[@LINE-2]]:31
+  // CHECK97: [[@LINE-8]]:44 -> [[@LINE-8]]:52, [[@LINE-8]]:55 -> [[@LINE-8]]:61, [[@LINE-7]]:5 -> [[@LINE-7]]:10
+  }];
+  // CHECK98: [[@LINE-18]]:12 -> [[@LINE-18]]:18, [[@LINE-10]]:5 -> [[@LINE-10]]:10, [[@LINE-10]]:21 -> [[@LINE-10]]:27
+  if (globalArray[i]) {
+      ([_undef_ivar world: ']' class:  usingThing: 12]);
+  // CHECK99: [[@LINE-1]]:21 -> [[@LINE-1]]:26, [[@LINE-1]]:32 -> [[@LINE-1]]:37, [[@LINE-1]]:40 -> [[@LINE-1]]:50
+
+  }
+  some_type_t foo = [self.undef_property object: ']'
+ test: ^ () {
+   globalArray[12] = [_undef_ivar z_Z_42: 12 withSomething: [self a_200: ']' perform: globalArray[i] z_Z_42: []  {
+
+
+ } perform: @"string literal" z_Z_42: globalArray[i]]
+ name: 12];
+  // CHECK100: [[@LINE-5]]:67 -> [[@LINE-5]]:72, [[@LINE-5]]:78 -> [[@LINE-5]]:85, [[@LINE-5]]:102 -> [[@LINE-5]]:108, [[@LINE-2]]:4 -> [[@LINE-2]]:11, [[@LINE-2]]:31 -> [[@LINE-2]]:37
+  // CHECK101: [[@LINE-6]]:35 -> [[@LINE-6]]:41, [[@LINE-6]]:46 -> [[@LINE-6]]:59, [[@LINE-2]]:2 -> [[@LINE-2]]:6
+
+ } bar: "]"
+//comment
+ usingThing: []  {
+   return [self onEntity: 12 < 12 withSomething: []  {
+
+
+ }];
+  // CHECK102: [[@LINE-4]]:17 -> [[@LINE-4]]:25, [[@LINE-4]]:35 -> [[@LINE-4]]:48
+
+ } withSomething: ^  {
+   [super class: ([self.undef_property bar: [self withSomething: [self piece: "string" < globalArray[i] onEntity: [self method: 12
+ part: "string" usingThing: @{ @1, @3 }]] perform: globalArray[i] bar: []  {
+  } name: 12] withSomething: "]"]) world: [] () {
+  } usingThing: "]"];
+  // CHECK103: [[@LINE-4]]:121 -> [[@LINE-4]]:127, [[@LINE-3]]:2 -> [[@LINE-3]]:6, [[@LINE-3]]:17 -> [[@LINE-3]]:27
+  // CHECK104: [[@LINE-5]]:72 -> [[@LINE-5]]:77, [[@LINE-5]]:105 -> [[@LINE-5]]:113
+  // CHECK105: [[@LINE-6]]:51 -> [[@LINE-6]]:64, [[@LINE-5]]:43 -> [[@LINE-5]]:50, [[@LINE-5]]:67 -> [[@LINE-5]]:70, [[@LINE-4]]:5 -> [[@LINE-4]]:9
+  // CHECK106: [[@LINE-7]]:40 -> [[@LINE-7]]:43, [[@LINE-5]]:15 -> [[@LINE-5]]:28
+  // CHECK107: [[@LINE-8]]:11 -> [[@LINE-8]]:16, [[@LINE-6]]:36 -> [[@LINE-6]]:41, [[@LINE-5]]:5 -> [[@LINE-5]]:15
+
+ }];
+  // CHECK108: [[@LINE-31]]:42 -> [[@LINE-31]]:48, [[@LINE-30]]:2 -> [[@LINE-30]]:6, [[@LINE-21]]:4 -> [[@LINE-21]]:7, [[@LINE-19]]:2 -> [[@LINE-19]]:12, [[@LINE-12]]:4 -> [[@LINE-12]]:17
+}
+// RUN: clang-refactor-test rename-indexed-file -name=part:class:test:a_200 -new-name=perform:name:test:struct -indexed-file=%s -indexed-at=480:44 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK95 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:piece:method:part:world -new-name=object:piece:world:piece:world -indexed-file=%s -indexed-at=489:25 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK96 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:struct:world -new-name=onEntity:world:world -indexed-file=%s -indexed-at=488:44 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK97 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:piece:z_Z_42 -new-name=part:object:onEntity -indexed-file=%s -indexed-at=480:12 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK98 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:class:usingThing -new-name=class:struct:method -indexed-file=%s -indexed-at=500:21 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK99 %s
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:perform:z_Z_42:perform:z_Z_42 -new-name=piece:part:piece:class:onEntity -indexed-file=%s -indexed-at=506:67 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK100 %s
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:withSomething:name -new-name=usingThing:onEntity:a_200 -indexed-file=%s -indexed-at=506:35 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK101 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:withSomething -new-name=method:usingThing -indexed-file=%s -indexed-at=517:17 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK102 %s
+// RUN: clang-refactor-test rename-indexed-file -name=method:part:usingThing -new-name=object:piece:method -indexed-file=%s -indexed-at=524:121 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK103 %s
+// RUN: clang-refactor-test rename-indexed-file -name=piece:onEntity -new-name=bar:struct -indexed-file=%s -indexed-at=524:72 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK104 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:perform:bar:name -new-name=usingThing:z_Z_42:class:part -indexed-file=%s -indexed-at=524:51 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK105 %s
+// RUN: clang-refactor-test rename-indexed-file -name=bar:withSomething -new-name=world:perform -indexed-file=%s -indexed-at=524:40 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK106 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:world:usingThing -new-name=object:name:name -indexed-file=%s -indexed-at=524:11 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK107 %s
+// RUN: clang-refactor-test rename-indexed-file -name=object:test:bar:usingThing:withSomething -new-name=bar:piece:class:perform:class -indexed-file=%s -indexed-at=504:42 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK108 %s
+
++(Object *) test {
+  [super foo: globalArray[i] a_200: globalArray[i]
+//comment
+ foo: 12
+ struct: ^ () {
+   [_undef_ivar class: globalArray[i] struct: 12 object: @"string literal" foo: "string"];
+  // CHECK109: [[@LINE-1]]:17 -> [[@LINE-1]]:22, [[@LINE-1]]:39 -> [[@LINE-1]]:45, [[@LINE-1]]:50 -> [[@LINE-1]]:56, [[@LINE-1]]:76 -> [[@LINE-1]]:79
+
+ } * [super struct: [self world: ']' struct: []  {
+   [self method: []  {
+
+
+ } withSomething: "string" usingThing: [] () {
+
+
+ }];
+  // CHECK110: [[@LINE-7]]:10 -> [[@LINE-7]]:16, [[@LINE-4]]:4 -> [[@LINE-4]]:17, [[@LINE-4]]:28 -> [[@LINE-4]]:38
+
+ } struct: ^ () {
+   return [] () {
+  };
+
+ } class: [_undef_ivar part: "string" name: []  {
+   int bar = [self withSomething: "string" bar: @"string literal" usingThing: @"string literal"];
+  // CHECK111: [[@LINE-1]]:20 -> [[@LINE-1]]:33, [[@LINE-1]]:44 -> [[@LINE-1]]:47, [[@LINE-1]]:67 -> [[@LINE-1]]:77
+
+ }] class: "]"] < 12 foo:  * "]"] + "string" + "]" == [] () {
+   some_type_t foo = [_undef_ivar part: 12 name: @"string literal" test: "]" bar: ^  {
+  }];
+  // CHECK112: [[@LINE-7]]:24 -> [[@LINE-7]]:28, [[@LINE-7]]:39 -> [[@LINE-7]]:43
+  // CHECK113: [[@LINE-22]]:27 -> [[@LINE-22]]:32, [[@LINE-22]]:38 -> [[@LINE-22]]:44, [[@LINE-12]]:4 -> [[@LINE-12]]:10, [[@LINE-8]]:4 -> [[@LINE-8]]:9, [[@LINE-4]]:5 -> [[@LINE-4]]:10
+  // CHECK114: [[@LINE-23]]:13 -> [[@LINE-23]]:19, [[@LINE-5]]:22 -> [[@LINE-5]]:25
+  // CHECK115: [[@LINE-5]]:35 -> [[@LINE-5]]:39, [[@LINE-5]]:44 -> [[@LINE-5]]:48, [[@LINE-5]]:68 -> [[@LINE-5]]:72, [[@LINE-5]]:78 -> [[@LINE-5]]:81
+
+ } < ^  {
+   int bar = [self struct: ^ () {
+
+
+ } a_200: @{ @1, @3 }];
+  // CHECK116: [[@LINE-4]]:20 -> [[@LINE-4]]:26, [[@LINE-1]]:4 -> [[@LINE-1]]:9
+
+ } == [super withSomething: []  {    return [_undef_ivar usingThing: [] () {
+  }
+ world: [] () {
+
+
+ } foo: 12 perform: globalArray[i] name: @"string literal"];
+  // CHECK117: [[@LINE-6]]:58 -> [[@LINE-6]]:68, [[@LINE-4]]:2 -> [[@LINE-4]]:7, [[@LINE-1]]:4 -> [[@LINE-1]]:7, [[@LINE-1]]:12 -> [[@LINE-1]]:19, [[@LINE-1]]:36 -> [[@LINE-1]]:40
+  } world: ^  {    // comment
+  } object: ^  {    int method = "]";
+  }
+]];
+  // CHECK118: [[@LINE-11]]:14 -> [[@LINE-11]]:27, [[@LINE-4]]:5 -> [[@LINE-4]]:10, [[@LINE-3]]:5 -> [[@LINE-3]]:11
+  // CHECK119: [[@LINE-52]]:10 -> [[@LINE-52]]:13, [[@LINE-52]]:30 -> [[@LINE-52]]:35, [[@LINE-50]]:2 -> [[@LINE-50]]:5, [[@LINE-49]]:2 -> [[@LINE-49]]:8
+  return []  {    return 12;
+  };
+  if ([]  {
+   some_type_t foo = [_undef_ivar perform: @"string literal" name: globalArray[i] * ']'
+ z_Z_42: "]" perform: globalArray[i] class: globalArray[i]
+];
+  // CHECK120: [[@LINE-3]]:35 -> [[@LINE-3]]:42, [[@LINE-3]]:62 -> [[@LINE-3]]:66, [[@LINE-2]]:2 -> [[@LINE-2]]:8, [[@LINE-2]]:14 -> [[@LINE-2]]:21, [[@LINE-2]]:38 -> [[@LINE-2]]:43
+
+ }) {
+      [globalObject message] = [self.undef_property withSomething: ']' test: @"string literal" onEntity: ^  {
+   return @{ @1, @3 };
+
+ } onEntity: "string"];
+  // CHECK121: [[@LINE-4]]:53 -> [[@LINE-4]]:66, [[@LINE-4]]:72 -> [[@LINE-4]]:76, [[@LINE-4]]:96 -> [[@LINE-4]]:104, [[@LINE-1]]:4 -> [[@LINE-1]]:12
+
+  }
+  [globalObject message] = [self onEntity: "string" onEntity: ^  {    call() = [self withSomething: ^ () {
+  } == ']' perform: ("string") bar: (']')];
+  // CHECK122: [[@LINE-2]]:86 -> [[@LINE-2]]:99, [[@LINE-1]]:12 -> [[@LINE-1]]:19, [[@LINE-1]]:32 -> [[@LINE-1]]:35
+  }
+];
+  // CHECK123: [[@LINE-5]]:34 -> [[@LINE-5]]:42, [[@LINE-5]]:53 -> [[@LINE-5]]:61
+  globalArray[12] = [self withSomething: @"string literal" piece: ^  {
+   call() = [_undef_ivar perform: (12) bar: ^  {
+
+
+ } test: "]" name: "string" bar: "]"];
+  // CHECK124: [[@LINE-4]]:26 -> [[@LINE-4]]:33, [[@LINE-4]]:40 -> [[@LINE-4]]:43, [[@LINE-1]]:4 -> [[@LINE-1]]:8, [[@LINE-1]]:14 -> [[@LINE-1]]:18, [[@LINE-1]]:29 -> [[@LINE-1]]:32
+
+ } z_Z_42: [] () {    [self onEntity: [] () {
+
+
+ } piece: "string"];
+  // CHECK125: [[@LINE-4]]:29 -> [[@LINE-4]]:37, [[@LINE-1]]:4 -> [[@LINE-1]]:9
+  } + @"string literal" object: ^  {
+   [globalObject send: [self world: "]" onEntity: ']'
+ struct: [] () {
+  } perform: [self.undef_property piece: [] () {
+
+
+ } method: 12 foo: []  {
+
+
+ } onEntity: "string" * "]" method: "]"] < ']'] other: 42];
+  // CHECK126: [[@LINE-7]]:35 -> [[@LINE-7]]:40, [[@LINE-4]]:4 -> [[@LINE-4]]:10, [[@LINE-4]]:15 -> [[@LINE-4]]:18, [[@LINE-1]]:4 -> [[@LINE-1]]:12, [[@LINE-1]]:29 -> [[@LINE-1]]:35
+  // CHECK127: [[@LINE-10]]:30 -> [[@LINE-10]]:35, [[@LINE-10]]:41 -> [[@LINE-10]]:49, [[@LINE-9]]:2 -> [[@LINE-9]]:8, [[@LINE-8]]:5 -> [[@LINE-8]]:12
+
+ } method: ^  {    // comment
+  }];
+  // CHECK128: [[@LINE-27]]:27 -> [[@LINE-27]]:40, [[@LINE-27]]:60 -> [[@LINE-27]]:65, [[@LINE-20]]:4 -> [[@LINE-20]]:10, [[@LINE-15]]:25 -> [[@LINE-15]]:31, [[@LINE-2]]:4 -> [[@LINE-2]]:10
+}
+// RUN: clang-refactor-test rename-indexed-file -name=class:struct:object:foo -new-name=onEntity:onEntity:struct:foo -indexed-file=%s -indexed-at=557:17 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK109 %s
+// RUN: clang-refactor-test rename-indexed-file -name=method:withSomething:usingThing -new-name=object:class:withSomething -indexed-file=%s -indexed-at=561:10 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK110 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:bar:usingThing -new-name=piece:class:test -indexed-file=%s -indexed-at=575:20 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK111 %s
+// RUN: clang-refactor-test rename-indexed-file -name=part:name -new-name=bar:object -indexed-file=%s -indexed-at=574:24 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK112 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:struct:struct:class:class -new-name=name:onEntity:z_Z_42:piece:foo -indexed-file=%s -indexed-at=560:27 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK113 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:foo -new-name=foo:test -indexed-file=%s -indexed-at=560:13 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK114 %s
+// RUN: clang-refactor-test rename-indexed-file -name=part:name:test:bar -new-name=class:z_Z_42:onEntity:usingThing -indexed-file=%s -indexed-at=579:35 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK115 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:a_200 -new-name=usingThing:bar -indexed-file=%s -indexed-at=587:20 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK116 %s
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:world:foo:perform:name -new-name=withSomething:foo:world:test:test -indexed-file=%s -indexed-at=593:58 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK117 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:world:object -new-name=withSomething:class:part -indexed-file=%s -indexed-at=593:14 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK118 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:a_200:foo:struct -new-name=usingThing:foo:object:test -indexed-file=%s -indexed-at=553:10 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK119 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:name:z_Z_42:perform:class -new-name=method:usingThing:class:class:world -indexed-file=%s -indexed-at=609:35 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK120 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:test:onEntity:onEntity -new-name=onEntity:z_Z_42:a_200:piece -indexed-file=%s -indexed-at=615:53 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK121 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:perform:bar -new-name=foo:usingThing:world -indexed-file=%s -indexed-at=622:86 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK122 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:onEntity -new-name=foo:perform -indexed-file=%s -indexed-at=622:34 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK123 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:bar:test:name:bar -new-name=onEntity:withSomething:object:method:test -indexed-file=%s -indexed-at=629:26 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK124 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:piece -new-name=world:z_Z_42 -indexed-file=%s -indexed-at=635:29 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK125 %s
+// RUN: clang-refactor-test rename-indexed-file -name=piece:method:foo:onEntity:method -new-name=foo:method:z_Z_42:piece:bar -indexed-file=%s -indexed-at=643:35 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK126 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:onEntity:struct:perform -new-name=test:object:z_Z_42:object -indexed-file=%s -indexed-at=641:30 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK127 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:piece:z_Z_42:object:method -new-name=test:test:withSomething:z_Z_42:name -indexed-file=%s -indexed-at=628:27 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK128 %s
+
++(int) object {
+  [self usingThing: [] () {    ([self.undef_property object: ^  {
+  } usingThing: @"string literal"
+ test: "string" usingThing: globalArray[i]
+ foo: /*]*/ globalArray[i]]);
+  // CHECK129: [[@LINE-4]]:54 -> [[@LINE-4]]:60, [[@LINE-3]]:5 -> [[@LINE-3]]:15, [[@LINE-2]]:2 -> [[@LINE-2]]:6, [[@LINE-2]]:17 -> [[@LINE-2]]:27, [[@LINE-1]]:2 -> [[@LINE-1]]:5
+  } < ^ () {
+   [self z_Z_42:  name: globalArray[i] test: globalArray[i]
+ perform: globalArray[i]];
+  // CHECK130: [[@LINE-2]]:10 -> [[@LINE-2]]:16, [[@LINE-2]]:19 -> [[@LINE-2]]:23, [[@LINE-2]]:40 -> [[@LINE-2]]:44, [[@LINE-1]]:2 -> [[@LINE-1]]:9
+
+ } perform:  a_200: ([] () {
+   [super z_Z_42: "string" z_Z_42: [self perform: [] () {
+
+
+ } withSomething: ^  {
+
+
+ }
+] world: "]" onEntity: globalArray[i] foo: "]"];
+  // CHECK131: [[@LINE-8]]:42 -> [[@LINE-8]]:49, [[@LINE-5]]:4 -> [[@LINE-5]]:17
+  // CHECK132: [[@LINE-9]]:11 -> [[@LINE-9]]:17, [[@LINE-9]]:28 -> [[@LINE-9]]:34, [[@LINE-2]]:3 -> [[@LINE-2]]:8, [[@LINE-2]]:14 -> [[@LINE-2]]:22, [[@LINE-2]]:39 -> [[@LINE-2]]:42
+
+ } * "string") a_200: ']'];
+  // CHECK133: [[@LINE-23]]:9 -> [[@LINE-23]]:19, [[@LINE-13]]:4 -> [[@LINE-13]]:11, [[@LINE-13]]:14 -> [[@LINE-13]]:19, [[@LINE-1]]:16 -> [[@LINE-1]]:21
+  if (12) {
+      int bar = [super piece: 12 == globalArray[i] method: [self class: [] () {    return "string";
+  }
+ class: @"string literal" test: ^ () {
+   globalArray[12] = [self class: globalArray[i] z_Z_42: [] () {
+  } method: [super test: [] () {
+  } struct: @"string literal"
+ withSomething: []  {
+
+
+ } == globalArray[i] class: "]" struct: @"string literal"]];
+  // CHECK134: [[@LINE-6]]:20 -> [[@LINE-6]]:24, [[@LINE-5]]:5 -> [[@LINE-5]]:11, [[@LINE-4]]:2 -> [[@LINE-4]]:15, [[@LINE-1]]:22 -> [[@LINE-1]]:27, [[@LINE-1]]:33 -> [[@LINE-1]]:39
+  // CHECK135: [[@LINE-8]]:28 -> [[@LINE-8]]:33, [[@LINE-8]]:50 -> [[@LINE-8]]:56, [[@LINE-7]]:5 -> [[@LINE-7]]:11
+
+ } struct: ']' * 12 + @"string literal"]];
+  // CHECK136: [[@LINE-14]]:66 -> [[@LINE-14]]:71, [[@LINE-12]]:2 -> [[@LINE-12]]:7, [[@LINE-12]]:27 -> [[@LINE-12]]:31, [[@LINE-1]]:4 -> [[@LINE-1]]:10
+  // CHECK137: [[@LINE-15]]:24 -> [[@LINE-15]]:29, [[@LINE-15]]:52 -> [[@LINE-15]]:58
+
+  }
+  [globalObject send: [super struct: ^  {
+   [globalObject message] = [self.undef_property test: "string" onEntity: "]"] other: 42];
+  // CHECK138: [[@LINE-1]]:50 -> [[@LINE-1]]:54, [[@LINE-1]]:65 -> [[@LINE-1]]:73
+
+ } z_Z_42: @"string literal" perform: @"string literal" part: globalArray[i] < 12 struct: [self onEntity: @"string literal" part: "]"]];
+  // CHECK139: [[@LINE-1]]:97 -> [[@LINE-1]]:105, [[@LINE-1]]:125 -> [[@LINE-1]]:129
+  // CHECK140: [[@LINE-6]]:30 -> [[@LINE-6]]:36, [[@LINE-2]]:4 -> [[@LINE-2]]:10, [[@LINE-2]]:30 -> [[@LINE-2]]:37, [[@LINE-2]]:57 -> [[@LINE-2]]:61, [[@LINE-2]]:83 -> [[@LINE-2]]:89
+  if ("]") {
+      [super onEntity: ^  {    [self.undef_property withSomething: globalArray[i]
+ method: ^ () {
+  } onEntity: [self test: [_undef_ivar bar: @{ @1, @3 } < globalArray[i] <  part: ] * "]" method: (([self struct: "string" piece: [] () {
+  } struct: "string"])) withSomething: [self a_200: "]" foo: ']' < [self a_200: @"string literal" object: ']' onEntity: "]"] part: 12 usingThing: globalArray[i] name: [self.undef_property perform: @"string literal" world: globalArray[i] method: (12) method: [self.undef_property foo: @"string literal" part: []  {
+
+
+ } * "string" withSomething: "string"
+] perform: @"string literal"]] bar: ']'
+]];
+  // CHECK141: [[@LINE-7]]:40 -> [[@LINE-7]]:43, [[@LINE-7]]:77 -> [[@LINE-7]]:81
+  // CHECK142: [[@LINE-8]]:107 -> [[@LINE-8]]:113, [[@LINE-8]]:124 -> [[@LINE-8]]:129, [[@LINE-7]]:5 -> [[@LINE-7]]:11
+  // CHECK143: [[@LINE-8]]:74 -> [[@LINE-8]]:79, [[@LINE-8]]:99 -> [[@LINE-8]]:105, [[@LINE-8]]:111 -> [[@LINE-8]]:119
+  // CHECK144: [[@LINE-9]]:280 -> [[@LINE-9]]:283, [[@LINE-9]]:303 -> [[@LINE-9]]:307, [[@LINE-6]]:15 -> [[@LINE-6]]:28
+  // CHECK145: [[@LINE-10]]:189 -> [[@LINE-10]]:196, [[@LINE-10]]:216 -> [[@LINE-10]]:221, [[@LINE-10]]:238 -> [[@LINE-10]]:244, [[@LINE-10]]:251 -> [[@LINE-10]]:257, [[@LINE-6]]:3 -> [[@LINE-6]]:10
+  // CHECK146: [[@LINE-11]]:46 -> [[@LINE-11]]:51, [[@LINE-11]]:57 -> [[@LINE-11]]:60, [[@LINE-11]]:126 -> [[@LINE-11]]:130, [[@LINE-11]]:135 -> [[@LINE-11]]:145, [[@LINE-11]]:162 -> [[@LINE-11]]:166
+  // CHECK147: [[@LINE-13]]:21 -> [[@LINE-13]]:25, [[@LINE-13]]:91 -> [[@LINE-13]]:97, [[@LINE-12]]:25 -> [[@LINE-12]]:38, [[@LINE-8]]:32 -> [[@LINE-8]]:35
+  // CHECK148: [[@LINE-16]]:53 -> [[@LINE-16]]:66, [[@LINE-15]]:2 -> [[@LINE-15]]:8, [[@LINE-14]]:5 -> [[@LINE-14]]:13
+  } usingThing:
+];
+  // CHECK149: [[@LINE-19]]:14 -> [[@LINE-19]]:22, [[@LINE-2]]:5 -> [[@LINE-2]]:15
+
+  }
+  [self.undef_property test: []  {    if (@"string literal") {
+      call() = [self z_Z_42: "string" usingThing: @"string literal"
+];
+  // CHECK150: [[@LINE-2]]:22 -> [[@LINE-2]]:28, [[@LINE-2]]:39 -> [[@LINE-2]]:49
+
+  }
+  } object: globalArray[i]
+ test: ^ () {    if ("string" == @"string literal" + ^ () {
+
+
+ }) {
+      int name = 12 * 12;
+
+  }
+  } a_200: "]"];
+  // CHECK151: [[@LINE-15]]:24 -> [[@LINE-15]]:28, [[@LINE-9]]:5 -> [[@LINE-9]]:11, [[@LINE-8]]:2 -> [[@LINE-8]]:6, [[@LINE-1]]:5 -> [[@LINE-1]]:10
+}
+// RUN: clang-refactor-test rename-indexed-file -name=object:usingThing:test:usingThing:foo -new-name=part:piece:object:a_200:name -indexed-file=%s -indexed-at=679:54 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK129 %s
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:name:test:perform -new-name=a_200:usingThing:usingThing:withSomething -indexed-file=%s -indexed-at=685:10 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK130 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:withSomething -new-name=piece:struct -indexed-file=%s -indexed-at=690:42 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK131 %s
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:z_Z_42:world:onEntity:foo -new-name=withSomething:method:perform:onEntity:bar -indexed-file=%s -indexed-at=690:11 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK132 %s
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:perform:a_200:a_200 -new-name=a_200:world:usingThing:class -indexed-file=%s -indexed-at=679:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK133 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:struct:withSomething:class:struct -new-name=withSomething:part:a_200:method:perform -indexed-file=%s -indexed-at=708:20 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK134 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:z_Z_42:method -new-name=part:a_200:part -indexed-file=%s -indexed-at=707:28 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK135 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:class:test:struct -new-name=a_200:world:struct:world -indexed-file=%s -indexed-at=704:66 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK136 %s
+// RUN: clang-refactor-test rename-indexed-file -name=piece:method -new-name=name:class -indexed-file=%s -indexed-at=704:24 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK137 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:onEntity -new-name=foo:piece -indexed-file=%s -indexed-at=723:50 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK138 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:part -new-name=class:name -indexed-file=%s -indexed-at=726:97 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK139 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:z_Z_42:perform:part:struct -new-name=onEntity:part:usingThing:struct:perform -indexed-file=%s -indexed-at=722:30 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK140 %s
+// RUN: clang-refactor-test rename-indexed-file -name=bar:part -new-name=part:class -indexed-file=%s -indexed-at=732:40 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK141 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:piece:struct -new-name=part:onEntity:foo -indexed-file=%s -indexed-at=732:107 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK142 %s
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:object:onEntity -new-name=world:bar:onEntity -indexed-file=%s -indexed-at=733:74 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK143 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:part:withSomething -new-name=usingThing:withSomething:perform -indexed-file=%s -indexed-at=733:280 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK144 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:world:method:method:perform -new-name=piece:bar:usingThing:class:piece -indexed-file=%s -indexed-at=733:189 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK145 %s
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:foo:part:usingThing:name -new-name=z_Z_42:object:name:perform:foo -indexed-file=%s -indexed-at=733:46 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK146 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:method:withSomething:bar -new-name=piece:class:a_200:z_Z_42 -indexed-file=%s -indexed-at=732:21 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK147 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:method:onEntity -new-name=usingThing:foo:object -indexed-file=%s -indexed-at=730:53 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK148 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:usingThing -new-name=perform:piece -indexed-file=%s -indexed-at=730:14 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK149 %s
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:usingThing -new-name=test:usingThing -indexed-file=%s -indexed-at=753:22 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK150 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:object:test:a_200 -new-name=foo:world:piece:z_Z_42 -indexed-file=%s -indexed-at=752:24 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK151 %s
+
++(void) onEntity {
+  int perform = [_undef_ivar onEntity: [] () {
+   /*comment*/([self z_Z_42: ']' + globalArray[i] a_200:  method: "]" == "]" < ^ () {
+
+
+ }]);
+  // CHECK152: [[@LINE-4]]:22 -> [[@LINE-4]]:28, [[@LINE-4]]:51 -> [[@LINE-4]]:56, [[@LINE-4]]:59 -> [[@LINE-4]]:65
+
+ } method: "]" < globalArray[i] == @"string literal" struct: "string" == @{ @1, @3 } onEntity: @"string literal"
+ perform: ^ () {    globalArray[12] = [self foo: ']' * @"string literal" piece: ^  {
+  } perform: "string" name: "]"];
+  // CHECK153: [[@LINE-2]]:45 -> [[@LINE-2]]:48, [[@LINE-2]]:74 -> [[@LINE-2]]:79, [[@LINE-1]]:5 -> [[@LINE-1]]:12, [[@LINE-1]]:23 -> [[@LINE-1]]:27
+  }];
+  // CHECK154: [[@LINE-12]]:30 -> [[@LINE-12]]:38, [[@LINE-5]]:4 -> [[@LINE-5]]:10, [[@LINE-5]]:54 -> [[@LINE-5]]:60, [[@LINE-5]]:86 -> [[@LINE-5]]:94, [[@LINE-4]]:2 -> [[@LINE-4]]:9
+  return []  {
+   [self part: (@"string literal") world: [self struct: [self a_200: "]" test: ']'] piece: "]" withSomething: @"string literal" struct: "]" object: ] bar: ']'];
+  // CHECK155: [[@LINE-1]]:63 -> [[@LINE-1]]:68, [[@LINE-1]]:74 -> [[@LINE-1]]:78
+  // CHECK156: [[@LINE-2]]:49 -> [[@LINE-2]]:55, [[@LINE-2]]:85 -> [[@LINE-2]]:90, [[@LINE-2]]:96 -> [[@LINE-2]]:109, [[@LINE-2]]:129 -> [[@LINE-2]]:135, [[@LINE-2]]:141 -> [[@LINE-2]]:147
+  // CHECK157: [[@LINE-3]]:10 -> [[@LINE-3]]:14, [[@LINE-3]]:36 -> [[@LINE-3]]:41, [[@LINE-3]]:151 -> [[@LINE-3]]:154
+
+ };
+}
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:a_200:method -new-name=name:world:part -indexed-file=%s -indexed-at=795:22 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK152 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:piece:perform:name -new-name=name:class:withSomething:method -indexed-file=%s -indexed-at=802:45 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK153 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:method:struct:onEntity:perform -new-name=withSomething:piece:bar:struct:piece -indexed-file=%s -indexed-at=794:30 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK154 %s
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:test -new-name=part:z_Z_42 -indexed-file=%s -indexed-at=808:63 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK155 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:piece:withSomething:struct:object -new-name=foo:name:piece:z_Z_42:bar -indexed-file=%s -indexed-at=808:49 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK156 %s
+// RUN: clang-refactor-test rename-indexed-file -name=part:world:bar -new-name=test:a_200:z_Z_42 -indexed-file=%s -indexed-at=808:10 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK157 %s
+
++(const Object &) foo {
+  [self foo: "]" bar: ']' method: ^ () { ] } z_Z_42: [super usingThing: "string" world: [self world: globalArray[i] a_200: []  {    [self z_Z_42: ']' usingThing: ("]")];
+  // CHECK158: [[@LINE-1]]:139 -> [[@LINE-1]]:145, [[@LINE-1]]:151 -> [[@LINE-1]]:161
+  } foo: (12)] usingThing: []  {
+   globalArray[12] = [self name: []  {
+
+
+ } foo: @"string literal"/*comment*/ withSomething: globalArray[i] test: []  {
+  }];
+  // CHECK159: [[@LINE-8]]:95 -> [[@LINE-8]]:100, [[@LINE-8]]:117 -> [[@LINE-8]]:122, [[@LINE-6]]:5 -> [[@LINE-6]]:8
+  // CHECK160: [[@LINE-6]]:28 -> [[@LINE-6]]:32, [[@LINE-3]]:4 -> [[@LINE-3]]:7, [[@LINE-3]]:38 -> [[@LINE-3]]:51, [[@LINE-3]]:68 -> [[@LINE-3]]:72
+
+ } foo: ^  {    call() = [_undef_ivar world: @"string literal" usingThing: 12 onEntity: @"string literal" struct: ^  {
+  }];
+  // CHECK161: [[@LINE-2]]:39 -> [[@LINE-2]]:44, [[@LINE-2]]:64 -> [[@LINE-2]]:74, [[@LINE-2]]:79 -> [[@LINE-2]]:87, [[@LINE-2]]:107 -> [[@LINE-2]]:113
+  } < "]" test: ^ () {    if ([]  {
+  }) {
+      call() = [self withSomething: globalArray[i] z_Z_42: globalArray[i]
+ foo: 12 onEntity: @"string literal"];
+  // CHECK162: [[@LINE-2]]:22 -> [[@LINE-2]]:35, [[@LINE-2]]:52 -> [[@LINE-2]]:58, [[@LINE-1]]:2 -> [[@LINE-1]]:5, [[@LINE-1]]:10 -> [[@LINE-1]]:18
+
+  }
+  }]];
+  // CHECK163: [[@LINE-22]]:61 -> [[@LINE-22]]:71, [[@LINE-22]]:82 -> [[@LINE-22]]:87, [[@LINE-20]]:16 -> [[@LINE-20]]:26, [[@LINE-11]]:4 -> [[@LINE-11]]:7, [[@LINE-8]]:11 -> [[@LINE-8]]:15
+  // CHECK164: [[@LINE-23]]:9 -> [[@LINE-23]]:12, [[@LINE-23]]:18 -> [[@LINE-23]]:21, [[@LINE-23]]:27 -> [[@LINE-23]]:33, [[@LINE-23]]:46 -> [[@LINE-23]]:52
+  const Object & struct = ;
+  [globalObject message] = [self object: 12
+ name: 12 a_200: ^ () {    if ([self object: ^  {
+  } foo: "string" * @"string literal"]) {
+      [self withSomething: []  {
+  }
+//comment
+ a_200: ^  {
+  } foo: "string" piece: [] () {
+
+
+ }];
+  // CHECK165: [[@LINE-10]]:38 -> [[@LINE-10]]:44, [[@LINE-9]]:5 -> [[@LINE-9]]:8
+  // CHECK166: [[@LINE-9]]:13 -> [[@LINE-9]]:26, [[@LINE-6]]:2 -> [[@LINE-6]]:7, [[@LINE-5]]:5 -> [[@LINE-5]]:8, [[@LINE-5]]:19 -> [[@LINE-5]]:24
+
+  }
+  }];
+  // CHECK167: [[@LINE-16]]:34 -> [[@LINE-16]]:40, [[@LINE-15]]:2 -> [[@LINE-15]]:6, [[@LINE-15]]:11 -> [[@LINE-15]]:16
+  [self world: @"string literal" withSomething: @{ @1, @3 }];
+  // CHECK168: [[@LINE-1]]:9 -> [[@LINE-1]]:14, [[@LINE-1]]:34 -> [[@LINE-1]]:47
+}
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:usingThing -new-name=method:onEntity -indexed-file=%s -indexed-at=823:139 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK158 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:a_200:foo -new-name=class:test:bar -indexed-file=%s -indexed-at=823:95 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK159 %s
+// RUN: clang-refactor-test rename-indexed-file -name=name:foo:withSomething:test -new-name=a_200:perform:piece:method -indexed-file=%s -indexed-at=826:28 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK160 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:usingThing:onEntity:struct -new-name=usingThing:name:onEntity:method -indexed-file=%s -indexed-at=834:39 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK161 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:z_Z_42:foo:onEntity -new-name=perform:struct:bar:object -indexed-file=%s -indexed-at=839:22 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK162 %s
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:world:usingThing:foo:test -new-name=method:onEntity:part:part:bar -indexed-file=%s -indexed-at=823:61 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK163 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:bar:method:z_Z_42 -new-name=class:onEntity:method:name -indexed-file=%s -indexed-at=823:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK164 %s
+// RUN: clang-refactor-test rename-indexed-file -name=object:foo -new-name=object:usingThing -indexed-file=%s -indexed-at=849:38 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK165 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:a_200:foo:piece -new-name=class:struct:bar:onEntity -indexed-file=%s -indexed-at=851:13 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK166 %s
+// RUN: clang-refactor-test rename-indexed-file -name=object:name:a_200 -new-name=piece:withSomething:withSomething -indexed-file=%s -indexed-at=848:34 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK167 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:withSomething -new-name=part:withSomething -indexed-file=%s -indexed-at=865:9 -indexed-symbol-kind=objc-message %s | FileCheck --check-prefix=CHECK168 %s
+
++(void) object {
+  int test = globalArray[i];
+}
diff --git a/test/Refactor/Rename/IndexedObjCMethod.m b/test/Refactor/Rename/IndexedObjCMethod.m
new file mode 100644
index 0000000..f9182c6
--- /dev/null
+++ b/test/Refactor/Rename/IndexedObjCMethod.m
@@ -0,0 +1,128 @@
+@interface Test
+
+- (int)performAction:(int)action with:(int)value; // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:21, [[@LINE]]:34 -> [[@LINE]]:38
+
+@end
+
+@implementation Test
+
+- (int)performAction:(int)action
+       with:(int)value { // CHECK: rename [[@LINE-1]]:8 -> [[@LINE-1]]:21, [[@LINE]]:8 -> [[@LINE]]:12
+    return action + value;
+}
+
++ (void)foo:(Test*)t {
+    [t performAction: 2 with: 4]; // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:21, [[@LINE]]:25 -> [[@LINE]]:29
+    SEL s1 = @selector(performAction:
+                       with:);    // CHECK-NOT: selector [[@LINE-1]]:24 -> [[@LINE-1]]:37, [[@LINE]]:24 -> [[@LINE]]:28
+    SEL s2 = @selector(performAction:); // CHECK-NOT: selector [[@LINE]]
+    SEL s3 = @selector(performAction);  // CHECK-NOT: selector [[@LINE]]
+    // Not indexed
+    [t performAction: 1 with: 2]; // CHECK-NOT: rename [[@LINE]]
+}
+
+@end
+
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -name=performAction:with -new-name=foo:bar -indexed-file=%s -indexed-at=3:8 -indexed-at=9:8 -indexed-at=objc-message:15:8 -indexed-symbol-kind=objc-im %s | FileCheck %s
+
+@interface SemicolonIsExcluded
+-(void)/*A_propA4_set_decl*/setPropA4X:(int)value;
+@end
+// CHECK2: rename [[@LINE-2]]:29 -> [[@LINE-2]]:39
+
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -name=setPropA4X: -new-name=foo -indexed-file=%s -indexed-at=29:29 -indexed-symbol-kind=objc-im %s -x objective-c | FileCheck --check-prefix=CHECK2 %s
+
+// It should be possible to have the filename as one of the compilation arguments
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -ignore-filename-for-initiation-tu -name=performAction:with: -new-name=foo:bar: -indexed-file=%s -indexed-at=3:8 -indexed-at=9:8 -indexed-at=objc-message:15:8 -indexed-symbol-kind=objc-cm %s -c %s -Wall | FileCheck %s
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -ignore-filename-for-initiation-tu -name=performAction:with: -new-name=foo:bar: -indexed-file=%s -indexed-at=3:8 -indexed-at=9:8 -indexed-at=objc-message:15:8 -indexed-symbol-kind=objc-cm %s %s -fsyntax-only | FileCheck %s
+
+// -gmodules should be stripped to avoid -fmodule-format=obj in CC1 arguments:
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -name=performAction:with: -new-name=foo:bar: -indexed-file=%s -indexed-at=3:8 -indexed-at=9:8 -indexed-at=objc-message:15:8 -indexed-symbol-kind=objc-cm %s -fmodules -gmodules | FileCheck %s
+
+// These texual matches should be reported as comment or selector occurrences:
+// CHECK3: rename [[@LINE-40]]:8 -> [[@LINE-40]]:21, [[@LINE-40]]:34 -> [[@LINE-40]]:38
+// performAction
+/* performAction: with: 2 performAction */
+/*! performAction+1
+// performAction with
+!*/
+/// Hello performAction with World
+/// \c performAction.
+
+// CHECK3: comment [[@LINE-8]]:4 -> [[@LINE-8]]:17
+// CHECK3-NEXT: comment [[@LINE-8]]:4 -> [[@LINE-8]]:17
+// CHECK3-NEXT: comment [[@LINE-9]]:27 -> [[@LINE-9]]:40
+// CHECK3-NEXT: documentation [[@LINE-9]]:5 -> [[@LINE-9]]:18
+// CHECK3-NEXT: documentation [[@LINE-9]]:4 -> [[@LINE-9]]:17
+// CHECK3-NEXT: documentation [[@LINE-8]]:11 -> [[@LINE-8]]:24
+// CHECK3-NEXT: documentation [[@LINE-8]]:8 -> [[@LINE-8]]:21
+
+// "performAction:with:"
+// 'performAction:'with:
+// CHECK3-NEXT: comment [[@LINE-2]]:5 -> [[@LINE-2]]:18
+// CHECK3-NEXT: comment [[@LINE-2]]:5 -> [[@LINE-2]]:18
+
+// CHECK3-NEXT: selector [[@LINE+1]]:11 -> [[@LINE+1]]:24, [[@LINE+1]]:25 -> [[@LINE+1]]:29
+@selector(performAction:with:);
+// CHECK3-NEXT: selector [[@LINE+1]]:11 -> [[@LINE+1]]:24, [[@LINE+1]]:28 -> [[@LINE+1]]:32
+@selector(performAction :  with );
+// CHECK3-NEXT: selector [[@LINE+2]]:19 -> [[@LINE+2]]:32, [[@LINE+2]]:46 -> [[@LINE+2]]:50
+SEL s = @selector(//comment
+                  performAction: /*comment*/ with
+                  );
+// CHECK3-NEXT: selector [[@LINE+1]]:33 -> [[@LINE+1]]:46, [[@LINE+2]]:33 -> [[@LINE+2]]:37
+void call = @selector(@selector(performAction:
+                                with: ));
+
+// CHECK3-NEXT: comment [[@LINE+1]]:55
+// RUN: clang-refactor-test rename-indexed-file -name=performAction:with: -new-name=foo:bar -indexed-file=%s -indexed-at=objc-cm:3:8 %s | FileCheck --check-prefix=CHECK3 %s
+
+// These ones shouldn't:
+// performAction2 PERFORMACTION performActionWith
+const char *test = "performAction:with:";
+
+@selector(performAction: with ::)
+@selector(performAction:)
+@selector(performAction)
+@selector(performAction with)
+@selector(performAction:without:)
+@selector(performAction:with:somethingElse:)
+@selector(performAction:with "")
+@selector("performAction:with:")
+@selector(with: performAction:)
+selector(performAction:with)
+(performAction:with:)
+
+// CHECK3-NOT: comment
+// CHECK3-NOT: documentation
+// CHECK3-NOT: selector
+
+// It should be possible to find a selector in a file without any indexed occurrences:
+
+// CHECK4: selector [[@LINE+1]]:11
+@selector(nonIndexedSelector)
+// CHECK4-NEXT: comment
+// CHECK4-NOT: selector
+
+// RUN: clang-refactor-test rename-indexed-file -indexed-symbol-kind=objc-im -name=nonIndexedSelector -new-name=test -indexed-file=%s %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-indexed-file -indexed-symbol-kind=objc-cm -name=nonIndexedSelector -new-name=test -indexed-file=%s %s | FileCheck --check-prefix=CHECK4 %s
+
+#define MACRO doStuff
+#define MACRO2(x, y) doStuff:(x) with: (y)
+
+@interface I
+- (void)doStuff:(int)x with: y;
+@end
+
+@implementation I
+- (void)MACRO:(int)x with: y {
+  [self MACRO2(x, y)];
+}
+@end
+
+// CHECK-MACRO: macro [[@LINE-5]]:9 -> [[@LINE-5]]:9
+// CHECK-MACRO-NEXT: macro [[@LINE-5]]:9 -> [[@LINE-5]]:9
+// CHECK-MACRO-NEXT: rename [[@LINE-11]]:9 -> [[@LINE-11]]:16, [[@LINE-11]]:24 -> [[@LINE-11]]:28
+// CHECK-MACRO-NOT: macro
+
+// RUN: clang-refactor-test rename-indexed-file -indexed-symbol-kind=objc-im -name=doStuff:with: -new-name=foo:bar -indexed-file=%s -indexed-at=114:9 -indexed-at=118:9 -indexed-at=119:9 %s | FileCheck --check-prefix=CHECK-MACRO %s
diff --git a/test/Refactor/Rename/IndexedObjCMethodDecl.mm b/test/Refactor/Rename/IndexedObjCMethodDecl.mm
new file mode 100644
index 0000000..23e41ac
--- /dev/null
+++ b/test/Refactor/Rename/IndexedObjCMethodDecl.mm
@@ -0,0 +1,748 @@
+@implementation foo
++(some_type_t)a_200:(void)a_200 name:(int[1 + 2 - 3])z_Z_42 usingThing:(some_type_t)world method:(void)test
+class:(int[1 + 2 - 3])method __attribute__((eval { int x = 0 + 1; })) method:(({}))method {
+  const Object & piece = 12;
+}
+// CHECK1: [[@LINE-4]]:15 -> [[@LINE-4]]:20, [[@LINE-4]]:33 -> [[@LINE-4]]:37, [[@LINE-4]]:61 -> [[@LINE-4]]:71, [[@LINE-4]]:91 -> [[@LINE-4]]:97, [[@LINE-3]]:1 -> [[@LINE-3]]:6, [[@LINE-3]]:71 -> [[@LINE-3]]:77
++(some_type_t)world:(BOOL)withSomething class:(const Object &)name struct:(some_type_t)method __attribute__((test()))a_200:(int)name
+a_200:(({}))perform withSomething:(Object * (^)(BOOL, Object *))onEntity
+{
+  const Object & class = globalArray[i];
+}
+// CHECK2: [[@LINE-5]]:15 -> [[@LINE-5]]:20, [[@LINE-5]]:41 -> [[@LINE-5]]:46, [[@LINE-5]]:68 -> [[@LINE-5]]:74, [[@LINE-5]]:118 -> [[@LINE-5]]:123, [[@LINE-4]]:1 -> [[@LINE-4]]:6, [[@LINE-4]]:21 -> [[@LINE-4]]:34
+-(some_type_t)struct:(int[1 + 2 - 3])bar
+class:(int[1 + 2 - 3])foo
+part:(void)piece
+{
+  int onEntity = "]";
+}
+// CHECK3: [[@LINE-6]]:15 -> [[@LINE-6]]:21, [[@LINE-5]]:1 -> [[@LINE-5]]:6, [[@LINE-4]]:1 -> [[@LINE-4]]:5
+-(some_type_t)test:(^ { })a_200 world:(BOOL)onEntity a_200:(BOOL)perform
+withSomething:(({}))method
+{
+  [self part: [self z_Z_42: "]" world: ("]")] world: globalArray[i] class: "string" test: globalArray[i]];
+}
+// CHECK4: [[@LINE-5]]:15 -> [[@LINE-5]]:19, [[@LINE-5]]:33 -> [[@LINE-5]]:38, [[@LINE-5]]:54 -> [[@LINE-5]]:59, [[@LINE-4]]:1 -> [[@LINE-4]]:14
+-(int)a_200:(BOOL)bar piece:(Object *)perform class:(^ { })onEntity {
+  [globalObject send: [self perform: ']' object: [] () {    ([self name: ']' a_200: ']']) other: 42];
+  } foo: ']'];
+}
+// CHECK5: [[@LINE-4]]:7 -> [[@LINE-4]]:12, [[@LINE-4]]:23 -> [[@LINE-4]]:28, [[@LINE-4]]:47 -> [[@LINE-4]]:52
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:name:usingThing:method:class:method -new-name=withSomething:struct:class:onEntity:withSomething:test -indexed-file=%s -indexed-at=2:15 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:class:struct:a_200:a_200:withSomething -new-name=onEntity:a_200:perform:onEntity:usingThing:onEntity -indexed-file=%s -indexed-at=7:15 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:class:part -new-name=z_Z_42:name:usingThing -indexed-file=%s -indexed-at=13:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:world:a_200:withSomething -new-name=part:withSomething:test:struct -indexed-file=%s -indexed-at=20:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:piece:class -new-name=a_200:a_200:piece -indexed-file=%s -indexed-at=26:7 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK5 %s
+
+@interface method
++(some_type_t)bar:(BOOL)bar bar:(Object *)usingThing struct:(int[1 + 2 - 3])usingThing
+perform:(BOOL)onEntity ;
+// CHECK6: [[@LINE-2]]:15 -> [[@LINE-2]]:18, [[@LINE-2]]:29 -> [[@LINE-2]]:32, [[@LINE-2]]:54 -> [[@LINE-2]]:60, [[@LINE-1]]:1 -> [[@LINE-1]]:8
++(void)struct:(^ { })part __attribute__((test()))foo:(^ { })part part:(void)class __attribute__((eval { int x = 0 + 1; })) onEntity:(Object *)method foo:(const Object &)class /*comment*/ ;
+// CHECK7: [[@LINE-1]]:8 -> [[@LINE-1]]:14, [[@LINE-1]]:50 -> [[@LINE-1]]:53, [[@LINE-1]]:66 -> [[@LINE-1]]:70, [[@LINE-1]]:124 -> [[@LINE-1]]:132, [[@LINE-1]]:150 -> [[@LINE-1]]:153
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=bar:bar:struct:perform -new-name=bar:withSomething:test:foo -indexed-file=%s -indexed-at=39:15 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:foo:part:onEntity:foo -new-name=z_Z_42:part:world:piece:perform -indexed-file=%s -indexed-at=42:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK7 %s
+
+@interface foo
++(BOOL)class:(Object *)method struct:(void)method
+perform:(Object *)class
+;
+// CHECK8: [[@LINE-3]]:8 -> [[@LINE-3]]:13, [[@LINE-3]]:31 -> [[@LINE-3]]:37, [[@LINE-2]]:1 -> [[@LINE-2]]:8
++(some_type_t)usingThing:(({}))struct withSomething:(const Object &)z_Z_42 method:(some_type_t)class
+a_200:(int)a_200 ;
+// CHECK9: [[@LINE-2]]:15 -> [[@LINE-2]]:25, [[@LINE-2]]:39 -> [[@LINE-2]]:52, [[@LINE-2]]:76 -> [[@LINE-2]]:82, [[@LINE-1]]:1 -> [[@LINE-1]]:6
++(Object *)a_200:(const Object &)class //comment
+class:(BOOL)bar usingThing:(void (*)(some_type_t, some_type_t))name
+bar:(BOOL)onEntity method:(void)method
+part:(BOOL)usingThing /*comment*/ ;
+// CHECK10: [[@LINE-4]]:12 -> [[@LINE-4]]:17, [[@LINE-3]]:1 -> [[@LINE-3]]:6, [[@LINE-3]]:17 -> [[@LINE-3]]:27, [[@LINE-2]]:1 -> [[@LINE-2]]:4, [[@LINE-2]]:20 -> [[@LINE-2]]:26, [[@LINE-1]]:1 -> [[@LINE-1]]:5
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=class:struct:perform -new-name=withSomething:foo:a_200 -indexed-file=%s -indexed-at=49:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK8 %s
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:withSomething:method:a_200 -new-name=piece:bar:test:perform -indexed-file=%s -indexed-at=53:15 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK9 %s
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:class:usingThing:bar:method:part -new-name=a_200:piece:class:z_Z_42:piece:world -indexed-file=%s -indexed-at=56:12 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK10 %s
+
+@implementation onEntity <object, onEntity, world>
+-(const Object &)test:(some_type_t (*)(some_type_t))z_Z_42 //comment
+perform:(Object *)name /*comment*/ method:(int)bar __attribute__((eval { int x = 0 + 1; })) part:(Object *)name z_Z_42:(BOOL)a_200 test:(^ { })usingThing __attribute__((test())){
+  call() = [self test: "]" z_Z_42: ^  {    [_undef_ivar foo: "string" piece: @{ @1, @3 } perform: @"string literal" world: ']'];
+  } == "]" a_200: 12/*comment*/ object: 12 test: 12];
+}
+// CHECK11: [[@LINE-5]]:18 -> [[@LINE-5]]:22, [[@LINE-4]]:1 -> [[@LINE-4]]:8, [[@LINE-4]]:36 -> [[@LINE-4]]:42, [[@LINE-4]]:93 -> [[@LINE-4]]:97, [[@LINE-4]]:113 -> [[@LINE-4]]:119, [[@LINE-4]]:132 -> [[@LINE-4]]:136
+-(const Object &)z_Z_42:(({}))usingThing onEntity:(^ { })world
+a_200:(const Object &)withSomething __attribute__((test()))onEntity:(({}))onEntity {
+  [_undef_ivar object: globalArray[i] perform: ^  {    globalArray[12] = [_undef_ivar class: "]" onEntity: []  {
+  } bar: "string" < ^  {
+  } foo: "string" piece: @{ @1, @3 }];
+  } test: /*]*/  method: globalArray[i]
+];
+}
+// CHECK12: [[@LINE-8]]:18 -> [[@LINE-8]]:24, [[@LINE-8]]:42 -> [[@LINE-8]]:50, [[@LINE-7]]:1 -> [[@LINE-7]]:6, [[@LINE-7]]:60 -> [[@LINE-7]]:68
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=test:perform:method:part:z_Z_42:test -new-name=a_200:piece:onEntity:withSomething:world:test -indexed-file=%s -indexed-at=67:18 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK11 %s
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:onEntity:a_200:onEntity -new-name=part:world:z_Z_42:onEntity -indexed-file=%s -indexed-at=73:18 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK12 %s
+
+@implementation method
+-(BOOL)usingThing:(void)part part:(void)world
+class:(int)part perform:(some_type_t)withSomething
+z_Z_42:(const Object &)class //comment
+usingThing:(({}))part {
+  some_type_t foo = [self.undef_property onEntity: "string" withSomething: ']'];
+}
+// CHECK13: [[@LINE-6]]:8 -> [[@LINE-6]]:18, [[@LINE-6]]:30 -> [[@LINE-6]]:34, [[@LINE-5]]:1 -> [[@LINE-5]]:6, [[@LINE-5]]:17 -> [[@LINE-5]]:24, [[@LINE-4]]:1 -> [[@LINE-4]]:7, [[@LINE-3]]:1 -> [[@LINE-3]]:11
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:part:class:perform:z_Z_42:usingThing -new-name=class:method:withSomething:world:name:name -indexed-file=%s -indexed-at=87:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK13 %s
+
+@interface withSomething
+-(Object *)object:(^ { })onEntity __attribute__((test()))piece:(^ { })z_Z_42 /*comment*/ ;
+// CHECK14: [[@LINE-1]]:12 -> [[@LINE-1]]:18, [[@LINE-1]]:58 -> [[@LINE-1]]:63
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=object:piece -new-name=foo:bar -indexed-file=%s -indexed-at=98:12 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK14 %s
+
+@interface usingThing <piece, withSomething, perform>
++(void)part:(some_type_t)onEntity
+a_200:(int)bar perform:(some_type_t)struct
+;
+// CHECK15: [[@LINE-3]]:8 -> [[@LINE-3]]:12, [[@LINE-2]]:1 -> [[@LINE-2]]:6, [[@LINE-2]]:16 -> [[@LINE-2]]:23
+-(some_type_t)piece:(^ { })foo name:(({}))perform part:(^ { })name z_Z_42:(Object *)test
+;
+// CHECK16: [[@LINE-2]]:15 -> [[@LINE-2]]:20, [[@LINE-2]]:32 -> [[@LINE-2]]:36, [[@LINE-2]]:51 -> [[@LINE-2]]:55, [[@LINE-2]]:68 -> [[@LINE-2]]:74
++(Object *)method:(const Object &)method onEntity:(^ { })withSomething
+withSomething:(int (*)(const Object &, BOOL))piece ;
+// CHECK17: [[@LINE-2]]:12 -> [[@LINE-2]]:18, [[@LINE-2]]:42 -> [[@LINE-2]]:50, [[@LINE-1]]:1 -> [[@LINE-1]]:14
+-(BOOL)foo:(int[1 + 2 - 3])world
+foo:(int[1 + 2 - 3])struct method:(void (*)())piece foo:(BOOL)test __attribute__((eval { int x = 0 + 1; })) ;
+// CHECK18: [[@LINE-2]]:8 -> [[@LINE-2]]:11, [[@LINE-1]]:1 -> [[@LINE-1]]:4, [[@LINE-1]]:28 -> [[@LINE-1]]:34, [[@LINE-1]]:53 -> [[@LINE-1]]:56
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=part:a_200:perform -new-name=part:test:part -indexed-file=%s -indexed-at=104:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK15 %s
+// RUN: clang-refactor-test rename-indexed-file -name=piece:name:part:z_Z_42 -new-name=usingThing:struct:onEntity:piece -indexed-file=%s -indexed-at=108:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK16 %s
+// RUN: clang-refactor-test rename-indexed-file -name=method:onEntity:withSomething -new-name=z_Z_42:method:usingThing -indexed-file=%s -indexed-at=111:12 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK17 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:foo:method:foo -new-name=piece:usingThing:class:foo -indexed-file=%s -indexed-at=114:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK18 %s
+
+@interface foo
+-(void)foo:(({}))part method:(({}))method ;
+// CHECK19: [[@LINE-1]]:8 -> [[@LINE-1]]:11, [[@LINE-1]]:23 -> [[@LINE-1]]:29
+-(const Object &)foo:(({}))usingThing test:(Object *)struct __attribute__((test()))name:(const Object &)z_Z_42 /*comment*/ name:(^ { })onEntity a_200:(Object * (^)())usingThing
+usingThing:(Object *)method /*comment*/ ;
+// CHECK20: [[@LINE-2]]:18 -> [[@LINE-2]]:21, [[@LINE-2]]:39 -> [[@LINE-2]]:43, [[@LINE-2]]:84 -> [[@LINE-2]]:88, [[@LINE-2]]:124 -> [[@LINE-2]]:128, [[@LINE-2]]:145 -> [[@LINE-2]]:150, [[@LINE-1]]:1 -> [[@LINE-1]]:11
++(BOOL)name:(Object *)a_200 part:(int)bar
+perform:(some_type_t)method ;
+// CHECK21: [[@LINE-2]]:8 -> [[@LINE-2]]:12, [[@LINE-2]]:29 -> [[@LINE-2]]:33, [[@LINE-1]]:1 -> [[@LINE-1]]:8
+-(some_type_t)usingThing:(void)test //comment
+foo:(void)world z_Z_42:(Object *)bar ;
+// CHECK22: [[@LINE-2]]:15 -> [[@LINE-2]]:25, [[@LINE-1]]:1 -> [[@LINE-1]]:4, [[@LINE-1]]:17 -> [[@LINE-1]]:23
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=foo:method -new-name=part:world -indexed-file=%s -indexed-at=124:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK19 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:test:name:name:a_200:usingThing -new-name=method:withSomething:struct:z_Z_42:bar:z_Z_42 -indexed-file=%s -indexed-at=126:18 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK20 %s
+// RUN: clang-refactor-test rename-indexed-file -name=name:part:perform -new-name=withSomething:part:object -indexed-file=%s -indexed-at=129:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK21 %s
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:foo:z_Z_42 -new-name=perform:test:class -indexed-file=%s -indexed-at=132:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK22 %s
+
+@implementation struct
++(void)bar:(void)piece a_200:(some_type_t)class {
+  [self name: [] () {
+   [globalObject send: [super name: [] () {
+
+
+ } perform: globalArray[i]] other: 42];
+
+ } usingThing: @"string literal"];
+
+  call() = [self usingThing: @"string literal" perform: "string"];
+}
+// CHECK23: [[@LINE-11]]:8 -> [[@LINE-11]]:11, [[@LINE-11]]:24 -> [[@LINE-11]]:29
+-(void)perform:(BOOL)test
+withSomething:(const Object &)foo {
+  return [_undef_ivar piece: globalArray[i] + globalArray[i] object: globalArray[i]
+ a_200: [self withSomething: [] () {    [self.undef_property usingThing: ']' struct: "]"
+ perform: "string"];
+  }
+ piece: ']' name: ']' a_200: "string" == ^ () {
+   globalArray[12] = [_undef_ivar foo: ']' foo: []  {
+  }
+ bar: ^  {
+  } + []  {
+
+
+ }
+];
+
+ }] z_Z_42: ^ () {
+   if (^ () {
+  }) {
+      return @"string literal" < globalArray[i] == [self world: []  {
+
+
+ } object: @"string literal" part: ']'];
+
+  }
+
+ } a_200: "string"];
+}
+// CHECK24: [[@LINE-28]]:8 -> [[@LINE-28]]:15, [[@LINE-27]]:1 -> [[@LINE-27]]:14
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=bar:a_200 -new-name=bar:name -indexed-file=%s -indexed-at=142:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK23 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:withSomething -new-name=withSomething:test -indexed-file=%s -indexed-at=154:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK24 %s
+
+@implementation object
+-(int)a_200:(Object *)perform usingThing:(int)bar //comment
+{
+  [self bar: ']' withSomething: "string"];
+
+  Object * part = ']';
+}
+// CHECK25: [[@LINE-6]]:7 -> [[@LINE-6]]:12, [[@LINE-6]]:31 -> [[@LINE-6]]:41
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=a_200:usingThing -new-name=object:bar -indexed-file=%s -indexed-at=188:7 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK25 %s
+
+@implementation test
++(void)method:(const Object &)z_Z_42 //comment
+piece:(some_type_t (*)(Object *))withSomething __attribute__((eval { int x = 0 + 1; })) perform:(void)piece method:(BOOL)object {
+  [self piece: [] () {
+   ; ;[self part: 12 a_200: @"string literal"];
+
+ } struct: globalArray[i] part: "]"];
+
+  ;
+}
+// CHECK26: [[@LINE-9]]:8 -> [[@LINE-9]]:14, [[@LINE-8]]:1 -> [[@LINE-8]]:6, [[@LINE-8]]:89 -> [[@LINE-8]]:96, [[@LINE-8]]:109 -> [[@LINE-8]]:115
+-(some_type_t)world:(some_type_t)world
+a_200:(void)bar //comment
+{
+  int piece = ;
+
+  if ("string") {
+      // comment
+
+  }
+}
+// CHECK27: [[@LINE-10]]:15 -> [[@LINE-10]]:20, [[@LINE-9]]:1 -> [[@LINE-9]]:6
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=method:piece:perform:method -new-name=perform:test:bar:object -indexed-file=%s -indexed-at=199:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK26 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:a_200 -new-name=z_Z_42:method -indexed-file=%s -indexed-at=209:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK27 %s
+
+@implementation perform
+-(Object *)class:(Object * (*)(BOOL))onEntity perform:(({}))class
+usingThing:(int (*)())object __attribute__((eval { int x = 0 + 1; })) piece:(BOOL (^)(BOOL, BOOL))class bar:(int)name withSomething:(const Object &)onEntity __attribute__((test())){
+  // comment
+}
+// CHECK28: [[@LINE-4]]:12 -> [[@LINE-4]]:17, [[@LINE-4]]:47 -> [[@LINE-4]]:54, [[@LINE-3]]:1 -> [[@LINE-3]]:11, [[@LINE-3]]:71 -> [[@LINE-3]]:76, [[@LINE-3]]:105 -> [[@LINE-3]]:108, [[@LINE-3]]:119 -> [[@LINE-3]]:132
+-(int)test:(({}))onEntity
+a_200:(BOOL)struct {
+  ([self name: ']' part: []  {
+   ; ;([_undef_ivar usingThing: globalArray[i] class: globalArray[i] method: globalArray[i] method: ']' class: 12]);
+
+ } bar: 12 withSomething: "]" == []  {    [self test: [self world: [_undef_ivar struct: "]" bar: @"string literal" method: globalArray[i]] usingThing: @"string literal" class: [] () {
+  } bar: @"string literal"
+] withSomething: ([]  {
+
+
+ } + "]" * ']') withSomething: @"string literal"];
+  } usingThing: "]"]);
+
+  call() = [self test: globalArray[i] name: @"string literal" perform: [self class: "]"
+ piece: globalArray[i] method: "string"
+]
+//comment
+ piece: "string"];
+}
+// CHECK29: [[@LINE-19]]:7 -> [[@LINE-19]]:11, [[@LINE-18]]:1 -> [[@LINE-18]]:6
+-(Object *)test:(^ { })z_Z_42 class:(void)usingThing
+{
+  if ([self.undef_property class: globalArray[i] a_200: ^ () { ] }
+]) {
+      if (globalArray[i]) {
+      some_type_t foo = [self foo: "]" perform: "string"
+];
+
+  }
+
+  }
+}
+// CHECK30: [[@LINE-12]]:12 -> [[@LINE-12]]:16, [[@LINE-12]]:31 -> [[@LINE-12]]:36
++(int)struct:(void (^)())method
+a_200:(BOOL)onEntity usingThing:(Object *)a_200 bar:(void)z_Z_42 z_Z_42:(Object *)struct perform:(BOOL (*)(Object *, Object *))method {
+  globalArray[12] = [self bar: ']' test: ^ () { ] } method: globalArray[i]];
+
+  if ([super test: "string" < globalArray[i] part: 12]) {
+      int bar = [self object: "]"
+ perform: [self a_200: "string" object: ("string")
+//comment
+]];
+
+  }
+}
+// CHECK31: [[@LINE-12]]:7 -> [[@LINE-12]]:13, [[@LINE-11]]:1 -> [[@LINE-11]]:6, [[@LINE-11]]:22 -> [[@LINE-11]]:32, [[@LINE-11]]:49 -> [[@LINE-11]]:52, [[@LINE-11]]:66 -> [[@LINE-11]]:72, [[@LINE-11]]:90 -> [[@LINE-11]]:97
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=class:perform:usingThing:piece:bar:withSomething -new-name=a_200:piece:foo:struct:onEntity:world -indexed-file=%s -indexed-at=225:12 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK28 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:a_200 -new-name=struct:world -indexed-file=%s -indexed-at=230:7 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK29 %s
+// RUN: clang-refactor-test rename-indexed-file -name=test:class -new-name=perform:name -indexed-file=%s -indexed-at=250:12 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK30 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:a_200:usingThing:bar:z_Z_42:perform -new-name=world:piece:test:world:class:struct -indexed-file=%s -indexed-at=263:7 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK31 %s
+
+@implementation usingThing <object>
+-(int)foo:(int)a_200 part:(Object *)name
+object:(BOOL)world __attribute__((test()))method:(const Object & (*)())test name:(some_type_t)z_Z_42 bar:(Object *)class /*comment*/ {
+  [self piece: ^  {
+   [self.undef_property name: [self z_Z_42: [self object: @"string literal" + []  {
+  }
+ z_Z_42: [] () {
+
+
+ }] class: [self method: globalArray[i] usingThing: globalArray[i] part: 12] onEntity: @{ @1, @3 } piece: "string"] object: ([self foo: @"string literal" < [self object: ']' usingThing:  usingThing: globalArray[i] a_200: [] () {
+  }]
+ name: "string" foo: [] () {
+
+
+ }]) struct: "string" struct: "]" + []  {
+  } usingThing: ];
+
+ } usingThing: (@"string literal") usingThing: 12 a_200: ^  {    [globalObject message] = [self onEntity: []  {
+  } == ^  {
+
+
+ } foo: @{ @1, @3 }];
+  } withSomething: "]" == ];
+}
+// CHECK32: [[@LINE-23]]:7 -> [[@LINE-23]]:10, [[@LINE-23]]:22 -> [[@LINE-23]]:26, [[@LINE-22]]:1 -> [[@LINE-22]]:7, [[@LINE-22]]:43 -> [[@LINE-22]]:49, [[@LINE-22]]:77 -> [[@LINE-22]]:81, [[@LINE-22]]:102 -> [[@LINE-22]]:105
+-(Object *)withSomething:(void)class __attribute__((test()))onEntity:(void)part struct:(some_type_t (*)(Object *))bar __attribute__((eval { int x = 0 + 1; })) perform:(Object *)world {
+  globalArray[12] = [self struct: globalArray[i] bar: ^  {    if (']' + "string") {
+      return ^ () {
+  };
+
+  }
+  } class: ^ () {    some_type_t foo = [self.undef_property withSomething: ']' bar: "]"];
+  } usingThing: ']'
+];
+}
+// CHECK33: [[@LINE-10]]:12 -> [[@LINE-10]]:25, [[@LINE-10]]:61 -> [[@LINE-10]]:69, [[@LINE-10]]:81 -> [[@LINE-10]]:87, [[@LINE-10]]:160 -> [[@LINE-10]]:167
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=foo:part:object:method:name:bar -new-name=z_Z_42:z_Z_42:part:part:usingThing:z_Z_42 -indexed-file=%s -indexed-at=283:7 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK32 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:onEntity:struct:perform -new-name=withSomething:name:foo:name -indexed-file=%s -indexed-at=307:12 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK33 %s
+
+@interface a_200 <foo>
++(void)bar:(int[1 + 2 - 3])a_200 object:(Object *)z_Z_42 world:(int[1 + 2 - 3])name name:(const Object &)name world:(Object *)world /*comment*/ ;
+// CHECK34: [[@LINE-1]]:8 -> [[@LINE-1]]:11, [[@LINE-1]]:34 -> [[@LINE-1]]:40, [[@LINE-1]]:58 -> [[@LINE-1]]:63, [[@LINE-1]]:85 -> [[@LINE-1]]:89, [[@LINE-1]]:111 -> [[@LINE-1]]:116
+-(int)foo:(void (^)())part usingThing:(int)usingThing object:(({}))withSomething class:(some_type_t (^)())perform /*comment*/ method:(int)foo ;
+// CHECK35: [[@LINE-1]]:7 -> [[@LINE-1]]:10, [[@LINE-1]]:28 -> [[@LINE-1]]:38, [[@LINE-1]]:55 -> [[@LINE-1]]:61, [[@LINE-1]]:82 -> [[@LINE-1]]:87, [[@LINE-1]]:127 -> [[@LINE-1]]:133
+-(void)z_Z_42:(({}))withSomething name:(void (*)())struct foo:(Object *)part ;
+// CHECK36: [[@LINE-1]]:8 -> [[@LINE-1]]:14, [[@LINE-1]]:35 -> [[@LINE-1]]:39, [[@LINE-1]]:59 -> [[@LINE-1]]:62
+-(BOOL)onEntity:(const Object &)z_Z_42
+piece:(const Object &)world
+onEntity:(BOOL)part ;
+// CHECK37: [[@LINE-3]]:8 -> [[@LINE-3]]:16, [[@LINE-2]]:1 -> [[@LINE-2]]:6, [[@LINE-1]]:1 -> [[@LINE-1]]:9
+-(BOOL)method:(some_type_t)name
+part:(BOOL)a_200 part:(void)test __attribute__((eval { int x = 0 + 1; })) ;
+// CHECK38: [[@LINE-2]]:8 -> [[@LINE-2]]:14, [[@LINE-1]]:1 -> [[@LINE-1]]:5, [[@LINE-1]]:18 -> [[@LINE-1]]:22
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=bar:object:world:name:world -new-name=withSomething:part:struct:part:withSomething -indexed-file=%s -indexed-at=323:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK34 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:usingThing:object:class:method -new-name=part:onEntity:foo:test:struct -indexed-file=%s -indexed-at=325:7 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK35 %s
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:name:foo -new-name=piece:z_Z_42:world -indexed-file=%s -indexed-at=327:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK36 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:piece:onEntity -new-name=part:usingThing:foo -indexed-file=%s -indexed-at=329:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK37 %s
+// RUN: clang-refactor-test rename-indexed-file -name=method:part:part -new-name=perform:test:part -indexed-file=%s -indexed-at=333:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK38 %s
+
+@interface part <world, struct, part>
++(some_type_t)z_Z_42:(Object *)onEntity test:(int (*)())a_200 __attribute__((test()));
+// CHECK39: [[@LINE-1]]:15 -> [[@LINE-1]]:21, [[@LINE-1]]:41 -> [[@LINE-1]]:45
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:test -new-name=name:onEntity -indexed-file=%s -indexed-at=344:15 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK39 %s
+
+@interface piece
+-(some_type_t)part:(some_type_t)onEntity test:(Object *)world
+bar:(BOOL)foo
+method:(const Object & (^)(int, some_type_t))object
+withSomething:(BOOL)part
+;
+// CHECK40: [[@LINE-5]]:15 -> [[@LINE-5]]:19, [[@LINE-5]]:42 -> [[@LINE-5]]:46, [[@LINE-4]]:1 -> [[@LINE-4]]:4, [[@LINE-3]]:1 -> [[@LINE-3]]:7, [[@LINE-2]]:1 -> [[@LINE-2]]:14
+-(some_type_t)onEntity:(void)object test:(int[1 + 2 - 3])object ;
+// CHECK41: [[@LINE-1]]:15 -> [[@LINE-1]]:23, [[@LINE-1]]:37 -> [[@LINE-1]]:41
+-(some_type_t)struct:(void)name class:(some_type_t)foo name:(int (^)(BOOL, int))method
+foo:(void)usingThing usingThing:(int)z_Z_42 /*comment*/ a_200:(int[1 + 2 - 3])object
+;
+// CHECK42: [[@LINE-3]]:15 -> [[@LINE-3]]:21, [[@LINE-3]]:33 -> [[@LINE-3]]:38, [[@LINE-3]]:56 -> [[@LINE-3]]:60, [[@LINE-2]]:1 -> [[@LINE-2]]:4, [[@LINE-2]]:22 -> [[@LINE-2]]:32, [[@LINE-2]]:57 -> [[@LINE-2]]:62
+-(BOOL)bar:(some_type_t (*)(int))part /*comment*/ object:(int[1 + 2 - 3])onEntity perform:(BOOL)usingThing /*comment*/ ;
+// CHECK43: [[@LINE-1]]:8 -> [[@LINE-1]]:11, [[@LINE-1]]:51 -> [[@LINE-1]]:57, [[@LINE-1]]:83 -> [[@LINE-1]]:90
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=part:test:bar:method:withSomething -new-name=name:usingThing:perform:onEntity:bar -indexed-file=%s -indexed-at=350:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK40 %s
+// RUN: clang-refactor-test rename-indexed-file -name=onEntity:test -new-name=onEntity:class -indexed-file=%s -indexed-at=356:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK41 %s
+// RUN: clang-refactor-test rename-indexed-file -name=struct:class:name:foo:usingThing:a_200 -new-name=class:a_200:class:object:class:name -indexed-file=%s -indexed-at=358:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK42 %s
+// RUN: clang-refactor-test rename-indexed-file -name=bar:object:perform -new-name=a_200:test:object -indexed-file=%s -indexed-at=362:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK43 %s
+
+@implementation piece
++(BOOL)name:(int (^)(BOOL, const Object &))onEntity /*comment*/ withSomething:(void)foo name:(const Object &)withSomething a_200:(Object *)struct foo:(^ { })object {
+  if (12) {
+      return 12;
+
+  }
+}
+// CHECK44: [[@LINE-6]]:8 -> [[@LINE-6]]:12, [[@LINE-6]]:65 -> [[@LINE-6]]:78, [[@LINE-6]]:89 -> [[@LINE-6]]:93, [[@LINE-6]]:124 -> [[@LINE-6]]:129, [[@LINE-6]]:147 -> [[@LINE-6]]:150
++(int)class:(some_type_t (*)(BOOL))name
+name:(BOOL)onEntity __attribute__((test()))a_200:(^ { })withSomething __attribute__((eval { int x = 0 + 1; })) piece:(int)withSomething usingThing:(Object *)name {
+  ; ;[super method:  part: ^ () {
+   // comment
+
+ }];
+
+  [self struct: "string" == "]" withSomething: ']' class: [] () {
+   [globalObject send: [self.undef_property part: ^ () {
+
+
+ } class: (']' < )
+ z_Z_42: ^ () {
+
+
+ } test: (12)] other: 42];
+
+ } object: 12 perform: ']'];
+}
+// CHECK45: [[@LINE-19]]:7 -> [[@LINE-19]]:12, [[@LINE-18]]:1 -> [[@LINE-18]]:5, [[@LINE-18]]:44 -> [[@LINE-18]]:49, [[@LINE-18]]:112 -> [[@LINE-18]]:117, [[@LINE-18]]:137 -> [[@LINE-18]]:147
++(some_type_t)perform:(int[1 + 2 - 3])world //comment
+withSomething:(const Object &)foo part:(int (^)(int))foo part:(int[1 + 2 - 3])perform //comment
+{
+  [globalObject send: [self object: ']' withSomething: 12 usingThing: ']' perform: @"string literal"] other: 42];
+}
+// CHECK46: [[@LINE-5]]:15 -> [[@LINE-5]]:22, [[@LINE-4]]:1 -> [[@LINE-4]]:14, [[@LINE-4]]:35 -> [[@LINE-4]]:39, [[@LINE-4]]:58 -> [[@LINE-4]]:62
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=name:withSomething:name:a_200:foo -new-name=object:onEntity:world:world:piece -indexed-file=%s -indexed-at=371:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK44 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:name:a_200:piece:usingThing -new-name=method:test:z_Z_42:part:foo -indexed-file=%s -indexed-at=378:7 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK45 %s
+// RUN: clang-refactor-test rename-indexed-file -name=perform:withSomething:part:part -new-name=a_200:object:perform:z_Z_42 -indexed-file=%s -indexed-at=398:15 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK46 %s
+
+@implementation z_Z_42 <struct>
++(BOOL)piece:(some_type_t (^)(int))class a_200:(BOOL (^)(some_type_t, BOOL))bar
+world:(const Object & (*)(const Object &, const Object &))struct piece:(^ { })test z_Z_42:(BOOL)name
+usingThing:(void (^)(Object *))struct {
+  [self object: ([self.undef_property struct: ^  {
+   /*comment*/[self.undef_property part: @"string literal" world: @"string literal"
+ object: "]" world: "string" world: @{ @1, @3 }];
+
+ } == ^ () {    [super class: ^ () {
+
+
+ } * globalArray[i] piece: []  {
+  } bar: [self part: @"string literal" perform: "]" world: [] () {
+  }
+ world: [self.undef_property world: globalArray[i] perform: "string" struct: "]"]]];
+  }
+ name: 12 usingThing: "]" bar: "]"
+//comment
+]) withSomething: ^ () {
+   if ("string") {
+      [self withSomething: []  {
+
+
+ } method: 12 piece: [] () {
+
+
+ } a_200: ']' method: "]"];
+
+  }
+
+ } test: @{ @1, @3 }
+ class: 12 world: "string"];
+}
+// CHECK47: [[@LINE-32]]:8 -> [[@LINE-32]]:13, [[@LINE-32]]:42 -> [[@LINE-32]]:47, [[@LINE-31]]:1 -> [[@LINE-31]]:6, [[@LINE-31]]:66 -> [[@LINE-31]]:71, [[@LINE-31]]:84 -> [[@LINE-31]]:90, [[@LINE-30]]:1 -> [[@LINE-30]]:11
+-(int)method:(Object *)bar //comment
+part:(int)bar usingThing:(({}))name {
+  // comment
+
+  [_undef_ivar world: "]" onEntity: []  {
+   ; ;[self part: globalArray[i] world: @{ @1, @3 }];
+
+ } bar: "string" == [super name: 12 piece: /*]*/ @"string literal" part: "string" method: ^  {
+   some_type_t object = "string";
+
+ } piece: (^  {
+   return /*]*/ "]";
+
+ })] onEntity: []  {
+   int bar = [self name: "string"/*comment*/ method: globalArray[i]];
+
+ }];
+}
+// CHECK48: [[@LINE-18]]:7 -> [[@LINE-18]]:13, [[@LINE-17]]:1 -> [[@LINE-17]]:5, [[@LINE-17]]:15 -> [[@LINE-17]]:25
++(Object *)class:(BOOL)object __attribute__((test()))method:(some_type_t)method
+world:(Object *)struct
+{
+  [self method: ^  {    call() = [self a_200: ']' a_200: "]"];
+  } struct: ^ () {
+   return [] () {
+  };
+
+ } class: [_undef_ivar part: "string" name: []  {
+   int bar = [self withSomething: "string" bar: @"string literal" usingThing: @"string literal"];
+
+ }]];
+
+  [super foo: 12 foo:  * "]" foo: ("string") foo: "string" method: 12];
+}
+// CHECK49: [[@LINE-15]]:12 -> [[@LINE-15]]:17, [[@LINE-15]]:54 -> [[@LINE-15]]:60, [[@LINE-14]]:1 -> [[@LINE-14]]:6
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=piece:a_200:world:piece:z_Z_42:usingThing -new-name=struct:part:bar:struct:class:usingThing -indexed-file=%s -indexed-at=410:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK47 %s
+// RUN: clang-refactor-test rename-indexed-file -name=method:part:usingThing -new-name=object:piece:method -indexed-file=%s -indexed-at=443:7 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK48 %s
+// RUN: clang-refactor-test rename-indexed-file -name=class:method:world -new-name=struct:test:z_Z_42 -indexed-file=%s -indexed-at=462:12 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK49 %s
+
+@implementation a_200 <name, bar, a_200>
++(some_type_t)class:(void)z_Z_42
+object:(BOOL)perform
+z_Z_42:(const Object &)usingThing name:(const Object &)a_200 test:(({}))world perform:(int[1 + 2 - 3])z_Z_42
+{
+  if ("string") {
+      if ([super withSomething: []  {    return [_undef_ivar usingThing: [] () {
+  }
+ world: [] () {
+
+
+ } foo: 12 perform: globalArray[i] name: @"string literal"];
+  } world: ^  {    // comment
+  } object: ^  {    int method = "]";
+  }
+]) {
+      [globalObject send: [self.undef_property method: globalArray[i] object: []  {    [self method: ']' test: [self foo: ("string") a_200: @"string literal" piece: 12 < [self class: @"string literal" piece: "]" + ']']] test: [self onEntity: @"string literal"
+ z_Z_42: ']'] name: globalArray[i] test: 12] other: 42];
+  } class: ^  {    ; ;[self perform: ("string") bar: (']') foo: "string"
+ foo: ^  {
+
+
+ }];
+  } piece: ^  {
+   call() = [_undef_ivar perform: (12) bar: ^  {
+
+
+ } test: "]" name: "string" bar: "]"];
+
+ }];
+
+  }
+
+  }
+
+  [globalObject send: [self bar: globalArray[i] == ']' perform: [_undef_ivar z_Z_42: @"string literal" object: ^  {
+   [globalObject send: [self world: "]" onEntity: ']'
+ struct: [] () {
+  } perform: [self.undef_property piece: [] () {
+
+
+ } method: 12 foo: []  {
+
+
+ } onEntity: "string" * "]" method: "]"] < ']'] other: 42] other: 42];
+
+ } method: ^  {    // comment
+  } test: ^ () {    return []  {
+  };
+  }] a_200: [] () {    ([self.undef_property object: ^  {
+  } usingThing: @"string literal"
+ test: "string" usingThing: globalArray[i]
+ foo: /*]*/ globalArray[i]]);
+  } piece: 12];
+}
+// CHECK50: [[@LINE-54]]:15 -> [[@LINE-54]]:20, [[@LINE-53]]:1 -> [[@LINE-53]]:7, [[@LINE-52]]:1 -> [[@LINE-52]]:7, [[@LINE-52]]:35 -> [[@LINE-52]]:39, [[@LINE-52]]:62 -> [[@LINE-52]]:66, [[@LINE-52]]:79 -> [[@LINE-52]]:86
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=class:object:z_Z_42:name:test:perform -new-name=world:foo:part:a_200:name:piece -indexed-file=%s -indexed-at=484:15 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK50 %s
+
+@implementation piece (part)
++(BOOL)method:(^ { })foo foo:(({}))foo
+usingThing:(int)withSomething perform:(int[1 + 2 - 3])bar a_200:(some_type_t (^)())onEntity test:(const Object &)z_Z_42 __attribute__((eval { int x = 0 + 1; })) {
+  if ([self method: ']' struct: ^  {    [globalObject send: [_undef_ivar world: "]" onEntity: globalArray[i] foo: "]" withSomething:  < ']' onEntity: "string"] other: 42];
+  }
+]) {
+      call() = [self part: 12
+ struct: "string" perform: "string" class: [] () {    return "string";
+  }
+];
+
+  }
+}
+// CHECK51: [[@LINE-12]]:8 -> [[@LINE-12]]:14, [[@LINE-12]]:26 -> [[@LINE-12]]:29, [[@LINE-11]]:1 -> [[@LINE-11]]:11, [[@LINE-11]]:31 -> [[@LINE-11]]:38, [[@LINE-11]]:59 -> [[@LINE-11]]:64, [[@LINE-11]]:93 -> [[@LINE-11]]:97
++(some_type_t)withSomething:(some_type_t (^)(int, Object *))z_Z_42 bar:(^ { })usingThing {
+  return 12;
+}
+// CHECK52: [[@LINE-3]]:15 -> [[@LINE-3]]:28, [[@LINE-3]]:68 -> [[@LINE-3]]:71
+-(some_type_t)object:(some_type_t (*)())bar
+foo:(some_type_t (*)(const Object &))class
+withSomething:(void)onEntity
+usingThing:(^ { })bar a_200:(some_type_t (^)())usingThing
+usingThing:(^ { })name {
+  call() = ([self part: "]" piece: "string" * "]" bar: globalArray[i] piece: [] () {    int bar = [self test: "string" method: globalArray[i] method: "string" == /*]*/ "string" * @"string literal" object: @"string literal" usingThing: globalArray[i]];
+  } < "string"]);
+
+  if ("]" + [self part: @"string literal" class: "string"]) {
+      [super onEntity: "]" object: "]" piece: (12) test: ']' < ^  {
+   int bar = [self usingThing: [] () {
+
+
+ } z_Z_42: ^  {
+  } usingThing: "]" object: "]"];
+
+ }
+];
+
+  }
+}
+// CHECK53: [[@LINE-21]]:15 -> [[@LINE-21]]:21, [[@LINE-20]]:1 -> [[@LINE-20]]:4, [[@LINE-19]]:1 -> [[@LINE-19]]:14, [[@LINE-18]]:1 -> [[@LINE-18]]:11, [[@LINE-18]]:23 -> [[@LINE-18]]:28, [[@LINE-17]]:1 -> [[@LINE-17]]:11
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=method:foo:usingThing:perform:a_200:test -new-name=object:z_Z_42:test:struct:perform:z_Z_42 -indexed-file=%s -indexed-at=543:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK51 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:bar -new-name=world:foo -indexed-file=%s -indexed-at=556:15 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK52 %s
+// RUN: clang-refactor-test rename-indexed-file -name=object:foo:withSomething:usingThing:a_200:usingThing -new-name=part:a_200:method:perform:world:part -indexed-file=%s -indexed-at=560:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK53 %s
+
+@interface world
+-(const Object &)class:(int[1 + 2 - 3])struct onEntity:(void (^)(Object *, int))withSomething __attribute__((test()));
+// CHECK54: [[@LINE-1]]:18 -> [[@LINE-1]]:23, [[@LINE-1]]:47 -> [[@LINE-1]]:55
+-(int)world:(int)foo name:(const Object & (^)(int, Object *))piece a_200:(Object *)test object:(BOOL)onEntity __attribute__((eval { int x = 0 + 1; })) onEntity:(BOOL)z_Z_42 /*comment*/ ;
+// CHECK55: [[@LINE-1]]:7 -> [[@LINE-1]]:12, [[@LINE-1]]:22 -> [[@LINE-1]]:26, [[@LINE-1]]:68 -> [[@LINE-1]]:73, [[@LINE-1]]:89 -> [[@LINE-1]]:95, [[@LINE-1]]:152 -> [[@LINE-1]]:160
+-(int)usingThing:(^ { })part name:(const Object &)usingThing usingThing:(^ { })perform __attribute__((test()))struct:(^ { })world
+withSomething:(int[1 + 2 - 3])method //comment
+;
+// CHECK56: [[@LINE-3]]:7 -> [[@LINE-3]]:17, [[@LINE-3]]:30 -> [[@LINE-3]]:34, [[@LINE-3]]:62 -> [[@LINE-3]]:72, [[@LINE-3]]:111 -> [[@LINE-3]]:117, [[@LINE-2]]:1 -> [[@LINE-2]]:14
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=class:onEntity -new-name=usingThing:usingThing -indexed-file=%s -indexed-at=588:18 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK54 %s
+// RUN: clang-refactor-test rename-indexed-file -name=world:name:a_200:object:onEntity -new-name=world:bar:onEntity:name:part -indexed-file=%s -indexed-at=590:7 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK55 %s
+// RUN: clang-refactor-test rename-indexed-file -name=usingThing:name:usingThing:struct:withSomething -new-name=name:struct:method:method:usingThing -indexed-file=%s -indexed-at=592:7 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK56 %s
+
+@implementation onEntity
+-(BOOL)piece:(some_type_t (^)(int))usingThing perform:(int)foo onEntity:(({}))withSomething __attribute__((test()))bar:(Object *)usingThing usingThing:(const Object &)bar class:(const Object & (^)(int, const Object &))perform {
+  [self object: "string" foo: ([self onEntity: "string" * []  {    if (@"string literal") {
+      call() = [self z_Z_42: "string" usingThing: @"string literal"
+];
+
+  }
+  } object: globalArray[i]
+ test: ^ () {    if ("string" == @"string literal" + ^ () {
+
+
+ }) {
+      int name = 12 * 12;
+
+  }
+  }]) foo: @{ @1, @3 }];
+
+  call() = [super foo: ^ () { ] } part: ']' onEntity: [self piece: ']' piece: [] () {    [super name: "]" perform: "string"];
+  }]
+ struct: "]" part: @"string literal"];
+}
+// CHECK57: [[@LINE-20]]:8 -> [[@LINE-20]]:13, [[@LINE-20]]:47 -> [[@LINE-20]]:54, [[@LINE-20]]:64 -> [[@LINE-20]]:72, [[@LINE-20]]:116 -> [[@LINE-20]]:119, [[@LINE-20]]:141 -> [[@LINE-20]]:151, [[@LINE-20]]:172 -> [[@LINE-20]]:177
+-(int)withSomething:(int[1 + 2 - 3])foo usingThing:(Object * (^)(some_type_t, BOOL))a_200 perform:(some_type_t)onEntity __attribute__((test())){
+  [globalObject message] = [self.undef_property struct: @"string literal" object: "]" < ']' withSomething: @"string literal" piece: [self.undef_property withSomething: 12 foo: @"string literal" withSomething: "]" object: [] () {    Object * z_Z_42 = 12 + "string";
+  } part: ^ () {
+   const Object & z_Z_42 = globalArray[i];
+
+ }]];
+
+  some_type_t foo = [self.undef_property foo: 12 * globalArray[i] method: @"string literal" a_200: ^ () {
+   globalArray[12] = [self onEntity: @"string literal" class: "string" onEntity: "]"];
+
+ }/*comment*/];
+}
+// CHECK58: [[@LINE-12]]:7 -> [[@LINE-12]]:20, [[@LINE-12]]:41 -> [[@LINE-12]]:51, [[@LINE-12]]:91 -> [[@LINE-12]]:98
++(int)piece:(int)test
+onEntity:(int[1 + 2 - 3])test piece:(const Object &)piece {
+  [self z_Z_42: ']' usingThing: ("]")];
+
+  if ([self test: [] () {
+   // comment
+
+ } a_200: [] () {    BOOL foo = [self world: [self.undef_property test: globalArray[i] foo: [self method: "]" onEntity: []  {
+
+
+ } withSomething: globalArray[i]] piece: 12 struct: ']'] usingThing: [super test: globalArray[i] world: [_undef_ivar bar: @{ @1, @3 } z_Z_42: [_undef_ivar bar:  z_Z_42: [self foo: ("string") object: ^ () {
+
+
+ } bar: "string"] struct: (12) withSomething: @"string literal" name: [self.undef_property part: @"string literal" onEntity: []  {
+
+
+ }]] onEntity: ']' name: 12 object: @{ @1, @3 }]
+//comment
+] part: globalArray[i] test: 12];
+  } + ']' bar: [super piece: "]" world: @"string literal" object: globalArray[i] test: ']'
+ withSomething: @{ @1, @3 }] piece: [self a_200: ']' world: ']'] onEntity: @"string literal"] == ^ () { ] }) {
+      if (12) {
+      [self.undef_property withSomething: [self a_200: globalArray[i] withSomething: "string"
+ test: [] () {    [self perform: "]" object: ']' foo: @{ @1, @3 } + [] () {
+  }];
+  } object: "string" struct: /*]*/ "]"] piece: @{ @1, @3 } a_200: 12 bar: globalArray[i]];
+
+  }
+
+  }
+}
+// CHECK59: [[@LINE-31]]:7 -> [[@LINE-31]]:12, [[@LINE-30]]:1 -> [[@LINE-30]]:9, [[@LINE-30]]:31 -> [[@LINE-30]]:36
++(some_type_t)withSomething:(BOOL)bar
+z_Z_42:(BOOL)struct {
+  [self usingThing: (globalArray[i]) world: @"string literal" name: [super test: globalArray[i] part: ^ () {
+   [super test: 12 z_Z_42: "string"];
+
+ } perform: ']' perform: "string"] object: "]" name: 12];
+
+  /*comment*/[self world: "string" bar: ^  {
+   [self.undef_property bar: @"string literal" name: ^  {
+
+
+ } z_Z_42: "string" + [_undef_ivar name: [self part: 12 struct: []  {
+  }
+] withSomething: @"string literal" class: ']' < "string" == "]" < "string" == "]"] onEntity: globalArray[i] object: "]"];
+
+ } == ']' test: @"string literal" world: "]" struct: "string"];
+}
+// CHECK60: [[@LINE-17]]:15 -> [[@LINE-17]]:28, [[@LINE-16]]:1 -> [[@LINE-16]]:7
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=piece:perform:onEntity:bar:usingThing:class -new-name=method:bar:piece:onEntity:foo:piece -indexed-file=%s -indexed-at=602:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK57 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:usingThing:perform -new-name=name:usingThing:foo -indexed-file=%s -indexed-at=623:7 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK58 %s
+// RUN: clang-refactor-test rename-indexed-file -name=piece:onEntity:piece -new-name=class:part:world -indexed-file=%s -indexed-at=636:7 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK59 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:z_Z_42 -new-name=object:object -indexed-file=%s -indexed-at=668:15 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK60 %s
+
+@interface test (z_Z_42)
+-(void)struct:(some_type_t)onEntity perform:(void)struct
+usingThing:(BOOL)foo onEntity:(some_type_t)onEntity /*comment*/ a_200:(Object *)piece ;
+// CHECK61: [[@LINE-2]]:8 -> [[@LINE-2]]:14, [[@LINE-2]]:37 -> [[@LINE-2]]:44, [[@LINE-1]]:1 -> [[@LINE-1]]:11, [[@LINE-1]]:22 -> [[@LINE-1]]:30, [[@LINE-1]]:65 -> [[@LINE-1]]:70
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=struct:perform:usingThing:onEntity:a_200 -new-name=method:world:foo:foo:perform -indexed-file=%s -indexed-at=693:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK61 %s
+
+@implementation part
+-(some_type_t)bar:(some_type_t (^)(some_type_t, Object *))class piece:(some_type_t)z_Z_42
+test:(BOOL)z_Z_42 /*comment*/ class:(void)class __attribute__((test())){
+  [globalObject send: [self onEntity:  == ']' z_Z_42: []  {    int bar = [_undef_ivar a_200: [super a_200: @"string literal"
+//comment
+ withSomething: @"string literal" + ^  {
+  }] foo: "]"] other: 42];
+  } test: ^ () {    if ([] () {
+
+
+ }) {
+      int bar = [self part: ^ () {
+  }
+ class: [] () {
+  } object: @"string literal"];
+
+  }
+  }];
+
+  [globalObject message] = [_undef_ivar part: (@{ @1, @3 }) struct: "]" z_Z_42: [self perform: @"string literal" usingThing: ']' a_200: ^  {    // comment
+  } struct: ^ () {
+   if ("string") {
+      int test = "string";
+
+  }
+
+ }]];
+}
+// CHECK62: [[@LINE-27]]:15 -> [[@LINE-27]]:18, [[@LINE-27]]:65 -> [[@LINE-27]]:70, [[@LINE-26]]:1 -> [[@LINE-26]]:5, [[@LINE-26]]:31 -> [[@LINE-26]]:36
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=bar:piece:test:class -new-name=perform:bar:struct:world -indexed-file=%s -indexed-at=700:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK62 %s
+
+@interface perform
++(void)piece:(BOOL)a_200 onEntity:(const Object & (^)())object bar:(int (*)())method //comment
+method:(some_type_t)onEntity
+;
+// CHECK63: [[@LINE-3]]:8 -> [[@LINE-3]]:13, [[@LINE-3]]:26 -> [[@LINE-3]]:34, [[@LINE-3]]:64 -> [[@LINE-3]]:67, [[@LINE-2]]:1 -> [[@LINE-2]]:7
+-(void)withSomething:(const Object &)piece //comment
+piece:(void)perform ;
+// CHECK64: [[@LINE-2]]:8 -> [[@LINE-2]]:21, [[@LINE-1]]:1 -> [[@LINE-1]]:6
+-(some_type_t)z_Z_42:(int)method piece:(^ { })struct struct:(BOOL)world /*comment*/ a_200:(const Object &)piece
+;
+// CHECK65: [[@LINE-2]]:15 -> [[@LINE-2]]:21, [[@LINE-2]]:34 -> [[@LINE-2]]:39, [[@LINE-2]]:54 -> [[@LINE-2]]:60, [[@LINE-2]]:85 -> [[@LINE-2]]:90
++(Object *)foo:(const Object &)part bar:(some_type_t)a_200 ;
+// CHECK66: [[@LINE-1]]:12 -> [[@LINE-1]]:15, [[@LINE-1]]:37 -> [[@LINE-1]]:40
+@end
+// RUN: clang-refactor-test rename-indexed-file -name=piece:onEntity:bar:method -new-name=onEntity:withSomething:class:piece -indexed-file=%s -indexed-at=732:8 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK63 %s
+// RUN: clang-refactor-test rename-indexed-file -name=withSomething:piece -new-name=perform:foo -indexed-file=%s -indexed-at=736:8 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK64 %s
+// RUN: clang-refactor-test rename-indexed-file -name=z_Z_42:piece:struct:a_200 -new-name=test:withSomething:piece:class -indexed-file=%s -indexed-at=739:15 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK65 %s
+// RUN: clang-refactor-test rename-indexed-file -name=foo:bar -new-name=usingThing:a_200 -indexed-file=%s -indexed-at=742:12 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK66 %s
diff --git a/test/Refactor/Rename/IndexedObjCMethodEmptySelector.mm b/test/Refactor/Rename/IndexedObjCMethodEmptySelector.mm
new file mode 100644
index 0000000..f533331
--- /dev/null
+++ b/test/Refactor/Rename/IndexedObjCMethodEmptySelector.mm
@@ -0,0 +1,49 @@
+
+@interface EmptySelectorsRule_Psych
+
+- (int):(int)_; // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:8
+- (void)test: (int)x :(int)y; // CHECK2: rename [[@LINE]]:9 -> [[@LINE]]:13, [[@LINE]]:22 -> [[@LINE]]:22
+- (void):(int)_ :(int) m:(int)z; // CHECK3: rename [[@LINE]]:9 -> [[@LINE]]:9, [[@LINE]]:17 -> [[@LINE]]:17, [[@LINE]]:25 -> [[@LINE]]:25
+
+@end
+
+namespace g {
+    int x;
+}
+
+@implementation EmptySelectorsRule_Psych
+
+- (int):(int)_ { // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:8
+    [self :2];   // CHECK1: rename [[@LINE]]:11 -> [[@LINE]]:11
+    SEL s0 = @selector(:); // CHECK1: selector [[@LINE]]:24 -> [[@LINE]]:24
+    // CHECK1-NOT: comment
+    // CHECK1-NOT: rename
+    // CHECK1-NOT: selector
+// RUN: clang-refactor-test rename-indexed-file -name=: -new-name=foo -indexed-file=%s -indexed-symbol-kind=objc-im -indexed-at=4:8 -indexed-at=16:8 -indexed-at=objc-message:17:11 %s | FileCheck --check-prefix=CHECK1 %s
+    return 0;
+}
+- (void)test: (int)x :(int)y { } // CHECK2: rename [[@LINE]]:9 -> [[@LINE]]:13, [[@LINE]]:22 -> [[@LINE]]:22
+- (void) :(int)_ :(int)m :(int)z { // CHECK3: rename [[@LINE]]:10 -> [[@LINE]]:10, [[@LINE]]:18 -> [[@LINE]]:18, [[@LINE]]:26 -> [[@LINE]]:26
+    [self test:0:1]; // CHECK2: rename [[@LINE]]:11 -> [[@LINE]]:15, [[@LINE]]:17 -> [[@LINE]]:17
+    SEL s1 = @selector(test::); // CHECK2: selector [[@LINE]]:24 -> [[@LINE]]:28, [[@LINE]]:29 -> [[@LINE]]:29
+    @selector(test: :); // CHECK2: selector [[@LINE]]:15 -> [[@LINE]]:19, [[@LINE]]:21 -> [[@LINE]]:21
+    // CHECK2-NOT: comment
+    // CHECK2-NOT: rename
+    // CHECK2-NOT: selector
+// RUN: clang-refactor-test rename-indexed-file -name=test:: -new-name=foo:bar: -indexed-file=%s -indexed-symbol-kind=objc-im -indexed-at=5:9 -indexed-at=25:9 -indexed-at=objc-message:27:11 %s | FileCheck --check-prefix=CHECK2 %s
+
+    [self: ::g::x + ([self: 0]):~0 :3]; // CHECK3: rename [[@LINE]]:10 -> [[@LINE]]:10, [[@LINE]]:32 -> [[@LINE]]:32, [[@LINE]]:36 -> [[@LINE]]:36
+    SEL s2 = @selector(:::); // CHECK3: selector [[@LINE]]:24 -> [[@LINE]]:24, [[@LINE]]:25 -> [[@LINE]]:25, [[@LINE]]:26 -> [[@LINE]]:26
+    @selector(: ::); // CHECK3: selector [[@LINE]]:15 -> [[@LINE]]:15, [[@LINE]]:17 -> [[@LINE]]:17, [[@LINE]]:18 -> [[@LINE]]:18
+    @selector(::::); // not matching.
+    // CHECK3-NOT: comment
+    // CHECK3-NOT: rename
+    // CHECK3-NOT: selector
+// RUN: clang-refactor-test rename-indexed-file -name=::: -new-name=do:stuff:: -indexed-file=%s -indexed-symbol-kind=objc-im -indexed-at=6:9 -indexed-at=26:10 -indexed-at=objc-message:35:10 %s | FileCheck --check-prefix=CHECK3 %s
+
+    // NO Textual matches: text:
+    // :
+    // :::
+}
+
+@end
diff --git a/test/Refactor/Rename/IndexedObjCProperty.m b/test/Refactor/Rename/IndexedObjCProperty.m
new file mode 100644
index 0000000..003186d
--- /dev/null
+++ b/test/Refactor/Rename/IndexedObjCProperty.m
@@ -0,0 +1,45 @@
+@interface I1
+
+@property int p1;
+
+@end
+
+@implementation I1
+
+- (void)foo {
+  self.p1;         // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:10
+  [self p1];       // CHECK: rename [[@LINE]]:9 -> [[@LINE]]:11
+  [self setP1: 2]; // CHECK: rename "setFoo" [[@LINE]]:9 -> [[@LINE]]:14
+  _p1 = 3;         // CHECK: rename "_foo" [[@LINE]]:3 -> [[@LINE]]:6
+}
+
+@end
+
+// RUN: clang-refactor-test rename-indexed-file -name=p1 -name=p1 -name=setP1 -name=_p1 -new-name=foo -new-name=foo -new-name=setFoo -new-name=_foo -indexed-file=%s -indexed-at=10:8 -indexed-at=objc-im:1:11:9 -indexed-at=objc-im:2:12:9 -indexed-at=3:13:3 %s | FileCheck %s
+
+// p1 _p1 setP1
+// CHECK: comment [[@LINE-1]]:4
+// CHECK: comment "_foo" [[@LINE-2]]:7
+// CHECK: comment "setFoo" [[@LINE-3]]:11
+
+@selector(p1)
+@selector(setP1:)
+@selector(_p1)
+// CHECK: selector [[@LINE-3]]:11
+// CHECK: selector "setFoo" [[@LINE-3]]:11
+// CHECK-NOT: selector
+
+@interface ImplicitProperty
+
+- (int)implicit; // IMPL_GET: rename [[@LINE]]:8 -> [[@LINE]]:16
+- (void)setImplicit:(int)x; // IMPL_SET: rename [[@LINE]]:9 -> [[@LINE]]:20
+
+@end
+
+void useImplicitProperty(ImplicitProperty *x) {
+  x.implicit; // IMPL_GET: rename [[@LINE]]:5 -> [[@LINE]]:13
+  x.implicit = 0; // IMPL_SET: implicit-property [[@LINE]]:5 -> [[@LINE]]:13
+}
+
+// RUN: clang-refactor-test rename-indexed-file -name=implicit -new-name=foo -indexed-file=%s -indexed-at=objc-im:34:8 -indexed-at=objc-message:40:5 %s | FileCheck --check-prefix=IMPL_GET %s
+// RUN: clang-refactor-test rename-indexed-file -name=setImplicit -new-name=setFoo -indexed-file=%s -indexed-at=objc-im:35:9 -indexed-at=objc-message:41:5 %s | FileCheck --check-prefix=IMPL_SET %s
diff --git a/test/Refactor/Rename/Inputs/MultiFileTUHeader.h b/test/Refactor/Rename/Inputs/MultiFileTUHeader.h
new file mode 100644
index 0000000..2e8d29f
--- /dev/null
+++ b/test/Refactor/Rename/Inputs/MultiFileTUHeader.h
@@ -0,0 +1,6 @@
+class Foo {  // CHECK: rename "{{.*}}/Inputs/MultiFileTUHeader.h" [[@LINE]]:7 -> [[@LINE]]:10
+public:
+  Foo();     // CHECK: rename "{{.*}}/Inputs/MultiFileTUHeader.h" [[@LINE]]:3 -> [[@LINE]]:6
+
+  void method();
+};
diff --git a/test/Refactor/Rename/Inputs/ObjCImplementationTURequestsImplementation.m b/test/Refactor/Rename/Inputs/ObjCImplementationTURequestsImplementation.m
new file mode 100644
index 0000000..249aa7f
--- /dev/null
+++ b/test/Refactor/Rename/Inputs/ObjCImplementationTURequestsImplementation.m
@@ -0,0 +1,3 @@
+@implementation ExplicitIVarsInInterface
+
+@end
diff --git a/test/Refactor/Rename/Inputs/TransparentEnum.h b/test/Refactor/Rename/Inputs/TransparentEnum.h
new file mode 100644
index 0000000..b21adae
--- /dev/null
+++ b/test/Refactor/Rename/Inputs/TransparentEnum.h
@@ -0,0 +1 @@
+#define TRANSPARENT_ENUM(_name, _type) enum _name:_type _name; enum _name : _type
diff --git a/test/Refactor/Rename/Inputs/objc-system-header.h b/test/Refactor/Rename/Inputs/objc-system-header.h
new file mode 100644
index 0000000..23b252a
--- /dev/null
+++ b/test/Refactor/Rename/Inputs/objc-system-header.h
@@ -0,0 +1,5 @@
+@interface MySystemClass
+
+- (void)someMethod:(int)x with:(int)y;
+
+@end
diff --git a/test/Refactor/Rename/Inputs/rename-indexed-file.cpp b/test/Refactor/Rename/Inputs/rename-indexed-file.cpp
new file mode 100644
index 0000000..ec6b78d
--- /dev/null
+++ b/test/Refactor/Rename/Inputs/rename-indexed-file.cpp
@@ -0,0 +1,4 @@
+void Test::otherFile() {
+  Test m;
+  m.~Test();
+}
diff --git a/test/Refactor/Rename/Inputs/system-header.h b/test/Refactor/Rename/Inputs/system-header.h
new file mode 100644
index 0000000..ae1af94
--- /dev/null
+++ b/test/Refactor/Rename/Inputs/system-header.h
@@ -0,0 +1,11 @@
+void systemFunction();
+
+struct SystemStruct {
+};
+typedef struct SystemStruct SystemTypedef;
+
+enum SystemEnum {
+  SystemEnumCase
+};
+
+extern int systemVariable;
diff --git a/test/Refactor/Rename/LocalBlockSymbol.m b/test/Refactor/Rename/LocalBlockSymbol.m
new file mode 100644
index 0000000..93235aa
--- /dev/null
+++ b/test/Refactor/Rename/LocalBlockSymbol.m
@@ -0,0 +1,58 @@
+__auto_type escaping1 = ^ {
+  struct Local {  // LOCAL1: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:2:10 -new-name=name %s -fblocks -x objective-c-header | FileCheck --check-prefix=LOCAL1 %s
+
+    int x;// ESCAPES1: rename [[@LINE]]
+          // NOESCAPE1: rename local [[@LINE-1]]
+// RUN: clang-refactor-test rename-initiate -at=%s:5:9 -new-name=name %s -fblocks -x objective-c-header | FileCheck --check-prefix=ESCAPES1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:5:9 -new-name=name %s -fblocks -x objective-c | FileCheck --check-prefix=NOESCAPE1 %s
+  };
+  struct Local result;
+  return result;
+};
+
+__auto_type escaping2 = ^ () { // no prototype,
+  struct Local {  // LOCAL2: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:15:10 -new-name=name %s -fblocks -x objective-c-header | FileCheck --check-prefix=LOCAL2 %s
+
+    int x;// ESCAPES2: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:18:9 -new-name=name %s -fblocks -x objective-c-header | FileCheck --check-prefix=ESCAPES2 %s
+  };
+  struct Local result;
+  return result;
+};
+
+__auto_type outer1 = ^ {
+  __auto_type escaping3 = ^ (int x) { // prototype with some arguments.
+    struct Local {  // LOCAL3: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:27:12 -new-name=name %s -fblocks -x objective-c-header | FileCheck --check-prefix=LOCAL3 %s
+
+      int x;// ESCAPES3: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:30:11 -new-name=name %s -fblocks -x objective-c-header | FileCheck --check-prefix=ESCAPES3 %s
+    };
+    struct Local result;
+    return result;
+  };
+  return escaping3(0);
+};
+
+void outer2() {
+  __auto_type escaping1 = ^ {
+    struct Local {
+      int x;// LOCAL4: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:42:11 -new-name=name %s -fblocks -x objective-c-header | FileCheck --check-prefix=LOCAL4 %s
+    };
+    struct Local result;
+    return result;
+  };
+}
+
+__auto_type normalBlock = ^int (void) {
+  struct Local {  // LOCAL5: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:51:10 -new-name=name %s -fblocks -x objective-c-header | FileCheck --check-prefix=LOCAL5 %s
+
+    int x;// LOCAL6: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:54:9 -new-name=name %s -fblocks -x objective-c-header | FileCheck --check-prefix=LOCAL6 %s
+  };
+  return 0;
+};
diff --git a/test/Refactor/Rename/LocalBlockSymbolCpp.mm b/test/Refactor/Rename/LocalBlockSymbolCpp.mm
new file mode 100644
index 0000000..d48f3b5
--- /dev/null
+++ b/test/Refactor/Rename/LocalBlockSymbolCpp.mm
@@ -0,0 +1,24 @@
+auto escaping1 = ^ {
+  struct Global {  // ESCAPES1: rename [[@LINE]]
+                   // NOESCAPE1: rename local [[@LINE-1]]
+// RUN: clang-refactor-test rename-initiate -at=%s:2:10 -new-name=name %s -std=c++14 -fblocks -x objective-c++-header | FileCheck --check-prefix=ESCAPES1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:2:10 -new-name=name %s -std=c++14 -fblocks -x objective-c++ | FileCheck --check-prefix=NOESCAPE1 %s
+  };
+  return Global();
+};
+
+void outer1() {
+  auto escaping1 = ^ {
+    struct Local {  // LOCAL1: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:12:12 -new-name=name %s -std=c++14 -fblocks -x objective-c++-header | FileCheck --check-prefix=LOCAL1 %s
+    };
+    return Local();
+  };
+}
+
+auto normalBlock = ^int () {
+  struct Local {  // LOCAL2: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:20:10 -new-name=name %s -std=c++14 -fblocks -x objective-c++-header | FileCheck --check-prefix=LOCAL2 %s
+  };
+  return 0;
+};
diff --git a/test/Refactor/Rename/LocalSymbol.cpp b/test/Refactor/Rename/LocalSymbol.cpp
new file mode 100644
index 0000000..4bc82ed
--- /dev/null
+++ b/test/Refactor/Rename/LocalSymbol.cpp
@@ -0,0 +1,232 @@
+static int staticIsGlobalVar = 0; // CHECK1: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:1:12 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK1 %s
+
+int globalVar = 0; // CHECK2: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:4:5 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK2 %s
+
+struct GlobalFoo { // CHECK3: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:7:8 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK3 %s
+
+  struct GlobalBar { // CHECK4: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:10:10 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK4 %s
+  };
+
+  void foo() { // CHECK5: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:14:8 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK5 %s
+
+    struct LocalFoo { }; // CHECK6: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:17:12 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK6 %s
+  }
+
+  virtual void bar() { } // CHECK-BAR: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:21:16 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK-BAR %s
+
+  int globalField; // CHECK7: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:24:7 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK7 %s
+};
+
+enum GlobalEnum { // CHECK8: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:28:6 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK8 %s
+
+  GlobalEnumCase = 0 // CHECK9: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:31:3 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK9 %s
+};
+
+namespace {
+  struct AnonymousIsGlobalFoo { }; // CHECK10: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:36:10 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=CHECK10 %s
+
+  void globalFoo() { } // CHECK11: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:39:8 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=CHECK11 %s
+}
+
+namespace globalNamespace { // CHECK12: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:43:11 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK12 %s
+}
+
+void func(int localParam) { // CHECK13: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:47:15 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK13 %s
+
+  int localVar = 0; // CHECK14: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:50:7 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK14 %s
+
+  enum LocalEnum { // CHECK15: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:53:8 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK15 %s
+
+    LocalEnumCase = 0 // CHECK16: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:56:5 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK16 %s
+  };
+
+  struct LocalFoo: GlobalFoo { // CHECK17: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:60:10 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK17 %s
+
+    struct LocalBar { }; // CHECK18: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:63:12 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK18 %s
+
+    void foo() { } // CHECK19: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:66:10 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK19 %s
+
+    // Bar is global since it overrides GlobalFoo::bar
+    void bar() { } // CHECK-BAR: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:70:10 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK-BAR %s
+
+    int localField; // CHECK20: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:73:10 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK20 %s
+  };
+}
+
+auto escapable1 = []() -> auto {
+  struct Global {  // ESCAPES1: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:79:10 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES1 %s
+
+    int field = 2; // ESCAPES2: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:82:9 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES2 %s
+
+    void foo() { } // ESCAPES3: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:85:10 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES3 %s
+  };
+  return Global();
+};
+
+auto escapable2() {
+  struct Global {  // ESCAPES4: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:92:10 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES4 %s
+
+    int field = 2; // ESCAPES5: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:95:9 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES5 %s
+
+    void foo() { } // ESCAPES6: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:98:10 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES6 %s
+  };
+  return Global();
+}
+
+template<typename T>
+struct C {
+  T x;
+};
+
+decltype(auto) escapable4() {
+  struct Global {  // ESCAPES7: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:110:10 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES7 %s
+  };
+  return C<Global>();
+}
+
+auto escapable5() -> decltype(auto) {
+  struct Foo {
+    struct Global { // ESCAPES8: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:118:12 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES8 %s
+    };
+  };
+  return C<Foo::Global>();
+}
+
+auto escapable6() {
+  struct Foo {
+    struct Global { // ESCAPES9: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:127:12 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES9 %s
+    };
+  };
+  return Foo::Global();
+}
+
+auto escapableOuter1() {
+  struct Foo {
+    auto escapableInner() {
+      struct Global {  // ESCAPES10: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:137:14 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES10 %s
+      };
+      return Global();
+    }
+  }
+  return Foo().escapableInner();
+}
+
+auto escapableOuter2() {
+  auto escapableInner = []() -> auto {
+    struct Global {  // ESCAPES11: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:148:12 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES11 %s
+    };
+    return Global();
+  }
+  return escapableInner();
+}
+
+void outer() {
+  auto escapableInner2 = []() -> auto {
+    struct Local {  // ESCAPES12: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:158:12 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES12 %s
+    };
+    return Local();
+  }
+  struct Foo {
+    auto foo() {
+      struct Local {  // ESCAPES13: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:165:14 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES13 %s
+      };
+      return Local();
+    }
+  };
+}
+
+struct Escapable {
+  auto escapable() {
+    struct Global {  // ESCAPES14: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:175:12 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES14 %s
+    };
+    return Global();
+  }
+};
+
+auto escapableViaTypedef() {
+  struct Global {  // ESCAPES15: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:183:10 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ESCAPES15 %s
+  };
+  typedef Foo Global;
+  return Foo();
+}
+
+auto nonescapable1 = []() -> auto {
+  struct Local {  // NOESCAPE1: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:191:10 -new-name=name %s -std=c++14 -x c++ | FileCheck --check-prefix=NOESCAPE1 %s
+
+    int field = 2; // NOESCAPE2: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:194:9 -new-name=name %s -std=c++14 -x c++ | FileCheck --check-prefix=NOESCAPE2 %s
+
+    void foo() { } // NOESCAPE3: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:197:10 -new-name=name %s -std=c++14 -x c++ | FileCheck --check-prefix=NOESCAPE3 %s
+  };
+  return Local();
+};
+
+static void localOrGlobal1() { }; // ISGLOBAL1: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:203:13 -new-name=name %s -std=c++14 -x c++ | FileCheck --check-prefix=ISGLOBAL1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:203:13 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ISGLOBAL1 %s
+
+namespace {
+
+struct LocalOrGlobal { }; // ISGLOBAL2: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:209:13 -new-name=name %s -std=c++14 -x c++ | FileCheck --check-prefix=ISGLOBAL2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:209:13 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ISGLOBAL2 %s
+
+
+void localOrGlobal2() { }; // ISGLOBAL3: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:214:13 -new-name=name %s -std=c++14 | FileCheck --check-prefix=ISGLOBAL3 %s
+}
+
+
+struct LocalOrGlobalWrapper1 {
+
+  static void foo() { } // ISGLOBAL4: rename [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:221:15 -new-name=name %s -std=c++14 -x c++ | FileCheck --check-prefix=ISGLOBAL4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:221:15 -new-name=name %s -std=c++14 -x c++-header | FileCheck --check-prefix=ISGLOBAL4 %s
+};
+
+void func2(int x) {
+  auto lambda1 = [x] // CHECK21: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:226:16 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK21 %s
+    (int z) { // CHECK22: rename local [[@LINE]]
+// RUN: clang-refactor-test rename-initiate -at=%s:229:10 -new-name=name %s -std=c++14 | FileCheck --check-prefix=CHECK22 %s
+  }
+}
diff --git a/test/Refactor/Rename/MemberExprMacro.cpp b/test/Refactor/Rename/MemberExprMacro.cpp
new file mode 100644
index 0000000..dfd7ec0
--- /dev/null
+++ b/test/Refactor/Rename/MemberExprMacro.cpp
@@ -0,0 +1,19 @@
+class Baz {
+public:
+  int Foo;  /* Test 1 */    // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+};
+
+int qux(int x) { return 0; }
+#define MACRO(a) qux(a)
+
+int main() {
+  Baz baz;
+  baz.Foo = 1; /* Test 2 */ // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+  MACRO(baz.Foo);           // CHECK: rename [[@LINE]]:13 -> [[@LINE]]:16
+  int y = baz.Foo;          // CHECK: rename [[@LINE]]:15 -> [[@LINE]]:18
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:3:7 -new-name=Bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:11:7 -new-name=Bar %s | FileCheck %s
diff --git a/test/Refactor/Rename/MultiFileTU.cpp b/test/Refactor/Rename/MultiFileTU.cpp
new file mode 100644
index 0000000..14b0be2
--- /dev/null
+++ b/test/Refactor/Rename/MultiFileTU.cpp
@@ -0,0 +1,9 @@
+#include "Inputs/MultiFileTUHeader.h"
+
+Foo::Foo() {}  // CHECK: rename "{{.*}}MultiFileTU.cpp" [[@LINE]]:1 -> [[@LINE]]:4
+// CHECK: rename "{{.*}}MultiFileTU.cpp" [[@LINE-1]]:6 -> [[@LINE-1]]:9
+
+void Foo::method() { } // CHECK: rename "{{.*}}MultiFileTU.cpp" [[@LINE]]:6 -> [[@LINE]]:9
+
+// RUN: clang-refactor-test rename-initiate -at=%s:3:6 -at=%s:6:6 -new-name=Bar %s | FileCheck %s
+// RUN: clang-refactor-test rename-initiate -at=%s:3:6 -at=%s:6:6 -new-name=Bar %s | FileCheck %S/Inputs/MultiFileTUHeader.h
diff --git a/test/Refactor/Rename/Namespace.cpp b/test/Refactor/Rename/Namespace.cpp
new file mode 100644
index 0000000..1a0900f
--- /dev/null
+++ b/test/Refactor/Rename/Namespace.cpp
@@ -0,0 +1,22 @@
+namespace gcc /* Test 1 */ {  // CHECK: rename [[@LINE]]:11 -> [[@LINE]]:14
+  int x;
+}
+
+void boo() {
+  gcc::x = 42;                // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:1:11 -new-name=clang %s | FileCheck %s
+
+namespace ns1 {
+namespace ns2 { // CHECK2: rename [[@LINE]]:11 -> [[@LINE]]:14
+void f();
+}
+}
+
+void testVisitTwice() {
+  ns1::ns2::f(); // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:11
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:19:8 -new-name=clang %s | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Rename/NoNewName.cpp b/test/Refactor/Rename/NoNewName.cpp
new file mode 100644
index 0000000..0fe0069
--- /dev/null
+++ b/test/Refactor/Rename/NoNewName.cpp
@@ -0,0 +1,4 @@
+// Check for an error while -new-name argument has not been passed to
+// clang-rename.
+// RUN: not clang-refactor-test rename-initiate -at=%s:1:11 %s 2>&1 | FileCheck %s
+// CHECK: clang-refactor-test: for the -new-name option: must be specified at least once
diff --git a/test/Refactor/Rename/ObjCClass.m b/test/Refactor/Rename/ObjCClass.m
new file mode 100644
index 0000000..aacfc2c
--- /dev/null
+++ b/test/Refactor/Rename/ObjCClass.m
@@ -0,0 +1,95 @@
+@class I1, // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+       I2; // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:10
+
+@interface I1 // CHECK1: rename [[@LINE]]:12 -> [[@LINE]]:14
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:1:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:4:12 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:2:8 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+@implementation I1 { // CHECK1: rename [[@LINE]]:17 -> [[@LINE]]:19
+  I1 *interfaceIVar; // CHECK1: rename [[@LINE]]:3 -> [[@LINE]]:5
+                     // CHECK4: rename [[@LINE-1]]:7 -> [[@LINE-1]]:20
+  int ivar; // CHECK3: rename [[@LINE]]:7 -> [[@LINE]]:11
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:11:17 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:12:3 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:21:20 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+-(void)foo: (const I1 *)bar { // CHECK1: rename [[@LINE]]:20 -> [[@LINE]]:22
+
+  ivar = 1;        // CHECK3: rename [[@LINE]]:3 -> [[@LINE]]:7
+  self->ivar = 2;  // CHECK3: rename [[@LINE]]:9 -> [[@LINE]]:13
+  print(bar->ivar);// CHECK3: rename [[@LINE]]:14 -> [[@LINE]]:18
+  interfaceIVar->ivar = 4; // CHECK4: rename [[@LINE]]:3 -> [[@LINE]]:16
+                           // CHECK3: rename [[@LINE-1]]:18 -> [[@LINE-1]]:22
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:14:7 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:23:3 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:24:9 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:25:14 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:26:18 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:12:7 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:26:3 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+
+@end
+
+@interface I1 (Category) // CHECK1: rename [[@LINE]]:12 -> [[@LINE]]:14
+@end                     // CHECK5: rename [[@LINE-1]]:16 -> [[@LINE-1]]:24
+
+@implementation I1 (Category) // CHECK1: rename [[@LINE]]:17 -> [[@LINE]]:19
+@end                          // CHECK5: rename [[@LINE-1]]:21 -> [[@LINE-1]]:29
+
+// RUN: clang-refactor-test rename-initiate -at=%s:41:12 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:44:17 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:41:16 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:44:21 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+
+// Implementation only-category:
+
+@interface I3 // CHECK6: rename [[@LINE]]:12 -> [[@LINE]]:14
+@end
+
+@implementation I3 (DummyCategory) // CHECK6: rename [[@LINE]]:17 -> [[@LINE]]:19
+@end                               // CHECK7: rename [[@LINE-1]]:21 -> [[@LINE-1]]:34
+
+// RUN: clang-refactor-test rename-initiate -at=%s:55:12 -new-name=foo %s | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:58:17 -new-name=foo %s | FileCheck --check-prefix=CHECK6 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:58:21 -new-name=foo %s | FileCheck --check-prefix=CHECK7 %s
+
+// Class extension:
+
+@interface I3 () // CHECK6: rename [[@LINE]]:12 -> [[@LINE]]:14
+@end
+
+@implementation I3 // CHECK6: rename [[@LINE]]:17 -> [[@LINE]]:19
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:68:12 -new-name=foo %s | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:71:17 -new-name=foo %s | FileCheck --check-prefix=CHECK6 %s
+
+// Ivar declared in the interface:
+
+@interface I4 {
+  @public
+  int ivar1; // CHECK8: rename [[@LINE]]:7 -> [[@LINE]]:12
+}
+@end
+
+@implementation I4 {
+}
+
+- (void)foo {
+  ivar1 = 0; // CHECK8: rename [[@LINE]]:3 -> [[@LINE]]:8
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:81:7 -new-name=foo %s | FileCheck --check-prefix=CHECK8 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:89:3 -new-name=foo %s | FileCheck --check-prefix=CHECK8 %s
diff --git a/test/Refactor/Rename/ObjCClassProperty.m b/test/Refactor/Rename/ObjCClassProperty.m
new file mode 100644
index 0000000..4c8c9e0
--- /dev/null
+++ b/test/Refactor/Rename/ObjCClassProperty.m
@@ -0,0 +1,100 @@
+@interface ExplicitClassProperty
+
+@property(class) int p1; // CHECK1: rename [[@LINE]]:22 -> [[@LINE]]:24
+@property(class, readonly) int p2; // CHECK2: rename [[@LINE]]:32 -> [[@LINE]]:34
+
++ (int)p1; // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+
+@end
+
+@implementation ExplicitClassProperty
+
+@dynamic p1; // CHECK1: rename [[@LINE]]:10 -> [[@LINE]]:12
+
+@dynamic p2; // CHECK2: rename [[@LINE]]:10 -> [[@LINE]]:12
+
++ (int)p1 { // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return 1;
+}
+// TODO: remove
++ (void)setP1:(int)x { // CHECK1: rename [[@LINE]]:9 -> [[@LINE]]:14
+}
+
++ (int)p2 { // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return 2;
+}
+
+- (void)foo {
+  ExplicitClassProperty.p1 =  // CHECK1: rename [[@LINE]]:25 -> [[@LINE]]:27
+    ExplicitClassProperty.p2; // CHECK2: rename [[@LINE]]:27 -> [[@LINE]]:29
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:3:22 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:6:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:12:10 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:16:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:20:9 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:28:25 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:4:32 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:14:10 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:23:8 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:29:27 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+@interface ImplicitClassProperty
+
++(int)p3; // CHECK3: rename [[@LINE]]:7 -> [[@LINE]]:9
++(void)setP3:(int)x; // CHECK4: rename [[@LINE]]:8 -> [[@LINE]]:13
++(int)p4; // CHECK5: rename [[@LINE]]:7 -> [[@LINE]]:9
+
+@end
+
+@implementation ImplicitClassProperty
+
++ (int)p3 { // CHECK3: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return 0;
+}
+
+- (void)foo {
+  ImplicitClassProperty.p3 =      // CHECK3: implicit-property [[@LINE]]:25 -> [[@LINE]]:27
+                                  // CHECK4: implicit-property [[@LINE-1]]:25 -> [[@LINE-1]]:30
+        ImplicitClassProperty.p4; // CHECK5: implicit-property [[@LINE]]:31 -> [[@LINE]]:33
+  (void)ImplicitClassProperty.p3; // CHECK3: implicit-property [[@LINE]]:31 -> [[@LINE]]:33
+                                  // CHECK4: implicit-property [[@LINE-1]]:31 -> [[@LINE-1]]:36
+
+  int x = [ImplicitClassProperty p3]; // CHECK3: rename [[@LINE]]:34 -> [[@LINE]]:36
+  [ImplicitClassProperty setP3: x];   // CHECK4: rename [[@LINE]]:26 -> [[@LINE]]:31
+  x = [ImplicitClassProperty p4];     // CHECK5: rename [[@LINE]]:30 -> [[@LINE]]:32
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:48:7 -at=%s:64:31 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:49:8 -at=%s:61:25 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:50:7 -at=%s:63:31 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+
+
+
+
+
+
+
+
+@interface ClassReceivers // CHECK-RECEIVER: rename [[@LINE]]:12 -> [[@LINE]]:26
+
+@property(class) int p1;
++ (int)implicit;
++ (void)setImplicit:(int)x;
+
+@end
+
+void classReceivers() {
+  ClassReceivers.p1 = 0; // CHECK-RECEIVER: rename [[@LINE]]:3 -> [[@LINE]]:17
+  int y = ClassReceivers.p1; // CHECK-RECEIVER: rename [[@LINE]]:11 -> [[@LINE]]:25
+  ClassReceivers.implicit = 0; // CHECK-RECEIVER: rename [[@LINE]]:3 -> [[@LINE]]:17
+  int x = ClassReceivers.implicit; // CHECK-RECEIVER: rename [[@LINE]]:11 -> [[@LINE]]:25
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:94:3 -at=%s:95:11 -at=%s:96:3 -at=%s:97:11 -new-name=x %s | FileCheck --check-prefix=CHECK-RECEIVER %s
diff --git a/test/Refactor/Rename/ObjCCompatibilityAlias.m b/test/Refactor/Rename/ObjCCompatibilityAlias.m
new file mode 100644
index 0000000..da98da6
--- /dev/null
+++ b/test/Refactor/Rename/ObjCCompatibilityAlias.m
@@ -0,0 +1,44 @@
+@class I1, // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+       I2; // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:10
+
+@interface I1 // CHECK1: rename [[@LINE]]:12 -> [[@LINE]]:14
+@end
+
+@compatibility_alias I1Alias I1; // CHECK3: rename [[@LINE]]:22 -> [[@LINE]]:29
+                                 // CHECK1: rename [[@LINE-1]]:30 -> [[@LINE-1]]:32
+
+@compatibility_alias I2Alias I2; // CHECK4: rename [[@LINE]]:22 -> [[@LINE]]:29
+                                 // CHECK2: rename [[@LINE-1]]:30 -> [[@LINE-1]]:32
+
+// RUN: clang-refactor-test rename-initiate -at=%s:7:30 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:10:30 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:7:22 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:10:22 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+
+// TODO: Implement TypeLocs for @compatibility_alias (rdar://29245831)
+// XFAIL: *
+void foo(I1Alias *object) { // CHECK3: rename [[@LINE]]:10 -> [[@LINE]]:17
+}
+
+@implementation I1 { // CHECK1: rename [[@LINE]]:17 -> [[@LINE]]:19
+  I1Alias *object;   // CHECK3: rename [[@LINE]]:3 -> [[@LINE]]:10
+}
+
+-(const I1Alias *)foo:(I2Alias *)object { // CHECK3: rename [[@LINE]]:9 -> [[@LINE]]:16
+                                          // CHECK4: rename [[@LINE-1]]:24 -> [[@LINE-1]]:31
+  return (const I1Alias *)self->object;   // CHECK3: rename [[@LINE]]:17 -> [[@LINE]]:24
+}
+
+@end
+
+@interface I3: I1Alias // CHECK3: rename [[@LINE]]:16 -> [[@LINE]]:23
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:21:10 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:25:3 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:28:9 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:30:17 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:35:16 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:28:24 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
diff --git a/test/Refactor/Rename/ObjCImplementationTURequests.m b/test/Refactor/Rename/ObjCImplementationTURequests.m
new file mode 100644
index 0000000..9486a8a
--- /dev/null
+++ b/test/Refactor/Rename/ObjCImplementationTURequests.m
@@ -0,0 +1,32 @@
+@interface ExplicitIVarsInInterface {
+  int _requiresImplementationTU;
+}
+
+@property int requiresImplementationTU;
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:2:7 -new-name=foo -implementation-tu="%S/Inputs/ObjCImplementationTURequestsImplementation.m" -dump-symbols %s | FileCheck --check-prefix=CHECK1 %s
+// CHECK1: Implementation TU USR: 'c:objc(cs)ExplicitIVarsInInterface@_requiresImplementationTU'
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:2:7 -new-name=foo -implementation-tu="%S/MissingFile.m" -dump-symbols %s 2>&1 | FileCheck --check-prefix=CHECK-ERR1 %s
+// CHECK-ERR1: failed to load implementation TU
+
+@interface NoNeedForImplementationTUs {
+  int _p1;
+}
+
+@property int p1;
+@property int p2;
+
+@end
+
+@implementation NoNeedForImplementationTUs {
+  int _p2;
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:16:7 -new-name=foo %s | FileCheck --check-prefix=CHECK-NO %s
+// RUN: clang-refactor-test rename-initiate -at=%s:25:7 -new-name=foo %s | FileCheck --check-prefix=CHECK-NO %s
+// CHECK-NO-NOT: Implementation TU USR
diff --git a/test/Refactor/Rename/ObjCImplicitProperty.m b/test/Refactor/Rename/ObjCImplicitProperty.m
new file mode 100644
index 0000000..b587f41
--- /dev/null
+++ b/test/Refactor/Rename/ObjCImplicitProperty.m
@@ -0,0 +1,31 @@
+@interface I1
+
+-(int)p1; // CHECK1: rename [[@LINE]]:7 -> [[@LINE]]:9
+-(void)setP1:(int)x; // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:13
+-(int)p2; // CHECK3: rename [[@LINE]]:7 -> [[@LINE]]:9
+
+@end
+
+@implementation I1
+
+- (int)p1 { // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return 0;
+}
+
+- (void)foo: (I1 *)other {
+  self.p1 =       // CHECK1: implicit-property [[@LINE]]:8 -> [[@LINE]]:10
+                  // CHECK2: implicit-property [[@LINE-1]]:8 -> [[@LINE-1]]:13
+             self.p2; // CHECK3: implicit-property [[@LINE]]:19 -> [[@LINE]]:21
+  (void)other.p1; // CHECK1: implicit-property [[@LINE]]:15 -> [[@LINE]]:17
+                  // CHECK2: implicit-property [[@LINE-1]]:15 -> [[@LINE-1]]:20
+
+  int x = [self p1]; // CHECK1: rename [[@LINE]]:17 -> [[@LINE]]:19
+  [self setP1: x];   // CHECK2: rename [[@LINE]]:9 -> [[@LINE]]:14
+  x = [other p2];    // CHECK3: rename [[@LINE]]:14 -> [[@LINE]]:16
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:3:7 -at=%s:19:15 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:4:8 -at=%s:16:8 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:5:7 -at=%s:18:19 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
diff --git a/test/Refactor/Rename/ObjCMethod.m b/test/Refactor/Rename/ObjCMethod.m
new file mode 100644
index 0000000..d2b1ad3
--- /dev/null
+++ b/test/Refactor/Rename/ObjCMethod.m
@@ -0,0 +1,150 @@
+@interface Test
+
+- (void)foo; // CHECK1: rename [[@LINE]]:9 -> [[@LINE]]:12
+- (int)performAction:(int)action with:(int)value; // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:21, [[@LINE]]:34 -> [[@LINE]]:38
+
+@end
+
+@implementation Test
+
+- (void)foo { // CHECK1: rename [[@LINE]]:9 -> [[@LINE]]:12
+}
+
+- (int)performAction:(int)action with:(int)value { // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:21, [[@LINE]]:34 -> [[@LINE]]:38
+    return action + value;
+}
+
++ (void)foo:(Test*)t {      // CHECK1-NOT: rename [[@LINE]]
+    [t foo];                // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:11
+    SEL s = @selector(foo);
+    [Test foo:t];           // CHECK1-NOT: rename [[@LINE]]
+    [t performAction: 2 with: 4]; // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:21, [[@LINE]]:25 -> [[@LINE]]:29
+    SEL s1 = @selector(foo:);
+    SEL s2 = @selector(performAction:
+                       with:);
+    SEL s3 = @selector(performAction:);
+    SEL s4 = @selector(performAction);
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:3:9 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:10:9 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:18:8 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:4:8 -new-name=doSomething:to %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:13:8 -new-name=doSomething:to: %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:21:8 -new-name=doSomething:to: %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK2 %s
+
+
+
+
+@interface SuperClass
+
+- (void)foo; // CHECK-OVERRIDEFOO: rename [[@LINE]]:9 -> [[@LINE]]:12
+- (int)compareTo:(SuperClass *)other with:(int)options; // CHECK-OVERRIDECOMP: rename [[@LINE]]:8 -> [[@LINE]]:17, [[@LINE]]:38 -> [[@LINE]]:42
+
+@end
+
+@implementation SuperClass
+
+- (void)foo { // CHECK-OVERRIDEFOO: rename [[@LINE]]:9 -> [[@LINE]]:12
+  return;
+}
+
+- (int)compareTo:(SuperClass *)other with:(int)options { // CHECK-OVERRIDECOMP: rename [[@LINE]]:8 -> [[@LINE]]:17, [[@LINE]]:38 -> [[@LINE]]:42
+  return 0;
+}
+
+@end
+
+@interface SubClass : SuperClass
+
+- (void)foo; // CHECK-OVERRIDEFOO: rename [[@LINE]]:9 -> [[@LINE]]:12
+
+@end
+
+@implementation SubClass
+
+- (void)foo { // CHECK-OVERRIDEFOO: rename [[@LINE]]:9 -> [[@LINE]]:12
+  [super foo]; // CHECK-OVERRIDEFOO: rename [[@LINE]]:10 -> [[@LINE]]:13
+}
+
+@end
+
+@interface SubClassTheSecond : SubClass
+
+- (void)foo; // CHECK-OVERRIDEFOO: rename [[@LINE]]:9 -> [[@LINE]]:12
+- (int)compareTo:(SuperClass *)other with:(int)options; // CHECK-OVERRIDECOMP: rename [[@LINE]]:8 -> [[@LINE]]:17, [[@LINE]]:38 -> [[@LINE]]:42
+
+@end
+
+@implementation SubClassTheSecond
+
+- (void)foo { // CHECK-OVERRIDEFOO: rename [[@LINE]]:9 -> [[@LINE]]:12
+  return;
+}
+- (int)compareTo:(SuperClass *)other // CHECK-OVERRIDECOMP: rename [[@LINE]]:8 -> [[@LINE]]:17, [[@LINE+1]]:8 -> [[@LINE+1]]:12
+       with:(int)options {
+  [other foo]; // CHECK-OVERRIDEFOO: rename [[@LINE]]:10 -> [[@LINE]]:13
+  return [super compareTo: other with: options]; // CHECK-OVERRIDECOMP: rename [[@LINE]]:17 -> [[@LINE]]:26, [[@LINE]]:34 -> [[@LINE]]:38
+}
+
+@end
+
+@interface UnrelatedClass
+
+- (void)foo; // CHECK-OVERRIDEFOO-NOT: rename [[@LINE]]
+
+@end
+
+@interface UnrelatedSubClass : UnrelatedClass
+// This method doesn't override SuperClass.foo, so verify that this occurrence
+// isn't renamed even though its selector is the same.
+- (void)foo; // CHECK-OVERRIDEFOO-NOT: rename [[@LINE]]
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:44:9 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDEFOO %s
+// RUN: clang-refactor-test rename-initiate -at=%s:51:9 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDEFOO %s
+// RUN: clang-refactor-test rename-initiate -at=%s:63:9 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDEFOO %s
+// RUN: clang-refactor-test rename-initiate -at=%s:69:9 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDEFOO %s
+// RUN: clang-refactor-test rename-initiate -at=%s:70:10 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDEFOO %s
+// RUN: clang-refactor-test rename-initiate -at=%s:77:9 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDEFOO %s
+// RUN: clang-refactor-test rename-initiate -at=%s:84:9 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDEFOO %s
+// RUN: clang-refactor-test rename-initiate -at=%s:89:10 -new-name=bar %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDEFOO %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:45:8 -new-name=a:b: %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDECOMP %s
+// RUN: clang-refactor-test rename-initiate -at=%s:55:8 -new-name=a:b: %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDECOMP %s
+// RUN: clang-refactor-test rename-initiate -at=%s:78:8 -new-name=a:b %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDECOMP %s
+// RUN: clang-refactor-test rename-initiate -at=%s:87:9 -new-name=a:b: %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDECOMP %s
+// RUN: clang-refactor-test rename-initiate -at=%s:90:17 -new-name=a:b %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDECOMP %s
+// RUN: clang-refactor-test rename-initiate -at=%s:90:34 -new-name=a:b %s -Wno-objc-root-class | FileCheck --check-prefix=CHECK-OVERRIDECOMP %s
+
+// Don't allow implicit parameters:
+@interface Foo
+- (void)foo;
+@end
+
+@implementation Foo
+- (void)foo {
+  self = 0;
+}
+@end
+// RUN: not clang-refactor-test rename-initiate -at=%s:130:3 -new-name=foo %s -Wno-objc-root-class 2>&1 | FileCheck --check-prefix=CHECK-NORENAME %s
+// CHECK-NORENAME: could not rename symbol at the given location
+
+@interface EmptySelectorsRule_Psych
+
+- (void):(int)_ :(int) m:(int)z; // EMPTY-SELECTOR: rename [[@LINE]]:9 -> [[@LINE]]:9, [[@LINE]]:17 -> [[@LINE]]:17, [[@LINE]]:25 -> [[@LINE]]:25
+
+@end
+
+@implementation EmptySelectorsRule_Psych
+
+- (void) :(int)_ :(int)m :(int)z { // EMPTY-SELECTOR: rename [[@LINE]]:10 -> [[@LINE]]:10, [[@LINE]]:18 -> [[@LINE]]:18, [[@LINE]]:26 -> [[@LINE]]:26
+    [self: 15:0 :3]; // EMPTY-SELECTOR: rename [[@LINE]]:10 -> [[@LINE]]:10, [[@LINE]]:14 -> [[@LINE]]:14, [[@LINE]]:17 -> [[@LINE]]:17
+}
+// RUN: clang-refactor-test rename-initiate -at=%s:139:9 -new-name=test:a:: %s -Wno-objc-root-class | FileCheck --check-prefix=EMPTY-SELECTOR %s
+
+@end
diff --git a/test/Refactor/Rename/ObjCMethodMacro.m b/test/Refactor/Rename/ObjCMethodMacro.m
new file mode 100644
index 0000000..c6d6322
--- /dev/null
+++ b/test/Refactor/Rename/ObjCMethodMacro.m
@@ -0,0 +1,28 @@
+#define FOO foo // CHECK1-NOT: rename [[@LINE]]
+// CHECK1-NOT: macro [[@LINE-1]]
+
+@interface I
+
+- (void)FOO; // CHECK1: macro [[@LINE]]:9 -> [[@LINE]]:9
+- (void)foo: (int)x FOO: (int)y; // CHECK2: macro [[@LINE]]:21 -> [[@LINE]]:21
+
+@end
+
+@implementation I
+
+- (void)foo { // CHECK1-NEXT: rename [[@LINE]]:9 -> [[@LINE]]:12
+  [self FOO: 1 FOO: 2]; // CHECK2-NEXT: macro [[@LINE]]:9 -> [[@LINE]]:9
+}
+
+- (void)foo: (int)x foo: (int)y { // CHECK2-NEXT: rename [[@LINE]]:9 -> [[@LINE]]:12, [[@LINE]]:21 -> [[@LINE]]:24
+  [self FOO]; // CHECK1-NEXT: macro [[@LINE]]:9 -> [[@LINE]]:9
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:13:9 -new-name=bar %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:17:9 -new-name=foo:bar %s | FileCheck --check-prefix=CHECK2 %s
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:1:13 -new-name=foo %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:6:9 -new-name=Bar %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+// CHECK-ERROR: could not rename symbol at the given location
diff --git a/test/Refactor/Rename/ObjCProperty.m b/test/Refactor/Rename/ObjCProperty.m
new file mode 100644
index 0000000..f0ed852
--- /dev/null
+++ b/test/Refactor/Rename/ObjCProperty.m
@@ -0,0 +1,303 @@
+// XFAIL: *
+// TODO: Remove or cut it down to one symbol rename.
+
+@interface I1
+
+@property int p1; // CHECK1: rename [[@LINE]]:15 -> [[@LINE]]:17
+@property (readwrite, nonatomic) int p2; // CHECK2: rename [[@LINE]]:38 -> [[@LINE]]:40
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:3:15 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:4:38 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+@implementation I1
+
+- (void)foo:(I1 *)other {
+  self.p2 =          // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:10
+            self.p1; // CHECK1: rename [[@LINE]]:18 -> [[@LINE]]:20
+  (void)other.p1;    // CHECK1: rename [[@LINE]]:15 -> [[@LINE]]:17
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:14:8 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:15:18 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:16:15 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+@implementation I1 (gettersAndSetters)
+
+- (void)foo2:(I1 *)other {
+  int x = [self p1]; // CHECK1: rename [[@LINE]]:17 -> [[@LINE]]:19
+  [self setP1: x];   // CHECK1: rename "setFoo" [[@LINE]]:9 -> [[@LINE]]:14
+  [other setP2:      // CHECK2: rename "setFoo" [[@LINE]]:10 -> [[@LINE]]:15
+    [other p2]];     // CHECK2: rename [[@LINE]]:12 -> [[@LINE]]:14
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:28:17 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:29:9 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:30:10 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:31:12 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+@interface I2
+
+@property int noImplementation; // CHECK3: rename [[@LINE]]:15 -> [[@LINE]]:31
+
+@end
+
+void noImplementationGetterSetters(I2 *object) {
+  object.noImplementation = 2;     // CHECK3: rename [[@LINE]]:10 -> [[@LINE]]:26
+  int x = object.noImplementation; // CHECK3: rename [[@LINE]]:18 -> [[@LINE]]:34
+  [object setNoImplementation: x]; // CHECK3: rename "setFoo" [[@LINE]]:11 -> [[@LINE]]:30
+  (void)[object noImplementation]; // CHECK3: rename [[@LINE]]:17 -> [[@LINE]]:33
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:43:15 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:48:10 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:49:18 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:50:11 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:51:17 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+
+@interface I3
+
+@property (readonly) int noSetter; // CHECK4: rename [[@LINE]]:26 -> [[@LINE]]:34
+
+@end
+
+void noPropertySetter(I3 *object) {
+  (void)object.noSetter;   // CHECK4: rename [[@LINE]]:16 -> [[@LINE]]:24
+  object.noSetter = 2;     // CHECK4-NOT: rename [[@LINE]]
+  (void)[object noSetter]; // CHECK4: rename [[@LINE]]:17 -> [[@LINE]]:25
+  [object setNoSetter: 2]; // CHECK4-NOT: rename "setFoo" [[@LINE]]
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:62:26 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:67:16 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:69:17 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+
+@interface PropertyOverrides1: I1
+
+- (int)p1; // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+- (void)setP1:(int)x; // CHECK1: rename "setFoo" [[@LINE]]:9 -> [[@LINE]]:14
+- (int)p2; // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:10
+
+@end
+
+@implementation PropertyOverrides1 {
+  I1 *object;
+}
+
+- (int)p1 {            // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return [super p1];   // CHECK1: rename [[@LINE]]:17 -> [[@LINE]]:19
+}
+- (void)setP1:(int)x { // CHECK1: rename "setFoo" [[@LINE]]:9 -> [[@LINE]]:14
+  [object setP1: x];   // CHECK1: rename "setFoo" [[@LINE]]:11 -> [[@LINE]]:16
+  [super setP1: x];    // CHECK1: rename "setFoo" [[@LINE]]:10 -> [[@LINE]]:15
+}
+- (int)p2 {            // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return super.p2;     // CHECK2: rename [[@LINE]]:16 -> [[@LINE]]:18
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:79:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:80:9 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:89:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:90:17 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:92:9 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:93:11 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:94:10 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:81:8 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:96:8 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:97:16 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+@interface PropertyOverrides2: I3
+
+- (int)noSetter; // CHECK4: rename [[@LINE]]:8 -> [[@LINE]]:16
+- (void)setNoSetter:(int)x; // CHECK4-NOT: rename "setFoo" [[@LINE]]
+
+@end
+
+void getterOnlyOverrideWithoutImplementation(PropertyOverrides2 *object) {
+  (void)object.noSetter;     // CHECK4: rename [[@LINE]]:16 -> [[@LINE]]:24
+  int _ = [object noSetter]; // CHECK4: rename [[@LINE]]:19 -> [[@LINE]]:27
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:115:8 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:121:16 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:122:19 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+
+@interface MismatchedPropertyOverrides: I1
+
+- (void)p1; // CHECK1: rename [[@LINE]]:9 -> [[@LINE]]:11
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:131:9 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+@interface ExplicitlyNamedGetterSetters1
+
+@property (getter=getP3) int p3; // CHECK5: rename [[@LINE]]:30 -> [[@LINE]]:32
+                                 // CHECK5GET: rename [[@LINE-1]]:19 -> [[@LINE-1]]:24
+@property (getter=a, setter=b:) int p4; // CHECK6: rename [[@LINE]]:37 -> [[@LINE]]:39
+                                        // CHECK6GET: rename [[@LINE-1]]:19 -> [[@LINE-1]]:20
+                                        // CHECK6SET: rename [[@LINE-2]]:29 -> [[@LINE-2]]:30
+@property (readonly, getter=local) bool isLocal; // CHECK7: rename [[@LINE]]:41 -> [[@LINE]]:48
+                                                 // CHECK7GET: rename [[@LINE-1]]:29 -> [[@LINE-1]]:34
+@end
+
+@implementation ExplicitlyNamedGetterSetters1
+
+- (void)foo:(ExplicitlyNamedGetterSetters *)other {
+  self.p3 = 2; // CHECK5: rename [[@LINE]]:8 -> [[@LINE]]:10
+  [self p3];   // CHECK5-NOT: rename [[@LINE]]
+  [self setP3: // CHECK5: rename "setFoo" [[@LINE]]:9 -> [[@LINE]]:14
+    [other getP3]]; // CHECK5-NOT: rename [[@LINE]]
+                    // CHECK5GET: rename [[@LINE-1]]:12 -> [[@LINE-1]]:17
+
+  self.p4 = 3; // CHECK6: rename [[@LINE]]:8 -> [[@LINE]]:10
+  [self p4];   // CHECK6-NOT: rename [[@LINE]]
+  [self setP4: 2]; // CHECK6-NOT: rename "setFoo" [[@LINE]]
+  [self b:         // CHECK6-NOT: rename "setFoo" [[@LINE]]
+                   // CHECK6SET: rename [[@LINE-1]]:9 -> [[@LINE-1]]:10
+    [other a]];    // CHECK6-NOT: rename [[@LINE]]
+                   // CHECK6GET: rename [[@LINE-1]]:12 -> [[@LINE-1]]:13
+
+  (void)self.isLocal; // CHECK7: rename [[@LINE]]:14 -> [[@LINE]]:21
+  [self isLocal]; // CHECK7-NOT: rename [[@LINE]]
+  [other local];  // CHECK7-NOT: rename [[@LINE]]
+                  // CHECK7GET: rename [[@LINE-1]]:10 -> [[@LINE-1]]:15
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:139:30 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:151:8 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:153:9 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:141:37 -new-name=foo %s | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:157:8 -new-name=foo %s | FileCheck --check-prefix=CHECK6 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:144:41 -new-name=foo %s | FileCheck --check-prefix=CHECK7 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:165:14 -new-name=foo %s | FileCheck --check-prefix=CHECK7 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:139:19 -new-name=foo %s | FileCheck --check-prefix=CHECK5GET %s
+// RUN: clang-refactor-test rename-initiate -at=%s:154:12 -new-name=foo %s | FileCheck --check-prefix=CHECK5GET %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:141:19 -new-name=foo %s | FileCheck --check-prefix=CHECK6GET %s
+// RUN: clang-refactor-test rename-initiate -at=%s:162:12 -new-name=foo %s | FileCheck --check-prefix=CHECK6GET %s
+// RUN: clang-refactor-test rename-initiate -at=%s:141:29 -new-name=foo %s | FileCheck --check-prefix=CHECK6SET %s
+// RUN: clang-refactor-test rename-initiate -at=%s:160:9 -new-name=foo %s | FileCheck --check-prefix=CHECK6SET %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:144:29 -new-name=foo %s | FileCheck --check-prefix=CHECK7GET %s
+// RUN: clang-refactor-test rename-initiate -at=%s:167:10 -new-name=foo %s | FileCheck --check-prefix=CHECK7GET %s
+
+void ivars1(I1 *object) {
+  object->_p1 = 2; // CHECK1: rename "_foo" [[@LINE]]:11 -> [[@LINE]]:14
+  object->_p2 =    // CHECK2: rename "_foo" [[@LINE]]:11 -> [[@LINE]]:14
+                object->_p1;  // CHECK1: rename "_foo" [[@LINE]]:25 -> [[@LINE]]:28
+}
+
+void ivars2(ExplicitlyNamedGetterSetters1 *object) {
+  object->_p3 = // CHECK5: rename "_foo" [[@LINE]]:11 -> [[@LINE]]:14
+                object->_p4; // CHECK6: rename "_foo" [[@LINE]]:25 -> [[@LINE]]:28
+  object->_isLocal = 0; // CHECK7: rename "_foo" [[@LINE]]:11 -> [[@LINE]]:19
+}
+
+void ivarsNoImplementation(I2 *object) {
+  object->_noImplementation = 4; // CHECK2-NOT: rename "_foo" [[@LINE]]
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:195:11 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:197:25 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:196:11 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:201:11 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:202:25 -new-name=foo %s | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:203:11 -new-name=foo %s | FileCheck --check-prefix=CHECK7 %s
+
+@interface ExplicitIVars
+
+@property int p5; // CHECK8: rename [[@LINE]]:15 -> [[@LINE]]:17
+@property(readonly) int p6; // CHECK9: rename [[@LINE]]:25 -> [[@LINE]]:27
+
+@end
+
+@implementation ExplicitIVars {
+  int _p5; // CHECK8: rename "_foo" [[@LINE]]:7 -> [[@LINE]]:10
+  int _p6; // CHECK9: rename "_foo" [[@LINE]]:7 -> [[@LINE]]:10
+}
+
+- (void)foo:(ExplicitIVars *)other {
+  _p5 =              // CHECK8: rename "_foo" [[@LINE]]:3 -> [[@LINE]]:6
+        other->_p6;  // CHECK9: rename "_foo" [[@LINE]]:16 -> [[@LINE]]:19
+  other->_p6 =       // CHECK9: rename "_foo" [[@LINE]]:10 -> [[@LINE]]:13
+               _p5;  // CHECK8: rename "_foo" [[@LINE]]:16 -> [[@LINE]]:19
+  self.p5 =          // CHECK8: rename [[@LINE]]:8 -> [[@LINE]]:10
+           other.p6; // CHECK9: rename [[@LINE]]:18 -> [[@LINE]]:20
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:220:15 -new-name=foo %s | FileCheck --check-prefix=CHECK8 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:226:7 -new-name=foo %s | FileCheck --check-prefix=CHECK8 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:231:3 -new-name=foo %s | FileCheck --check-prefix=CHECK8 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:234:16 -new-name=foo %s | FileCheck --check-prefix=CHECK8 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:235:8 -new-name=foo %s | FileCheck --check-prefix=CHECK8 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:221:25 -new-name=foo %s | FileCheck --check-prefix=CHECK9 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:227:7 -new-name=foo %s | FileCheck --check-prefix=CHECK9 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:232:16 -new-name=foo %s | FileCheck --check-prefix=CHECK9 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:233:10 -new-name=foo %s | FileCheck --check-prefix=CHECK9 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:236:18 -new-name=foo %s | FileCheck --check-prefix=CHECK9 %s
+
+@interface ExplicitIVarsInInterface {
+  int _p7; // CHECK10: rename "_foo" [[@LINE]]:7 -> [[@LINE]]:10
+  @public
+  int _p8; // CHECK11: rename "_foo" [[@LINE]]:7 -> [[@LINE]]:10
+}
+
+@property int p7; // CHECK10: rename [[@LINE]]:15 -> [[@LINE]]:17
+@property int p8; // CHECK11: rename [[@LINE]]:15 -> [[@LINE]]:17
+
+@end
+
+@implementation ExplicitIVarsInInterface
+@end
+
+void explicitIVarsInInterface(ExplicitIVarsInInterface* object) {
+  object->_p7 = // CHECK10: rename "_foo" [[@LINE]]:11 -> [[@LINE]]:14
+                object->_p8; // CHECK11: rename "_foo" [[@LINE]]:25 -> [[@LINE]]:28
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:254:7 -new-name=foo %s | FileCheck --check-prefix=CHECK10 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:259:15 -new-name=foo %s | FileCheck --check-prefix=CHECK10 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:268:11 -new-name=foo %s | FileCheck --check-prefix=CHECK10 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:256:7 -new-name=foo %s | FileCheck --check-prefix=CHECK11 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:260:15 -new-name=foo %s | FileCheck --check-prefix=CHECK11 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:269:25 -new-name=foo %s | FileCheck --check-prefix=CHECK11 %s
+
+@interface GetterSetterDefinedInInterfaceOnly
+
+@property int p9; // CHECK12: rename [[@LINE]]:15 -> [[@LINE]]:17
+
+@end
+
+@implementation GetterSetterDefinedInInterfaceOnly
+
+- (int)p9 { return 0; }  // CHECK12: rename [[@LINE]]:8 -> [[@LINE]]:10
+- (void)setP9:(int)x { } // CHECK12: rename "setFoo" [[@LINE]]:9 -> [[@LINE]]:14
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:288:8 -new-name=foo %s | FileCheck --check-prefix=CHECK12 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:289:9 -new-name=foo %s | FileCheck --check-prefix=CHECK12 %s
+
+void matchingGetterSetterSelector() {
+  @selector(p1);     // CHECK1: selector [[@LINE]]:13 -> [[@LINE]]:15
+  @selector(setP1:); // CHECK1: selector "setFoo" [[@LINE]]:13 -> [[@LINE]]:18
+  @selector(setP1);  // CHECK1-NOT: selector "setFoo" [[@LINE]]
+}
diff --git a/test/Refactor/Rename/ObjCPropertyDynamic.m b/test/Refactor/Rename/ObjCPropertyDynamic.m
new file mode 100644
index 0000000..8ac7aac
--- /dev/null
+++ b/test/Refactor/Rename/ObjCPropertyDynamic.m
@@ -0,0 +1,41 @@
+@interface DynamicProperty
+
+@property int p1; // CHECK1: rename [[@LINE]]:15 -> [[@LINE]]:17
+@property(readonly) int p2; // CHECK2: rename [[@LINE]]:25 -> [[@LINE]]:27
+
+@end
+
+@implementation DynamicProperty
+
+@dynamic p1; // CHECK1: rename [[@LINE]]:10 -> [[@LINE]]:12
+
+@dynamic p2; // CHECK2: rename [[@LINE]]:10 -> [[@LINE]]:12
+
+- (int)p1 { // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return 1;
+}
+// TODO: Remove
+- (void)setP1:(int)x { // CHECK1: rename [[@LINE]]:9 -> [[@LINE]]:14
+}
+
+- (int)p2 { // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return 2;
+}
+
+- (void)foo:(DynamicProperty *)other {
+  self.p1 = // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+            other.p2; // CHECK2: rename [[@LINE]]:19 -> [[@LINE]]:21
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:3:15 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:10:10 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:14:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:18:9 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:26:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:4:25 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:12:10 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:21:8 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:27:19 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Rename/ObjCPropertyIVarInInterfaceWithoutImplementation.m b/test/Refactor/Rename/ObjCPropertyIVarInInterfaceWithoutImplementation.m
new file mode 100644
index 0000000..fda9e82
--- /dev/null
+++ b/test/Refactor/Rename/ObjCPropertyIVarInInterfaceWithoutImplementation.m
@@ -0,0 +1,28 @@
+@interface ExplicitIVarsInInterface {
+  int _p1; // CHECK1: rename "_foo" [[@LINE]]:7 -> [[@LINE]]:10
+  @public
+  int _p2; // CHECK2: rename "_foo" [[@LINE]]:7 -> [[@LINE]]:10
+}
+
+@property int p1; // CHECK1: rename [[@LINE]]:15 -> [[@LINE]]:17
+@property int p2; // CHECK2: rename [[@LINE]]:15 -> [[@LINE]]:17
+
+@end
+
+void explicitIVarsInInterface(ExplicitIVarsInInterface* object) {
+  object->_p7 = // CHECK1: rename "_foo" [[@LINE]]:11 -> [[@LINE]]:14
+                object->_p8; // CHECK2: rename "_foo" [[@LINE]]:25 -> [[@LINE]]:28
+}
+
+// XFAIL: *
+// This test is currently disabled as renaming can't initiate a property
+// renaming operation in a TU without @implementation.
+// rdar://29329980
+
+// RUN: clang-refactor-test rename-initiate -at=%s:2:7 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:7:15 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:13:11 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:4:7 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:8:15 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:14:25 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Rename/ObjCPropertyInCategory.m b/test/Refactor/Rename/ObjCPropertyInCategory.m
new file mode 100644
index 0000000..9c8bc79
--- /dev/null
+++ b/test/Refactor/Rename/ObjCPropertyInCategory.m
@@ -0,0 +1,45 @@
+@interface I1
+
+@end
+
+@interface I1 (Category)
+
+@property int p1; // CHECK1: rename [[@LINE]]:15 -> [[@LINE]]:17
+@property(readonly) int p2; // CHECK2: rename [[@LINE]]:25 -> [[@LINE]]:27
+
+- (int)p1; // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+
+@end
+
+@implementation I1 (Category)
+
+@dynamic p2; // CHECK2: rename [[@LINE]]:10 -> [[@LINE]]:12
+
+- (int)p1 { // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return 1;
+}
+// TODO: Remove
+- (void)setP1:(int)x { // CHECK1: rename [[@LINE]]:9 -> [[@LINE]]:14
+}
+
+- (int)p2 { // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:10
+  return 2;
+}
+
+- (void)foo:(I1 *)other {
+  self.p1 = // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+            other.p2; // CHECK2: rename [[@LINE]]:19 -> [[@LINE]]:21
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:7:15 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:10:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:18:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:22:9 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:30:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:8:25 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:16:10 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:25:8 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:31:19 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
diff --git a/test/Refactor/Rename/ObjCPropertyMacro.m b/test/Refactor/Rename/ObjCPropertyMacro.m
new file mode 100644
index 0000000..9d3ffa3
--- /dev/null
+++ b/test/Refactor/Rename/ObjCPropertyMacro.m
@@ -0,0 +1,21 @@
+#define IMPLICIT implicit
+#define SETIMPLICIT setImplicit
+
+@interface I
+
+- (int)IMPLICIT;
+- (void)setImplicit:(int)x; // CHECK1: rename  [[@LINE]]
+
+@end
+
+@implementation I
+
+- (void)foo {
+  self.implicit; // CHECK1-NEXT: implicit-property [[@LINE]]
+  self.IMPLICIT; // CHECK1-NEXT: implicit-property in macro [[@LINE]]
+  self.IMPLICIT = 2; // CHECK1-NEXT: implicit-property in macro [[@LINE]]
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:7:9 -new-name=bar %s | FileCheck --check-prefix=CHECK1 %s
diff --git a/test/Refactor/Rename/ObjCPropertySynthesize.m b/test/Refactor/Rename/ObjCPropertySynthesize.m
new file mode 100644
index 0000000..2b12b6f
--- /dev/null
+++ b/test/Refactor/Rename/ObjCPropertySynthesize.m
@@ -0,0 +1,112 @@
+// XFAIL: *
+// TODO: Remove or cut it down to one symbol rename.
+
+@interface SynthesizedIVars
+
+@property int p1; // CHECK1: rename [[@LINE]]:15 -> [[@LINE]]:17
+@property(readonly) int p2; // CHECK2PROP: rename [[@LINE]]:25 -> [[@LINE]]:27
+
+@end
+
+@implementation SynthesizedIVars
+
+@synthesize p1 = _p1; // CHECK1: rename [[@LINE]]:13 -> [[@LINE]]:15
+                      // CHECK1: rename "_foo" [[@LINE-1]]:18 -> [[@LINE-1]]:21
+
+// The rename of ivar 'p2_' shouldn't initiate the rename of property 'p2'
+// because it doesn't follow the default naming convention.
+@synthesize p2 = p2_; // CHECK2PROP: rename [[@LINE]]:13 -> [[@LINE]]:15
+                      // CHECK2IVAR: rename [[@LINE-1]]:18 -> [[@LINE-1]]:21
+
+- (void)foo:(SynthesizedIVars *)other {
+  _p1 =              // CHECK1: rename "_foo" [[@LINE]]:3 -> [[@LINE]]:6
+        other->p2_;  // CHECK2IVAR: rename [[@LINE]]:16 -> [[@LINE]]:19
+  other->p2_ =       // CHECK2IVAR: rename [[@LINE]]:10 -> [[@LINE]]:13
+               _p1;  // CHECK1: rename "_foo" [[@LINE]]:16 -> [[@LINE]]:19
+  self.p1 =          // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+           other.p2; // CHECK2PROP: rename [[@LINE]]:18 -> [[@LINE]]:20
+}
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:3:15 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:10:13 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:10:18 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:19:3 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:22:16 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:23:8 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:4:25 -new-name=foo %s | FileCheck --check-prefix=CHECK2PROP %s
+// RUN: clang-refactor-test rename-initiate -at=%s:15:13 -new-name=foo %s | FileCheck --check-prefix=CHECK2PROP %s
+// RUN: clang-refactor-test rename-initiate -at=%s:24:18 -new-name=foo %s | FileCheck --check-prefix=CHECK2PROP %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:15:18 -new-name=foo %s | FileCheck --check-prefix=CHECK2IVAR %s
+// RUN: clang-refactor-test rename-initiate -at=%s:20:16 -new-name=foo %s | FileCheck --check-prefix=CHECK2IVAR %s
+// RUN: clang-refactor-test rename-initiate -at=%s:21:10 -new-name=foo %s | FileCheck --check-prefix=CHECK2IVAR %s
+
+@interface SynthesizedExplicitIVars {
+  int _p3; // CHECK3: rename "_foo" [[@LINE]]:7 -> [[@LINE]]:10
+}
+
+@property int p3; // CHECK3: rename [[@LINE]]:15 -> [[@LINE]]:17
+@property int p4; // CHECK4: rename [[@LINE]]:15 -> [[@LINE]]:17
+
+@end
+
+@implementation SynthesizedExplicitIVars {
+  int _p4; // CHECK4: rename "_foo" [[@LINE]]:7 -> [[@LINE]]:10
+}
+
+@synthesize p3 = _p3; // CHECK3: rename [[@LINE]]:13 -> [[@LINE]]:15
+                      // CHECK3: rename "_foo" [[@LINE-1]]:18 -> [[@LINE-1]]:21
+@synthesize p4 = _p4; // CHECK4: rename [[@LINE]]:13 -> [[@LINE]]:15
+                      // CHECK4: rename "_foo" [[@LINE-1]]:18 -> [[@LINE-1]]:21
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:45:7 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:48:15 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:57:13 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:57:18 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:49:15 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:54:7 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:59:13 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:59:18 -new-name=foo %s | FileCheck --check-prefix=CHECK4 %s
+
+@interface SynthesizedWithoutIVarName
+
+@property int p5; // CHECK5: rename [[@LINE]]:15 -> [[@LINE]]:17
+
+@end
+
+@implementation SynthesizedWithoutIVarName {
+  int _p5; // CHECK5-NOT: rename "" [[@LINE]]
+           // CHECK5-NOT: rename [[@LINE-1]]
+  int p5;  // CHECK5: rename [[@LINE]]:7 -> [[@LINE]]:9
+}
+
+@synthesize p5; // CHECK5: rename [[@LINE]]:13 -> [[@LINE]]:15
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:76:15 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:83:7 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:86:13 -new-name=foo %s | FileCheck --check-prefix=CHECK5 %s
+
+@interface A
+@property int p6;
+@end
+
+@interface C : A
+@end
+
+@implementation C
+
+@synthesize p6;
+// CHECK6: Renaming 4 symbols
+// CHECK6-NEXT: 'c:objc(cs)A(py)p6'
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:103:13 -new-name=foo -dump-symbols %s | FileCheck --check-prefix=CHECK6 %s
diff --git a/test/Refactor/Rename/ObjCProtocol.m b/test/Refactor/Rename/ObjCProtocol.m
new file mode 100644
index 0000000..661d83b
--- /dev/null
+++ b/test/Refactor/Rename/ObjCProtocol.m
@@ -0,0 +1,67 @@
+@protocol P1, // CHECK1: rename [[@LINE]]:11 -> [[@LINE]]:13
+          P2; // CHECK2: rename [[@LINE]]:11 -> [[@LINE]]:13
+
+@protocol P1 // CHECK1: rename [[@LINE]]:11 -> [[@LINE]]:13
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:1:11 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:4:11 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:2:11 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+void protocolExpressions(id foo) {
+  (void)@protocol(P1);    // CHECK1: rename [[@LINE]]:19 -> [[@LINE]]:21
+  [foo p: @protocol(P2)]; // CHECK2: rename [[@LINE]]:21 -> [[@LINE]]:23
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:12:19 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:13:21 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+void qualifiedId(id<P1> foo) { // CHECK1: rename [[@LINE]]:21 -> [[@LINE]]:23
+  id<P2, P1> bar = // CHECK2: rename [[@LINE]]:6 -> [[@LINE]]:8
+                   // CHECK1: rename [[@LINE-1]]:10 -> [[@LINE-1]]:12
+                   (id<P1, P2, P1>)foo; // CHECK1: rename [[@LINE]]:24 -> [[@LINE]]:26
+                                        // CHECK2: rename [[@LINE-1]]:28 -> [[@LINE-1]]:30
+                                        // CHECK1: rename [[@LINE-2]]:32 -> [[@LINE-2]]:34
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:19:21 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:20:6 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:20:10 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:22:24 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:22:28 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:22:32 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+typedef id<P1> TypedefQualifiedID; // CHECK1: rename [[@LINE]]:12 -> [[@LINE]]:14
+
+// RUN: clang-refactor-test rename-initiate -at=%s:34:12 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+
+@interface I1<P1> // CHECK1: rename [[@LINE]]:15 -> [[@LINE]]:17
+@end
+
+@protocol P3 < P1> // CHECK3: rename [[@LINE]]:11 -> [[@LINE]]:13
+                   // CHECK1: rename [[@LINE-1]]:16 -> [[@LINE-1]]:18
+@end
+
+@interface I1 (Cat) <P2, P3> // CHECK2: rename [[@LINE]]:22 -> [[@LINE]]:24
+@end                         // CHECK3: rename [[@LINE-1]]:26 -> [[@LINE-1]]:28
+
+// RUN: clang-refactor-test rename-initiate -at=%s:38:15 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:41:16 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:45:22 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:41:11 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:45:26 -new-name=foo %s | FileCheck --check-prefix=CHECK3 %s
+
+typedef I1<P1, P2> * TypedefI1; // CHECK1: rename [[@LINE]]:12 -> [[@LINE]]:14
+                                // CHECK2: rename [[@LINE-1]]:16 -> [[@LINE-1]]:18
+
+void qualifiedClassPointer(I1<P1> *x) { // CHECK1: rename [[@LINE]]:31 -> [[@LINE]]:33
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:54:12 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:57:31 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:54:16 -new-name=foo %s | FileCheck --check-prefix=CHECK2 %s
+
+void protocolTypeof(typeof(@protocol(P1)) *bar) { // CHECK1: rename [[@LINE]]:38 -> [[@LINE]]:40
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:64:38 -new-name=foo %s | FileCheck --check-prefix=CHECK1 %s
diff --git a/test/Refactor/Rename/ProhibitedDeclarations.cpp b/test/Refactor/Rename/ProhibitedDeclarations.cpp
new file mode 100644
index 0000000..b93f11d
--- /dev/null
+++ b/test/Refactor/Rename/ProhibitedDeclarations.cpp
@@ -0,0 +1,72 @@
+void dontRenameBuiltins(int x) {
+  __builtin_assume(x != 0);
+  __builtin_trap();
+}
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:2:3 -at=%s:3:3 -new-name=foo %s 2>&1 | FileCheck %s
+// CHECK: error: could not rename symbol at the given location
+
+// RUN: not clang-refactor-test list-actions -at=%s:2:3 %s 2>&1 | FileCheck --check-prefix=CHECK-BUILTIN %s
+// CHECK-BUILTIN: Failed to initiate 1 actions because:
+// CHECK-BUILTIN-NEXT: Rename: '__builtin_assume' is a builtin function that cannot be renamed
+// CHECK-BUILTIN-NEXT: No refactoring actions are available at the given location
+
+#include <system-header.h>
+
+void dontRenameSystemSymbols() {
+  systemFunction();
+}
+// RUN: not clang-refactor-test rename-initiate -at=%s:17:3 -new-name=foo %s -isystem %S/Inputs 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYSTEM %s
+// CHECK-SYSTEM: 'systemFunction' cannot be renamed because it is declared in a system header
+
+struct External {
+  static void foo();
+} __attribute__((external_source_symbol(language="Swift")));
+
+void dontRenameExternalSourceSymbols() {
+  External::foo();
+}
+// RUN: not clang-refactor-test rename-initiate -at=%s:27:3 -new-name=foo %s 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-EXTERNAL1 %s
+// CHECK-EXTERNAL1: 'External' is declared in a Swift file; rename can be initiated in a Swift file only
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:27:13 -new-name=foo %s 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-EXTERNAL2 %s
+// CHECK-EXTERNAL2: 'foo' is declared in a Swift file; rename can be initiated in a Swift file only
+
+// Ensure that operators can't be renamed:
+struct Stream {
+};
+
+Stream &operator <<(Stream &, int);
+
+void renameArgsNotOperator(Stream x) { // CHECK-OP-X: rename local [[@LINE]]:35 -> [[@LINE]]:36
+  int y = 0; // CHECK-OP-Y: rename local [[@LINE]]:7 -> [[@LINE]]:8
+  x << // CHECK-OP-X: rename local [[@LINE]]:3 -> [[@LINE]]:4
+  y << // CHECK-OP-Y: rename local [[@LINE]]:3 -> [[@LINE]]:4
+  y; // CHECK-OP-Y: rename local [[@LINE]]:3 -> [[@LINE]]:4
+}
+// RUN: clang-refactor-test rename-initiate -at=%s:43:3 -new-name=foo %s | FileCheck --check-prefixes=CHECK-OP-X %s
+// RUN: clang-refactor-test rename-initiate -at=%s:44:3 -at=%s:45:3 -new-name=foo %s | FileCheck --check-prefixes=CHECK-OP-Y %s
+
+struct SystemStruct;
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:50:8 -new-name=foo %s -isystem %S/Inputs 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYSTEM2 %s
+// CHECK-SYSTEM2: 'SystemStruct' cannot be renamed because it is declared in a system header
+
+typedef struct SystemStruct SystemTypedef;
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:55:29 -new-name=foo %s -isystem %S/Inputs 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYSTEM3 %s
+// CHECK-SYSTEM3: 'SystemTypedef' cannot be renamed because it is declared in a system header
+
+enum SystemEnum;
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:60:6 -new-name=foo %s -isystem %S/Inputs 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYSTEM4 %s
+// CHECK-SYSTEM4: 'SystemEnum' cannot be renamed because it is declared in a system header
+
+void systemFunction();
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:65:6 -new-name=foo %s -isystem %S/Inputs 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYSTEM %s
+
+int systemVariable;
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:69:5 -new-name=foo %s -isystem %S/Inputs 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYSTEM5 %s
+// CHECK-SYSTEM5: 'systemVariable' cannot be renamed because it is declared in a system header
diff --git a/test/Refactor/Rename/ProhibitedDeclarations.m b/test/Refactor/Rename/ProhibitedDeclarations.m
new file mode 100644
index 0000000..cb91a6b
--- /dev/null
+++ b/test/Refactor/Rename/ProhibitedDeclarations.m
@@ -0,0 +1,35 @@
+@protocol P1
+@end
+
+void dontRenameProtocol() {
+  Protocol *p = @protocol(P1);
+}
+// RUN: not clang-refactor-test rename-initiate -at=%s:5:3 -new-name=foo %s 2>&1 | FileCheck %s
+// CHECK: error: could not rename symbol at the given location
+
+#include <objc-system-header.h>
+
+@interface MyClass: MySystemClass
+
+- (void)someMethod:(int)x with:(int)y;
+
+@end
+
+@implementation MyClass
+
+- (void)someMethod:(int)x with:(int)y {
+}
+
+@end
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:14:9 -at=%s:20:9 -at=%s:28:9  -new-name=foo:bar %s -isystem %S/Inputs 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYSTEM %s
+// CHECK-SYSTEM: method 'someMethod:with:' cannot be renamed because it overrides a method declared in a system framework
+
+@interface MySubClass: MyClass
+@end
+@implementation MySubClass
+- (void)someMethod:(int)x with:(int)y {
+}
+@end
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:31:9  -new-name=foo:bar %s -isystem %S/Inputs 2>&1 | FileCheck --check-prefixes=CHECK,CHECK-SYSTEM %s
diff --git a/test/Refactor/Rename/TemplateClassInstantiation.cpp b/test/Refactor/Rename/TemplateClassInstantiation.cpp
new file mode 100644
index 0000000..48b7603
--- /dev/null
+++ b/test/Refactor/Rename/TemplateClassInstantiation.cpp
@@ -0,0 +1,39 @@
+template <typename T>
+class Foo { /* Test 1 */   // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+public:
+  T foo(T arg, T& ref, T* ptr) {
+    T value;
+    int number = 42;
+    value = (T)number;
+    value = static_cast<T>(number);
+    return value;
+  }
+  static void foo(T value) {}
+  T member;
+};
+
+template <typename T>
+void func() {
+  Foo<T> obj; /* Test 2 */  // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+  obj.member = T();
+  Foo<T>::foo();            // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+}
+
+int main() {
+  Foo<int> i; /* Test 3 */  // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+  i.member = 0;
+  Foo<int>::foo(0);         // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+
+  Foo<bool> b;              // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+  b.member = false;
+  Foo<bool>::foo(false);    // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+
+  return 0;
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:2:7 -new-name=Bar %s -fno-delayed-template-parsing | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:17:3 -new-name=Bar %s -fno-delayed-template-parsing | FileCheck %s
+// Test 3.
+// RUN: clang-refactor-test rename-initiate -at=%s:25:3 -new-name=Bar %s -fno-delayed-template-parsing | FileCheck %s
diff --git a/test/Refactor/Rename/TemplateParameters.cpp b/test/Refactor/Rename/TemplateParameters.cpp
new file mode 100644
index 0000000..2dbff69
--- /dev/null
+++ b/test/Refactor/Rename/TemplateParameters.cpp
@@ -0,0 +1,25 @@
+template <typename T, int x> // CHECK1: rename local [[@LINE]]:20 -> [[@LINE]]:21
+class Foo { // CHECK2: rename local [[@LINE-1]]:27 -> [[@LINE-1]]:28
+
+T func(); // CHECK1-NEXT: rename local [[@LINE]]:1 -> [[@LINE]]:2
+
+int array[x]; // CHECK2-NEXT: rename local [[@LINE]]:11 -> [[@LINE]]:12
+};
+
+// CHECK1-NOT: rename
+// CHECK2-NOT: rename
+
+// RUN: clang-refactor-test rename-initiate -at=%s:1:20 -new-name=U %s -fno-delayed-template-parsing | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:1:27 -new-name=U %s -fno-delayed-template-parsing | FileCheck --check-prefix=CHECK2 %s
+
+template<typename T, int x>
+T Foo<T, x>::func() { return T(); }
+
+template <template<typename> class H, typename S> // CHECK3: rename local [[@LINE]]:36 -> [[@LINE]]:37
+// CHECK4: rename local [[@LINE-1]]:48 -> [[@LINE-1]]:49
+void templateTemplateParam(const H<S> &value) { // CHECK3-NEXT: rename local [[@LINE]]:34 -> [[@LINE]]:35
+// CHECK4-NEXT: rename local [[@LINE-1]]:36 -> [[@LINE-1]]:37
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:18:36 -at=%s:20:34 -new-name=U %s -fno-delayed-template-parsing | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:18:48 -at=%s:20:36 -new-name=U %s -fno-delayed-template-parsing | FileCheck --check-prefix=CHECK4 %s
diff --git a/test/Refactor/Rename/TemplateTypename.cpp b/test/Refactor/Rename/TemplateTypename.cpp
new file mode 100644
index 0000000..da79f67
--- /dev/null
+++ b/test/Refactor/Rename/TemplateTypename.cpp
@@ -0,0 +1,24 @@
+template <typename T /* Test 1 */>              // CHECK: rename local [[@LINE]]:20 -> [[@LINE]]:21
+class Foo {
+T foo(T arg, T& ref, T* /* Test 2 */ ptr) {     // CHECK: rename local [[@LINE]]:1 -> [[@LINE]]:2
+                                                // CHECK: rename local [[@LINE-1]]:7 -> [[@LINE-1]]:8
+                                                // CHECK: rename local [[@LINE-2]]:14 -> [[@LINE-2]]:15
+                                                // CHECK: rename local [[@LINE-3]]:22 -> [[@LINE-3]]:23
+  T value;                                      // CHECK: rename local [[@LINE]]:3 -> [[@LINE]]:4
+  int number = 42;
+  value = (T)number;                            // CHECK: rename local [[@LINE]]:12 -> [[@LINE]]:13
+  value = static_cast<T /* Test 3 */>(number);  // CHECK: rename local [[@LINE]]:23 -> [[@LINE]]:24
+  return value;
+}
+
+static void foo(T value) {}                     // CHECK: rename local [[@LINE]]:17 -> [[@LINE]]:18
+
+T member;                                       // CHECK: rename local [[@LINE]]:1 -> [[@LINE]]:2
+};
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:1:20 -new-name=U %s -fno-delayed-template-parsing | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:3:22 -new-name=U %s -fno-delayed-template-parsing | FileCheck %s
+// Test 3.
+// RUN: clang-refactor-test rename-initiate -at=%s:10:23 -new-name=U %s -fno-delayed-template-parsing | FileCheck %s
diff --git a/test/Refactor/Rename/TemplatedClassFunction.cpp b/test/Refactor/Rename/TemplatedClassFunction.cpp
new file mode 100644
index 0000000..7eb3e44
--- /dev/null
+++ b/test/Refactor/Rename/TemplatedClassFunction.cpp
@@ -0,0 +1,19 @@
+template <typename T>
+class A {
+public:
+  void foo() /* Test 1 */ {}  // CHECK: rename [[@LINE]]:8 -> [[@LINE]]:11
+};
+
+int main(int argc, char **argv) {
+  A<int> a;
+  a.foo();   /* Test 2 */     // CHECK: rename [[@LINE]]:5 -> [[@LINE]]:8
+  return 0;
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:4:8 -new-name=bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:9:5 -new-name=bar %s | FileCheck %s
+//
+// Currently unsupported test.
+// XFAIL: *
diff --git a/test/Refactor/Rename/TransparentTypedef.m b/test/Refactor/Rename/TransparentTypedef.m
new file mode 100644
index 0000000..1a2dcb1
--- /dev/null
+++ b/test/Refactor/Rename/TransparentTypedef.m
@@ -0,0 +1,49 @@
+#define NS_ENUM(_name, _type) enum _name:_type _name; enum _name : _type
+// CHECK1: Renaming 1 symbols
+// CHECK1-NEXT: 'c:@E@AnotherEnum'
+typedef NS_ENUM(AnotherEnum, int) { // CHECK1: rename [[@LINE]]:17 -> [[@LINE]]:28
+  AnotherEnumFirst = 0,
+};
+AnotherEnum anotherT; // CHECK1: rename [[@LINE]]:1 -> [[@LINE]]:12
+enum AnotherEnum anotherE; // CHECK1: rename [[@LINE]]:6 -> [[@LINE]]:17
+
+// RUN: clang-refactor-test rename-initiate -at=%s:4:17 -at=%s:7:1 -at=%s:8:6 -new-name=foo -dump-symbols %s | FileCheck --check-prefix=CHECK1 %s
+
+#define TRANSPARENT(_name) struct _name _name; struct _name
+#define OPAQUE(_name) struct _name *_name; struct _name
+
+// CHECK2: Renaming 1 symbols
+// CHECK2-NEXT: 'c:@S@AStruct'
+typedef TRANSPARENT(AStruct) { // CHECK2: rename [[@LINE]]:21 -> [[@LINE]]:28
+  int x;
+};
+
+AStruct aStructT; // CHECK2: rename [[@LINE]]:1 -> [[@LINE]]:8
+struct AStruct aStructS; // CHECK2: rename [[@LINE]]:8 -> [[@LINE]]:15
+
+// RUN: clang-refactor-test rename-initiate -at=%s:17:21 -at=%s:21:1 -at=%s:22:8 -new-name=foo -dump-symbols %s | FileCheck --check-prefix=CHECK2 %s
+
+// CHECK3: Renaming 1 symbols
+// CHECK3-NEXT: 'c:{{.*}}TransparentTypedef.m@T@Separate'
+// CHECK4: Renaming 1 symbols
+// CHECK4-NEXT: 'c:@S@Separate'
+
+typedef OPAQUE(Separate) { // CHECK3: rename [[@LINE]]:16 -> [[@LINE]]:24
+  int x; // CHECK4: rename [[@LINE-1]]:16 -> [[@LINE-1]]:24
+};
+
+
+Separate separateT; // CHECK3: rename [[@LINE]]:1 -> [[@LINE]]:9
+struct Separate separateE;  // CHECK4: rename [[@LINE]]:8 -> [[@LINE]]:16
+
+// RUN: clang-refactor-test rename-initiate -at=%s:36:1 -new-name=foo -dump-symbols %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:31:16 -at=%s:37:8 -new-name=foo -dump-symbols %s | FileCheck --check-prefix=CHECK4 %s
+
+#include "Inputs/TransparentEnum.h"
+
+// CHECK5: 'c:@E@AnotherEnum2'
+typedef TRANSPARENT_ENUM(AnotherEnum2, int) { // CHECK5: rename [[@LINE]]:26 -> [[@LINE]]:38
+  EnumThing = 0, // CHECK6: [[@LINE]]:3 -> [[@LINE]]:12
+};
+// RUN: clang-refactor-test rename-initiate -at=%s:45:26 -new-name=foo -dump-symbols %s | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:46:3 -new-name=foo %s | FileCheck --check-prefix=CHECK6 %s
diff --git a/test/Refactor/Rename/TypedefTag.cpp b/test/Refactor/Rename/TypedefTag.cpp
new file mode 100644
index 0000000..390350c
--- /dev/null
+++ b/test/Refactor/Rename/TypedefTag.cpp
@@ -0,0 +1,21 @@
+struct S1 { }; // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:10
+
+typedef struct S2 { } S3; // CHECK2: rename [[@LINE]]:16 -> [[@LINE]]:18
+// CHECK3: rename [[@LINE-1]]:23 -> [[@LINE-1]]:25
+
+void func(struct S1, // CHECK1-NEXT: rename [[@LINE]]:18 -> [[@LINE]]:20
+          struct S2, // CHECK2-NEXT: rename [[@LINE]]:18 -> [[@LINE]]:20
+          S3) { // CHECK3-NEXT: rename [[@LINE]]:11 -> [[@LINE]]:13
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:1:8 -at=%s:6:18 -new-name=Bar %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:3:16 -at=%s:7:18 -new-name=Bar %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:3:23 -at=%s:8:11 -new-name=Bar %s | FileCheck --check-prefix=CHECK3 %s
+
+// RUN: clang-refactor-test rename-initiate -at=%s:1:8 -at=%s:6:18 -new-name=Bar %s -x c | FileCheck --check-prefix=CHECK1 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:3:16 -at=%s:7:18 -new-name=Bar %s -x c | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-initiate -at=%s:3:23 -at=%s:8:11 -new-name=Bar %s -x c | FileCheck --check-prefix=CHECK3 %s
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:3:9 -at=%s:6:11 -at=%s:7:11 -new-name=Bar %s 2>&1 | FileCheck --check-prefix=ERROR %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:3:9 -at=%s:6:11 -at=%s:7:11 -new-name=Bar %s -x c 2>&1 | FileCheck --check-prefix=ERROR %s
+// ERROR: could not rename symbol at the given location
diff --git a/test/Refactor/Rename/USRForSymbols.m b/test/Refactor/Rename/USRForSymbols.m
new file mode 100644
index 0000000..1f1efe8
--- /dev/null
+++ b/test/Refactor/Rename/USRForSymbols.m
@@ -0,0 +1,16 @@
+@interface I1
+
+@property int p1;
+
+@end
+
+@implementation I1
+
+@end
+
+// CHECK: 3 symbols
+// CHECK: 'c:objc(cs)I1(py)p1'
+// CHECK: 'c:objc(cs)I1(im)p1'
+// CHECK: 'c:objc(cs)I1(im)setP1:'
+
+// RUN: clang-refactor-test rename-initiate -at=%s:3:15 -new-name=foo -dump-symbols %s | FileCheck %s
diff --git a/test/Refactor/Rename/UserDefinedConversion.cpp b/test/Refactor/Rename/UserDefinedConversion.cpp
new file mode 100644
index 0000000..24614bf
--- /dev/null
+++ b/test/Refactor/Rename/UserDefinedConversion.cpp
@@ -0,0 +1,23 @@
+class Foo {       /* Test 1 */          // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:10
+public:
+  Foo() {}                              // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+};
+
+class Baz {
+public:
+  operator Foo()  /* Test 2 */ const {  // CHECK: rename [[@LINE]]:12 -> [[@LINE]]:15
+    Foo foo;                            // CHECK: rename [[@LINE]]:5 -> [[@LINE]]:8
+    return foo;
+  }
+};
+
+int main() {
+  Baz boo;
+  Foo foo = static_cast<Foo>(boo);      // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:6
+  return 0;                             // CHECK: rename [[@LINE-1]]:25 -> [[@LINE-1]]:28
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:1:7 -new-name=Bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:8:12 -new-name=Bar %s | FileCheck %s
diff --git a/test/Refactor/Rename/UsingDecl.cpp b/test/Refactor/Rename/UsingDecl.cpp
new file mode 100644
index 0000000..99eb1f4
--- /dev/null
+++ b/test/Refactor/Rename/UsingDecl.cpp
@@ -0,0 +1,46 @@
+
+namespace ns { // CHECK4: rename [[@LINE]]:11 -> [[@LINE]]:13
+
+struct Struct { }; // CHECK1: rename [[@LINE]]:8 -> [[@LINE]]:14
+
+void func(); // CHECK2: rename [[@LINE]]:6 -> [[@LINE]]:10
+
+void overload1(int x);
+void overload1(double y); // CHECK3: rename [[@LINE]]:6 -> [[@LINE]]:15
+
+}
+
+using ns::Struct; // CHECK1: rename [[@LINE]]:11 -> [[@LINE]]:17
+
+// RUN: clang-refactor-test rename-initiate -at=%s:13:11 -new-name=x %s | FileCheck --check-prefix=CHECK1 %s
+
+using ns::func; // CHECK2: rename [[@LINE]]:11 -> [[@LINE]]:15
+
+// RUN: clang-refactor-test rename-initiate -at=%s:17:11 -new-name=x %s | FileCheck --check-prefix=CHECK2 %s
+
+using ns::overload1; // CHECK3: rename [[@LINE]]:11 -> [[@LINE]]:20
+
+// RUN: clang-refactor-test rename-initiate -at=%s:21:11 -new-name=x %s | FileCheck --check-prefix=CHECK3 %s
+
+using namespace ns; // CHECK4: rename [[@LINE]]:17 -> [[@LINE]]:19
+
+// RUN: clang-refactor-test rename-initiate -at=%s:25:17 -new-name=x %s | FileCheck --check-prefix=CHECK4 %s
+
+struct UsingConstructor {
+  template<class T>
+  UsingConstructor(T, typename T::Q);
+};
+struct UsingConstructorHere : UsingConstructor {
+using UsingConstructor::UsingConstructor; // CHECK5: rename [[@LINE]]:7 -> [[@LINE]]:23
+// CHECK5: rename [[@LINE-1]]:25 -> [[@LINE-1]]:41
+};
+// RUN: clang-refactor-test rename-initiate -at=%s:34:25 -new-name=x %s -std=c++14 | FileCheck --check-prefix=CHECK5 %s
+
+template<typename T>
+struct S : T {
+  using T::T; // CHECK6: rename local [[@LINE]]:12 -> [[@LINE]]:13
+// RUN: clang-refactor-test rename-initiate -at=%s:41:12 -new-name=x %s -std=c++14 | FileCheck --check-prefix=CHECK6 %s
+  using typename T::Foo;
+// RUN: not clang-refactor-test rename-initiate -at=%s:43:12 -new-name=x %s -std=c++14 2>&1 | FileCheck --check-prefix=CHECK-UNRESOLVED %s
+// CHECK-UNRESOLVED: error: could not rename symbol at the given location
+};
diff --git a/test/Refactor/Rename/Variable.cpp b/test/Refactor/Rename/Variable.cpp
new file mode 100644
index 0000000..7d5c41e
--- /dev/null
+++ b/test/Refactor/Rename/Variable.cpp
@@ -0,0 +1,29 @@
+namespace A {
+int Foo;          /* Test 1 */        // CHECK: rename [[@LINE]]:5 -> [[@LINE]]:8
+}
+int Foo;
+int Qux = Foo;
+int Baz = A::Foo; /* Test 2 */        // CHECK-NEXT: rename [[@LINE]]:14 -> [[@LINE]]:17
+void fun() {
+  struct {
+    int Foo;
+  } b = {100};
+  int Foo = 100;
+  Baz = Foo;
+  {
+    extern int Foo;
+    Baz = Foo;
+    Foo = A::Foo /* Test 3 */ + Baz;  // CHECK-NEXT: rename [[@LINE]]:14 -> [[@LINE]]:17
+    A::Foo /* Test 4 */ = b.Foo;      // CHECK-NEXT: rename [[@LINE]]:8 -> [[@LINE]]:11
+  }
+  Foo = b.Foo;                        // CHECK-NOT: rename [[@LINE]]
+}
+
+// Test 1.
+// RUN: clang-refactor-test rename-initiate -at=%s:2:5 -new-name=Bar %s | FileCheck %s
+// Test 2.
+// RUN: clang-refactor-test rename-initiate -at=%s:6:14 -new-name=Bar %s | FileCheck %s
+// Test 3.
+// RUN: clang-refactor-test rename-initiate -at=%s:16:14 -new-name=Bar %s | FileCheck %s
+// Test 4.
+// RUN: clang-refactor-test rename-initiate -at=%s:17:8 -new-name=Bar %s | FileCheck %s
diff --git a/test/Refactor/Rename/VariableMacro.cpp b/test/Refactor/Rename/VariableMacro.cpp
new file mode 100644
index 0000000..312d459
--- /dev/null
+++ b/test/Refactor/Rename/VariableMacro.cpp
@@ -0,0 +1,69 @@
+#define Baz Foo // CHECK1-NOT: rename local [[@LINE]]
+// CHECK1-NOT: macro [[@LINE-1]]
+
+void foo(int value) {}
+
+void macro() {
+  int Foo;  // CHECK1: rename local [[@LINE]]:7 -> [[@LINE]]:10
+  Foo = 42; // CHECK1-NEXT: rename local [[@LINE]]:3 -> [[@LINE]]:6
+  Baz -= 0; // CHECK1-NEXT: macro [[@LINE]]:3 -> [[@LINE]]:3
+  foo(Foo); // CHECK1-NEXT: rename local [[@LINE]]:7 -> [[@LINE]]:10
+  foo(Baz); // CHECK1-NEXT: macro [[@LINE]]:7 -> [[@LINE]]:7
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:7:7 -at=%s:8:3 -at=%s:10:7 -new-name=Bar %s | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:1:13 -new-name=Bar %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:9:3 -new-name=Bar %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+// CHECK-ERROR: could not rename symbol at the given location
+
+#define M var
+#define MM M
+void macro2() {
+  int M = 2; // CHECK2: macro [[@LINE]]:7 -> [[@LINE]]:7
+  (void)var; // CHECK2-NEXT: rename local [[@LINE]]:9 -> [[@LINE]]:12
+  (void)M;   // CHECK2-NEXT: macro [[@LINE]]:9 -> [[@LINE]]:9
+  (void)MM;  // CHECK2-NEXT: macro [[@LINE]]:9 -> [[@LINE]]:9
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:24:9 -new-name=Bar %s | FileCheck --check-prefix=CHECK2 %s
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:20:11 -new-name=Bar %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:21:12 -new-name=Bar %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:23:7 -new-name=Bar %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:25:9 -new-name=Bar %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+
+#define BAR(x) x
+#define FOO(x) BAR(x)
+int FOO(global) = 2; // CHECK3: rename [[@LINE]]:9 -> [[@LINE]]:15
+void macro3() {
+  (void)global;      // CHECK3-NEXT: rename [[@LINE]]:9 -> [[@LINE]]:15
+  BAR(global) = 0;   // CHECK3-NEXT: rename [[@LINE]]:7 -> [[@LINE]]:13
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:40:9 -at=%s:41:7 -new-name=Bar %s | FileCheck --check-prefix=CHECK3 %s
+
+
+
+#define CONCAT(x, y) x##_##y
+int CONCAT(a, b) = 2; // CHECK4: macro [[@LINE]]:5 -> [[@LINE]]:5
+void macro3() {
+  (void)a_b;          // CHECK4-NEXT: rename [[@LINE]]:9 -> [[@LINE]]:12
+  CONCAT(a, b) = 0;   // CHECK4-NEXT: macro [[@LINE]]:3 -> [[@LINE]]:3
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:51:9 -new-name=Bar %s | FileCheck --check-prefix=CHECK4 %s
+
+void macroInFunc() {
+  #define VARNAME var
+  int VARNAME;
+}
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:58:19 -new-name=Bar %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR %s
+
+void localVarArg() {
+  int var; // CHECK5: rename local [[@LINE]]:7 -> [[@LINE]]:10
+  BAR(var) = 0; // CHECK5-NEXT: rename local [[@LINE]]:7 -> [[@LINE]]:10
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:65:7 -at=%s:66:7 -new-name=Bar %s | FileCheck --check-prefix=CHECK5 %s
diff --git a/test/Refactor/Rename/invalid-indexed-name.m b/test/Refactor/Rename/invalid-indexed-name.m
new file mode 100644
index 0000000..b682bb3
--- /dev/null
+++ b/test/Refactor/Rename/invalid-indexed-name.m
@@ -0,0 +1,37 @@
+// XFAIL: *
+// TODO: Remove if unused
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test
+
+int variable = 0; // CHECK1: rename [[@LINE]]:5 -> [[@LINE]]:13
+
+// RUN: clang-refactor-test rename-indexed-file -name=variable -new-name=class -indexed-file=%s -indexed-at=4:5 %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: not clang-refactor-test rename-indexed-file -name=variable -new-name=class -indexed-file=%s -indexed-at=4:5 %s -x objective-c++ 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
+// CHECK-ERR: error: invalid new name
+
+// RUN: not clang-refactor-test rename-indexed-file -name=variable -new-name=int -indexed-file=%s -indexed-at=4:5 %s 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
+
+@interface I
+
+- (void)some:(int)x selector:(int)y; // CHECK2: rename [[@LINE]]:9 -> [[@LINE]]:13, [[@LINE]]:21 -> [[@LINE]]:29
+
+@end
+
+// RUN: clang-refactor-test rename-indexed-file -name=some:selector -new-name=struct:void -indexed-file=%s -indexed-at=14:9 -indexed-symbol-kind=objc-im %s | FileCheck --check-prefix=CHECK2 %s
+// RUN: clang-refactor-test rename-indexed-file -name=some:selector: -new-name=struct:void -indexed-file=%s -indexed-at=14:9 -indexed-symbol-kind=objc-cm %s | FileCheck --check-prefix=CHECK2 %s
+
+// RUN: not clang-refactor-test rename-indexed-file -name=some:selector -new-name=struct:void -indexed-file=%s -indexed-at=14:9 %s 2>&1 | FileCheck --check-prefix=CHECK-ERR-FAIL %s
+// CHECK-ERR-FAIL: failed to perform indexed file rename
+// RUN: not clang-refactor-test rename-indexed-file -name=some:selector -new-name=hello:123 -indexed-file=%s -indexed-at=14:9 -indexed-symbol-kind=objc-im %s 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
+// RUN: not clang-refactor-test rename-indexed-file -name=some:selector -new-name=+:test -indexed-file=%s -indexed-at=14:9 -indexed-symbol-kind=objc-im %s 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
+
+// RUN: not clang-refactor-test rename-indexed-file -name=some:selector -new-name=justOnePiece -indexed-file=%s -indexed-at=14:9 -indexed-symbol-kind=objc-im %s 2>&1 | FileCheck --check-prefix=CHECK-ERR2 %s
+// CHECK-ERR2: error: the number of strings in the new name 'justOnePiece' doesn't match the the number of strings in the old name
+
+@interface I1
+
+- (void)singlePiece;
+
+@end
+
+// RUN: not clang-refactor-test rename-indexed-file -name=singlePiece -new-name=struct -indexed-file=%s -indexed-at=31:9 %s 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
diff --git a/test/Refactor/Rename/invalid-name.cpp b/test/Refactor/Rename/invalid-name.cpp
new file mode 100644
index 0000000..703f818
--- /dev/null
+++ b/test/Refactor/Rename/invalid-name.cpp
@@ -0,0 +1,13 @@
+// XFAIL: *
+// TODO: Remove if unused
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test
+
+int variable = 0;
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:4:5 -new-name=class %s 2>&1 | FileCheck %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:4:5 -new-name=- %s 2>&1 | FileCheck %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:4:5 -new-name=var+ %s 2>&1 | FileCheck %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:4:5 -new-name="var " %s 2>&1 | FileCheck %s
+
+// CHECK: error: invalid new name
diff --git a/test/Refactor/Rename/invalid-name.m b/test/Refactor/Rename/invalid-name.m
new file mode 100644
index 0000000..65014be
--- /dev/null
+++ b/test/Refactor/Rename/invalid-name.m
@@ -0,0 +1,23 @@
+// XFAIL: *
+// TODO: Remove if unused
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test
+
+int variable = 0; // CHECK1: rename [[@LINE]]:5 -> [[@LINE]]:13
+
+// RUN: clang-refactor-test rename-initiate -at=%s:4:5 -new-name=class %s | FileCheck --check-prefix=CHECK1 %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:4:5 -new-name=class %s -x objective-c++ 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
+// CHECK-ERR: error: invalid new name
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:4:5 -new-name=int %s 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
+
+@interface I
+
+- (void)some:(int)x selector:(int)y; // CHECK2: rename [[@LINE]]:9 -> [[@LINE]]:13, [[@LINE]]:21 -> [[@LINE]]:29
+
+@end
+
+// RUN: clang-refactor-test rename-initiate -at=%s:14:9 -new-name=struct:void %s | FileCheck --check-prefix=CHECK2 %s
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:14:9 -new-name=hello:123 %s 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
+// RUN: not clang-refactor-test rename-initiate -at=%s:14:9 -new-name=+:test %s 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
diff --git a/test/Refactor/Rename/rename-indexed-file.cpp b/test/Refactor/Rename/rename-indexed-file.cpp
new file mode 100644
index 0000000..4e64fdf
--- /dev/null
+++ b/test/Refactor/Rename/rename-indexed-file.cpp
@@ -0,0 +1,123 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test
+
+class Test {  // CHECK1: rename [[@LINE]]:7 -> [[@LINE]]:11
+public:
+  Test() { }  // CHECK1: rename [[@LINE]]:3 -> [[@LINE]]:7
+  ~Test() { } // CHECK1: rename [[@LINE]]:4 -> [[@LINE]]:8
+
+  void doSomething() { return; }
+  void otherFile();
+};
+
+void foo() {
+  Test test;  // CHECK1: rename [[@LINE]]:3 -> [[@LINE]]:7
+  (test).doSomething();
+}
+
+Test notIndexed; // CHECK1-NOT: rename [[@LINE]]
+
+// RUN: clang-refactor-test rename-indexed-file -name=Test -new-name=Foo -indexed-file=%s -indexed-at=4:7 -indexed-at=6:3 -indexed-at=7:4 -indexed-at=14:3 %s | FileCheck --check-prefix=CHECK1 %s
+
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -name=Test -new-name=Foo -indexed-file=%S/Inputs/rename-indexed-file.cpp -indexed-at=1:6 -indexed-at=2:3 -indexed-at=3:6 %s | FileCheck --check-prefix=CHECK2 %s
+// CHECK2: rename 1:6 -> 1:10
+// CHECK2: rename 2:3 -> 2:7
+// CHECK2: rename 3:6 -> 3:10
+
+// A valid location with an non-identifier token shouldn't produce an occurence
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -name=Test -new-name=Foo -indexed-file=%s -indexed-at=15:3 %s | FileCheck --check-prefix=CHECK3 %s
+
+// A invalid location shouldn't produce an occurence
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -name=Test -new-name=Foo -indexed-file=%s -indexed-at=999:1 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -name=Test -new-name=Foo -indexed-file=%s -indexed-at=0:1 %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -name=Test -new-name=Foo -indexed-file=%s -indexed-at=1:0 %s | FileCheck --check-prefix=CHECK3 %s
+
+
+// CHECK3: no replacements found
+// CHECK3-NOT: rename
+
+// RUN: not clang-refactor-test rename-indexed-file -no-textual-matches -name=Test -new-name=Foo %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR1 %s
+
+// CHECK-ERROR1: for the -indexed-file option: must be specified at least once!
+
+// It should be possible to have the filename as one of the compilation arguments
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -ignore-filename-for-initiation-tu -name=Test -new-name=Foo -indexed-file=%s -indexed-at=4:7 -indexed-at=6:3 -indexed-at=7:4 -indexed-at=14:3 %s -c %s -Wall | FileCheck --check-prefix=CHECK1 %s
+
+// -gmodules should be stripped to avoid -fmodule-format=obj in CC1 arguments:
+// RUN: clang-refactor-test rename-indexed-file -no-textual-matches -name=Test -new-name=Foo -indexed-file=%s -indexed-at=4:7 -indexed-at=6:3 -indexed-at=7:4 -indexed-at=14:3 %s -fmodules -gmodules | FileCheck --check-prefix=CHECK1 %s
+
+// These texual matches should be reported as comment occurrences:
+// CHECK4-INIT: rename [[@LINE-46]]:7 -> [[@LINE-46]]:11
+// Test
+/* Test 2 Test */
+/** Test+1
+// Test
+**/
+/// Hello Test World
+//! \c Test.
+
+// CHECK4: comment [[@LINE-8]]:4 -> [[@LINE-8]]:8
+// CHECK4-NEXT: comment [[@LINE-8]]:4 -> [[@LINE-8]]:8
+// CHECK4-NEXT: comment [[@LINE-9]]:11 -> [[@LINE-9]]:15
+// CHECK4-NEXT: documentation [[@LINE-9]]:5 -> [[@LINE-9]]:9
+// CHECK4-NEXT: documentation [[@LINE-9]]:4 -> [[@LINE-9]]:8
+// CHECK4-NEXT: documentation [[@LINE-8]]:11 -> [[@LINE-8]]:15
+// CHECK4-NEXT: documentation [[@LINE-8]]:8 -> [[@LINE-8]]:12
+
+// "Test"
+// 'Test'
+// CHECK4-NEXT: comment [[@LINE-2]]:5 -> [[@LINE-2]]:9
+// CHECK4-NEXT: comment [[@LINE-2]]:5 -> [[@LINE-2]]:9
+
+// CHECK4-NEXT: comment [[@LINE+1]]:55
+// RUN: clang-refactor-test rename-indexed-file -name=Test -new-name=Foo -indexed-file=%s -indexed-at=4:7 %s | FileCheck --check-prefixes=CHECK4-INIT,CHECK4 %s
+// We should find textual occurrences even without indexed occurrences:
+// CHECK4-NEXT: comment [[@LINE+1]]:55
+// RUN: clang-refactor-test rename-indexed-file -name=Test -new-name=Foo -indexed-file=%s %s | FileCheck --check-prefix=CHECK4 %s
+
+// These ones shouldn't:
+// Test2 test Testable
+/// _Test
+/// ATest_
+const char *test = "Test";
+void Test20() { }
+
+// CHECK4-NOT: comment
+// CHECK4-NOT: documentation
+
+
+class MyInclude { // CHECK5: rename [[@LINE]]:7 -> [[@LINE]]:16
+};
+
+ /*comment*/ #include "MyInclude.h"
+#include <clang/myinclude.h>
+#import <MyInclude/ThisIsMyInclude>
+// CHECK5-NEXT: filename [[@LINE-3]]:24 -> [[@LINE-3]]:33
+// CHECK5-NEXT: filename [[@LINE-3]]:17 -> [[@LINE-3]]:26
+// CHECK5-NEXT: filename [[@LINE-3]]:26 -> [[@LINE-3]]:35
+
+// CHECK5-NOT: filename
+#include "My Include.h"
+"MyInclude.h"
+
+// RUN: clang-refactor-test rename-indexed-file -name=MyInclude -new-name=Foo -indexed-file=%s -indexed-at=89:7 -indexed-at=include:92:1 -indexed-at=include:93:1 -indexed-at=include:94:1 -indexed-at=include:100:1 %s | FileCheck --check-prefix=CHECK5 %s
+
+#define MACRO variable
+
+void macroOccurrence() {
+  variable;
+  MACRO;
+  22;
+  MACRO;
+}
+// CHECK-MACRO: rename [[@LINE-5]]:3 -> [[@LINE-5]]:11
+// CHECK-MACRO-NEXT: macro [[@LINE-5]]:3 -> [[@LINE-5]]:3
+// CHECK-MACRO-NOT: macro
+
+// RUN: clang-refactor-test rename-indexed-file -name=variable -new-name=foo -indexed-file=%s -indexed-at=108:3 -indexed-at=109:3 -indexed-at=110:3 -indexed-at=111:2 %s | FileCheck --check-prefix=CHECK-MACRO %s
+
+struct MyType { // CHECK-MACRO-PREFIX: rename [[@LINE]]:8 -> [[@LINE]]:14
+};
+MyType MyTypePrefix; // CHECK-MACRO-PREFIX: macro [[@LINE]]:8 -> [[@LINE]]:8
+
+// RUN: clang-refactor-test rename-indexed-file -name=MyType -new-name=x -indexed-file=%s -indexed-at=119:8 -indexed-at=121:8 %s | FileCheck --check-prefix=CHECK-MACRO-PREFIX %s
diff --git a/test/Refactor/Rename/rename-initiate-usr.cpp b/test/Refactor/Rename/rename-initiate-usr.cpp
new file mode 100644
index 0000000..2f15465
--- /dev/null
+++ b/test/Refactor/Rename/rename-initiate-usr.cpp
@@ -0,0 +1,20 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test
+
+class Test {  // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:11
+public:
+  Test() { }  // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:7
+  ~Test() { } // CHECK: rename [[@LINE]]:4 -> [[@LINE]]:8
+};
+
+void foo() {
+  Test test;  // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:7
+}
+
+// RUN: clang-refactor-test rename-initiate-usr -usr="c:@S@Test" -new-name=Foo %s | FileCheck %s
+
+// RUN: not clang-refactor-test rename-initiate-usr -usr="c:@S@Foo" -new-name=Foo %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR1 %s
+// CHECK-ERROR1: error: could not rename symbol with the given USR
+
+// RUN: not clang-refactor-test rename-initiate-usr -new-name=Foo %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR2 %s
+// CHECK-ERROR2: for the -usr option: must be specified at least once
diff --git a/test/Refactor/Rename/rename-initiate.cpp b/test/Refactor/Rename/rename-initiate.cpp
new file mode 100644
index 0000000..30c918c
--- /dev/null
+++ b/test/Refactor/Rename/rename-initiate.cpp
@@ -0,0 +1,27 @@
+// Note: the run lines follow their respective tests, since line/column
+// matter in this test
+
+class Test {  // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:11
+public:
+  Test() { }  // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:7
+  ~Test() { } // CHECK: rename [[@LINE]]:4 -> [[@LINE]]:8
+  void doSomething() {
+    return;
+  }
+};
+
+void foo() {
+  Test test;  // CHECK: rename [[@LINE]]:3 -> [[@LINE]]:7
+  test.doSomething();
+}
+
+// RUN: clang-refactor-test rename-initiate -at=%s:4:7 -new-name=Foo %s | FileCheck %s
+// RUN: clang-refactor-test rename-initiate -at=%s:4:8 -new-name=Foo %s | FileCheck %s
+// RUN: clang-refactor-test rename-initiate -at=%s:4:9 -new-name=Foo %s | FileCheck %s
+// RUN: clang-refactor-test rename-initiate -at=%s:4:10 -new-name=Foo %s | FileCheck %s
+
+// RUN: not clang-refactor-test rename-initiate -at=%s:1:10 -new-name=Foo %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR1 %s
+// CHECK-ERROR1: error: could not rename symbol at the given location
+
+// RUN: not clang-refactor-test rename-initiate -at=%s -new-name=Foo %s 2>&1 | FileCheck --check-prefix=CHECK-ERROR2 %s
+// CHECK-ERROR2: error: The -at option must use the <file:line:column> format
diff --git a/test/Refactor/list-refactoring-actions.cpp b/test/Refactor/list-refactoring-actions.cpp
new file mode 100644
index 0000000..573a076
--- /dev/null
+++ b/test/Refactor/list-refactoring-actions.cpp
@@ -0,0 +1,39 @@
+int
+renamable = 0;
+
+// RUN: clang-refactor-test list-actions -at=%s:2:1 %s | FileCheck --check-prefix=CHECK-RENAME %s
+
+// CHECK-RENAME: Found {{[0-9]*}} actions:
+// CHECK-RENAME-NEXT: Rename
+
+// RUN: not clang-refactor-test list-actions -at=%s:2:13 %s 2>&1 | FileCheck --check-prefix=CHECK-NONE %s
+
+// CHECK-NONE: No refactoring actions are available at the given location
+// CHECK-NONE-NOT: Rename
+
+// RUN: not clang-refactor-test list-actions -at=%s %s 2>&1 | FileCheck --check-prefix=CHECK-ERR %s
+// CHECK-ERR: error: The -at option must use the <file:line:column> format
+
+void localVsGlobalRename(int renamable) { }
+
+// RUN: clang-refactor-test list-actions -dump-raw-action-type -at=%s:17:30 %s | FileCheck --check-prefix=CHECK-LOCAL-RENAME %s
+
+// CHECK-LOCAL-RENAME: Found {{[0-9]*}} actions:
+// CHECK-LOCAL-RENAME-NEXT: Rename(1)
+
+namespace nullDeclNamespace {
+
+template<template<typename T> class C> class NullNode {};
+
+struct AfterNull { };
+// RUN: clang-refactor-test list-actions -at=%s:28:8 %s | FileCheck --check-prefix=CHECK-RENAME %s
+
+}
+
+#define MACRO(X) (void)X;
+void macroArg() {
+  int variable = 0;
+  MACRO(variable);
+}
+// RUN: not clang-refactor-test list-actions -at=%s:26:9 -selected=%s:36:9-36:16 %s 2>&1 | FileCheck --check-prefix=CHECK-MACRO-ARG %s
+// CHECK-MACRO-ARG: No refactoring actions are available at the given location
diff --git a/test/Sema/attr-availability-app-extensions.c b/test/Sema/attr-availability-app-extensions.c
index 8f9dcbc..c66c14e 100644
--- a/test/Sema/attr-availability-app-extensions.c
+++ b/test/Sema/attr-availability-app-extensions.c
@@ -21,8 +21,19 @@
 #endif
 void f1(int); // expected-note {{'f1' has been explicitly marked unavailable here}}
 
+#if __has_feature(attribute_availability_app_extension)
+ __attribute__((availability(macOSApplicationExtension,unavailable)))
+#ifndef TVOS
+ __attribute__((availability(iOSApplicationExtension,unavailable)))
+#else
+ __attribute__((availability(tvOSApplicationExtension,unavailable)))
+#endif
+#endif
+void f2(int); // expected-note {{'f2' has been explicitly marked unavailable here}}
+
 void test() {
   f0(1); // expected-error {{'f0' is unavailable: not available on}}
   f1(1); // expected-error {{'f1' is unavailable}}
+  f2(2); // expected-error {{'f2' is unavailable: not available on}}
 }
 
diff --git a/test/Sema/attr-availability-ios.c b/test/Sema/attr-availability-ios.c
index 6462d58..3f901bb 100644
--- a/test/Sema/attr-availability-ios.c
+++ b/test/Sema/attr-availability-ios.c
@@ -2,13 +2,13 @@
 
 void f0(int) __attribute__((availability(ios,introduced=2.0,deprecated=2.1))); // expected-note {{'f0' has been explicitly marked deprecated here}}
 void f1(int) __attribute__((availability(ios,introduced=2.1)));
-void f2(int) __attribute__((availability(ios,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
+void f2(int) __attribute__((availability(iOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2' has been explicitly marked deprecated here}}
 void f3(int) __attribute__((availability(ios,introduced=3.0)));
 void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
 
 void f5(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5' has been explicitly marked deprecated here}}
 void f6(int) __attribute__((availability(ios,deprecated=3.0)));
-void f6(int) __attribute__((availability(ios,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
+void f6(int) __attribute__((availability(iOS,introduced=2.0))); // expected-note {{'f6' has been explicitly marked deprecated here}}
 
 void test() {
   f0(0); // expected-warning{{'f0' is deprecated: first deprecated in iOS 2.1}}
diff --git a/test/Sema/attr-availability-macosx.c b/test/Sema/attr-availability-macosx.c
index f422811..d390869 100644
--- a/test/Sema/attr-availability-macosx.c
+++ b/test/Sema/attr-availability-macosx.c
@@ -10,7 +10,7 @@
 void f3(int) __attribute__((availability(macosx,introduced=10.6)));
 void f4(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(ios,introduced=2.0,deprecated=3.0))); // expected-note{{explicitly marked unavailable}}
 void f5(int) __attribute__((availability(ios,introduced=3.2), availability(macosx,unavailable))); // expected-note{{'f5' has been explicitly marked unavailable here}}
-void f6(int) __attribute__((availability(macosx,strict,introduced=10.6))); //expected-note{{'f6' has been explicitly marked unavailable here}}
+void f6(int) __attribute__((availability(macOS,strict,introduced=10.6))); //expected-note{{'f6' has been explicitly marked unavailable here}}
 
 void test() {
   f0(0);
@@ -47,7 +47,7 @@
 };
 
 // Make sure the note is on the declaration with the actual availability attributes.
-struct __attribute__((availability(macosx,strict,introduced=10.9))) type_info // \
+struct __attribute__((availability(macOS,strict,introduced=10.9))) type_info // \
     expected-note{{'type_info' has been explicitly marked unavailable here}}
 {
 };
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-tvos.c b/test/Sema/attr-availability-tvos.c
index 6422464..d53d6ac 100644
--- a/test/Sema/attr-availability-tvos.c
+++ b/test/Sema/attr-availability-tvos.c
@@ -36,7 +36,7 @@
 // Test tvOS specific attributes.
 void f0_tvos(int) __attribute__((availability(tvos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0_tvos' has been explicitly marked deprecated here}}
 void f1_tvos(int) __attribute__((availability(tvos,introduced=2.1)));
-void f2_tvos(int) __attribute__((availability(tvos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_tvos' has been explicitly marked deprecated here}}
+void f2_tvos(int) __attribute__((availability(tvOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_tvos' has been explicitly marked deprecated here}}
 void f3_tvos(int) __attribute__((availability(tvos,introduced=3.0)));
 void f4_tvos(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(tvos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
 void f5_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0)));
@@ -44,7 +44,7 @@
 void f5b_tvos(int) __attribute__((availability(tvos,introduced=2.0))) __attribute__((availability(tvos,deprecated=3.0))); // expected-note {{'f5b_tvos' has been explicitly marked deprecated here}}
 void f5c_tvos(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5c_tvos' has been explicitly marked deprecated here}}
 void f6_tvos(int) __attribute__((availability(tvos,deprecated=3.0)));
-void f6_tvos(int) __attribute__((availability(tvos,introduced=2.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}}
+void f6_tvos(int) __attribute__((availability(tvOS,introduced=2.0))); // expected-note {{'f6_tvos' has been explicitly marked deprecated here}}
 
 void test_tvos() {
   f0_tvos(0); // expected-warning{{'f0_tvos' is deprecated: first deprecated in tvOS 2.1}}
diff --git a/test/Sema/attr-availability-watchos.c b/test/Sema/attr-availability-watchos.c
index cb9f968..ec7f3a7 100644
--- a/test/Sema/attr-availability-watchos.c
+++ b/test/Sema/attr-availability-watchos.c
@@ -25,7 +25,7 @@
 // Test watchOS specific attributes.
 void f0_watchos(int) __attribute__((availability(watchos,introduced=2.0,deprecated=2.1))); // expected-note {{'f0_watchos' has been explicitly marked deprecated here}}
 void f1_watchos(int) __attribute__((availability(watchos,introduced=2.1)));
-void f2_watchos(int) __attribute__((availability(watchos,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_watchos' has been explicitly marked deprecated here}}
+void f2_watchos(int) __attribute__((availability(watchOS,introduced=2.0,deprecated=3.0))); // expected-note {{'f2_watchos' has been explicitly marked deprecated here}}
 void f3_watchos(int) __attribute__((availability(watchos,introduced=3.0)));
 void f4_watchos(int) __attribute__((availability(macosx,introduced=10.1,deprecated=10.3,obsoleted=10.5), availability(watchos,introduced=2.0,deprecated=2.1,obsoleted=3.0))); // expected-note{{explicitly marked unavailable}}
 void f5_watchos(int) __attribute__((availability(watchos,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0)));
@@ -33,7 +33,7 @@
 void f5b_watchos(int) __attribute__((availability(watchos,introduced=2.0))) __attribute__((availability(watchos,deprecated=3.0))); // expected-note {{'f5b_watchos' has been explicitly marked deprecated here}}
 void f5c_watchos(int) __attribute__((availability(ios,introduced=2.0))) __attribute__((availability(ios,deprecated=3.0))); // expected-note {{'f5c_watchos' has been explicitly marked deprecated here}}
 void f6_watchos(int) __attribute__((availability(watchos,deprecated=3.0)));
-void f6_watchos(int) __attribute__((availability(watchos,introduced=2.0))); // expected-note {{'f6_watchos' has been explicitly marked deprecated here}}
+void f6_watchos(int) __attribute__((availability(watchOS,introduced=2.0))); // expected-note {{'f6_watchos' has been explicitly marked deprecated here}}
 
 void test_watchos() {
   f0_watchos(0); // expected-warning{{'f0_watchos' is deprecated: first deprecated in watchOS 2.1}}
diff --git a/test/Sema/attr-availability.c b/test/Sema/attr-availability.c
index 1b8cbd2..b2b1d87 100644
--- a/test/Sema/attr-availability.c
+++ b/test/Sema/attr-availability.c
@@ -91,7 +91,6 @@
 extern int x2 __attribute__((availability(macosx,introduced=10.2))); // expected-note {{previous attribute is here}}
 extern int x2 __attribute__((availability(macosx,introduced=10.5))); // expected-warning {{availability does not match previous declaration}}
 
-
 enum Original {
   OriginalDeprecated __attribute__((availability(macosx, deprecated=10.2))), // expected-note + {{'OriginalDeprecated' has been explicitly marked deprecated here}}
   OriginalUnavailable __attribute__((availability(macosx, unavailable))) // expected-note + {{'OriginalUnavailable' has been explicitly marked unavailable here}}
diff --git a/test/Sema/attr-noescape.c b/test/Sema/attr-noescape.c
new file mode 100644
index 0000000..ec367b6
--- /dev/null
+++ b/test/Sema/attr-noescape.c
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -fblocks -verify -fsyntax-only
+
+#if !__has_attribute(noescape)
+#  error "missing noescape attribute"
+#endif
+
+int *global_var __attribute((noescape)); // expected-warning{{'noescape' attribute only applies to parameters}}
+
+void foo(__attribute__((noescape)) int *int_ptr,
+         __attribute__((noescape)) int (^block)(int),
+         __attribute((noescape)) int integer) { // expected-warning{{'noescape' attribute ignored on parameter of non-pointer type 'int'}}
+}
diff --git a/test/Sema/enum-attr.c b/test/Sema/enum-attr.c
index 933d8cc..bf0dcb0 100644
--- a/test/Sema/enum-attr.c
+++ b/test/Sema/enum-attr.c
@@ -44,7 +44,7 @@
   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}}
+  switch (t0) { // expected-warning{{enumeration value 'A1' not handled in switch}} expected-note {{add missing switch cases}}
   case A0: break;
   case 16: break; // expected-warning{{case value not in enumerated type}}
   }
@@ -58,7 +58,7 @@
   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}}
+  switch (t1) { // expected-warning{{enumeration value 'B1' not handled in switch}} expected-note {{add missing switch cases}}
   case B0: break;
   case 16: break; // expected-warning{{case value not in enumerated type}}
   }
@@ -72,7 +72,7 @@
   enum EnumOpen t2 = 100;
   t2 = 1;
 
-  switch (t2) { // expected-warning{{enumeration value 'C1' not handled in switch}}
+  switch (t2) { // expected-warning{{enumeration value 'C1' not handled in switch}} expected-note {{add missing switch cases}}
   case C0: break;
   case 16: break;
   }
@@ -86,7 +86,7 @@
   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}}
+  switch (t3) { // expected-warning{{enumeration value 'D1' not handled in switch}} expected-note {{add missing switch cases}}
   case D0: break;
   case 9: break;
   case 16: break; // expected-warning{{case value not in enumerated type}}
@@ -101,7 +101,7 @@
   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}}
+  switch (t4) { // expected-warning{{enumeration value 'E1' not handled in switch}} expected-note {{add missing switch cases}}
   case E0: break;
   case 9: break;
   case 16: break; // expected-warning{{case value not in enumerated type}}
@@ -116,7 +116,7 @@
   enum EnumFlagOpen t5 = 5;
   t5 = 9;
 
-  switch (t5) { // expected-warning{{enumeration value 'F1' not handled in switch}}
+  switch (t5) { // expected-warning{{enumeration value 'F1' not handled in switch}} expected-note {{add missing switch cases}}
   case F0: break;
   case 9: break;
   case 16: break;
diff --git a/test/Sema/enum.c b/test/Sema/enum.c
index 3546bfe..cf59ca1 100644
--- a/test/Sema/enum.c
+++ b/test/Sema/enum.c
@@ -123,3 +123,14 @@
 // PR24610
 enum Color { Red, Green, Blue }; // expected-note{{previous use is here}}
 typedef struct Color NewColor; // expected-error {{use of 'Color' with tag type that does not match previous declaration}}
+
+// PR28903
+struct PR28903 {
+  enum {
+    PR28903_A = (enum { // expected-error-re {{'enum PR28903::(anonymous at {{.*}})' cannot be defined in an enumeration}}
+      PR28903_B,
+      PR28903_C = PR28903_B
+    })0
+  };
+  int makeStructNonEmpty;
+};
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/fp16vec-sema.c b/test/Sema/fp16vec-sema.c
new file mode 100644
index 0000000..aefb5f8
--- /dev/null
+++ b/test/Sema/fp16vec-sema.c
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef __fp16 half4 __attribute__ ((vector_size (8)));
+typedef float float4 __attribute__ ((vector_size (16)));
+typedef short short4 __attribute__ ((vector_size (8)));
+typedef int int4 __attribute__ ((vector_size (16)));
+
+half4 hv0, hv1;
+float4 fv0, fv1;
+short4 sv0;
+int4 iv0;
+
+void testFP16Vec(int c) {
+  hv0 = hv0 + hv1;
+  hv0 = hv0 - hv1;
+  hv0 = hv0 * hv1;
+  hv0 = hv0 / hv1;
+  hv0 = c ? hv0 : hv1;
+  hv0 += hv1;
+  hv0 -= hv1;
+  hv0 *= hv1;
+  hv0 /= hv1;
+  sv0 = hv0 == hv1;
+  sv0 = hv0 != hv1;
+  sv0 = hv0 < hv1;
+  sv0 = hv0 > hv1;
+  sv0 = hv0 <= hv1;
+  sv0 = hv0 >= hv1;
+  sv0 = hv0 || hv1; // expected-error{{logical expression with vector types 'half4' (vector of 4 '__fp16' values) and 'half4' is only supported in C++}}
+  sv0 = hv0 && hv1; // expected-error{{logical expression with vector types 'half4' (vector of 4 '__fp16' values) and 'half4' is only supported in C++}}
+
+  // Implicit conversion between half vectors and float vectors are not allowed.
+  hv0 = fv0; // expected-error{{assigning to}}
+  fv0 = hv0; // expected-error{{assigning to}}
+  hv0 = (half4)fv0; // expected-error{{invalid conversion between}}
+  fv0 = (float4)hv0; // expected-error{{invalid conversion between}}
+  hv0 = fv0 + fv1; // expected-error{{assigning to}}
+  fv0 = hv0 + hv1; // expected-error{{assigning to}}
+  hv0 = hv0 + fv1; // expected-error{{cannot convert between vector}}
+  hv0 = c ? hv0 : fv1; // expected-error{{cannot convert between vector}}
+  sv0 = hv0 == fv1; // expected-error{{cannot convert between vector}}
+  sv0 = hv0 < fv1; // expected-error{{cannot convert between vector}}
+  sv0 = hv0 || fv1; // expected-error{{cannot convert between vector}} expected-error{{invalid operands to binary expression}}
+  iv0 = hv0 == hv1; // expected-error{{assigning to}}
+
+  // FIXME: clang currently disallows using these operators on vectors, which is
+  // allowed by gcc.
+  sv0 = !hv0; // expected-error{{invalid argument type}}
+  hv0++; // expected-error{{cannot increment value of type}}
+  ++hv0; // expected-error{{cannot increment value of type}}
+}
diff --git a/test/Sema/statements.c b/test/Sema/statements.c
index dbb4d56..a17e840 100644
--- a/test/Sema/statements.c
+++ b/test/Sema/statements.c
@@ -56,7 +56,7 @@
 enum x { a, b, c, d, e, f, g };
 
 void foo(enum x X) {
-  switch (X) { // expected-warning {{enumeration value 'g' not handled in switch}}
+  switch (X) { // expected-warning {{enumeration value 'g' not handled in switch}} expected-note {{add missing switch cases}}
   case a:
   case b:
   case c:
@@ -66,7 +66,7 @@
     break;
   }
 
-  switch (X) { // expected-warning {{enumeration values 'f' and 'g' not handled in switch}}
+  switch (X) { // expected-warning {{enumeration values 'f' and 'g' not handled in switch}} expected-note {{add missing switch cases}}
   case a:
   case b:
   case c:
@@ -75,7 +75,7 @@
     break;
   }
 
-  switch (X) {  // expected-warning {{enumeration values 'e', 'f', and 'g' not handled in switch}}
+  switch (X) {  // expected-warning {{enumeration values 'e', 'f', and 'g' not handled in switch}} expected-note {{add missing switch cases}}
     case a:
     case b:
     case c:
@@ -83,7 +83,7 @@
       break;
   }
 
-  switch (X) { // expected-warning {{5 enumeration values not handled in switch: 'c', 'd', 'e'...}}
+  switch (X) { // expected-warning {{5 enumeration values not handled in switch: 'c', 'd', 'e'...}} expected-note {{add missing switch cases}}
   case a:
   case b:
     break;
diff --git a/test/Sema/switch.c b/test/Sema/switch.c
index 7aa695d..5580209 100644
--- a/test/Sema/switch.c
+++ b/test/Sema/switch.c
@@ -97,7 +97,7 @@
     A = 1,
     B
   } a;
-  switch(a) { //expected-warning{{enumeration value 'B' not handled in switch}}
+  switch(a) { //expected-warning{{enumeration value 'B' not handled in switch}} expected-note {{add missing switch cases}}
     case A:
       break;
   }
@@ -155,7 +155,7 @@
     case C:
       break;
   }
-  switch(a) { //expected-warning{{enumeration value 'B' not handled in switch}}
+  switch(a) { //expected-warning{{enumeration value 'B' not handled in switch}} expected-note {{add missing switch cases}}
     case A:
       break;
   }
@@ -202,13 +202,13 @@
     B,
     C
   } a;
-  switch(a) { //expected-warning{{enumeration value 'A' not handled in switch}}
+  switch(a) { //expected-warning{{enumeration value 'A' not handled in switch}} expected-note {{add missing switch cases}}
     case B:
     case C:
       break;
   }
 
-  switch(a) { //expected-warning{{enumeration value 'A' not explicitly handled in switch}}
+  switch(a) { //expected-warning{{enumeration value 'A' not explicitly handled in switch}} expected-note {{add missing switch cases}}
     case B:
     case C:
       break;
@@ -238,7 +238,7 @@
 } my_type_t;
 
 int test13(my_type_t t) {
-  switch(t) { // expected-warning{{enumeration value 'val3' not handled in switch}}
+  switch(t) { // expected-warning{{enumeration value 'val3' not handled in switch}} expected-note {{add missing switch cases}}
   case val1:
     return 1;
   case val2:
diff --git a/test/SemaCXX/array-bounds.cpp b/test/SemaCXX/array-bounds.cpp
index 8ae92e7..92e8dd4 100644
--- a/test/SemaCXX/array-bounds.cpp
+++ b/test/SemaCXX/array-bounds.cpp
@@ -164,7 +164,7 @@
 static enum enumB myVal = enumB_X;
 void test_nested_switch() {
   switch (enumA_E) { // expected-warning {{no case matching constant}}
-    switch (myVal) { // expected-warning {{enumeration values 'enumB_X' and 'enumB_Z' not handled in switch}}
+    switch (myVal) { // expected-warning {{enumeration values 'enumB_X' and 'enumB_Z' not handled in switch}} expected-note {{add missing switch cases}}
       case enumB_Y: ;
     }
   }
diff --git a/test/SemaCXX/cxx1y-init-captures.cpp b/test/SemaCXX/cxx1y-init-captures.cpp
index d681954..4b82452 100644
--- a/test/SemaCXX/cxx1y-init-captures.cpp
+++ b/test/SemaCXX/cxx1y-init-captures.cpp
@@ -206,3 +206,11 @@
   find(weight); // expected-note {{in instantiation of function template specialization}}
 }
 }
+
+namespace init_capture_undeclared_identifier {
+  auto a = [x = y]{}; // expected-error{{use of undeclared identifier 'y'}}
+
+  int typo_foo; // expected-note 2 {{'typo_foo' declared here}}
+  auto b = [x = typo_boo]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
+  auto c = [x(typo_boo)]{}; // expected-error{{use of undeclared identifier 'typo_boo'; did you mean 'typo_foo'}}
+}
diff --git a/test/SemaCXX/cxx1z-init-statement-template.cpp b/test/SemaCXX/cxx1z-init-statement-template.cpp
new file mode 100644
index 0000000..cedd2c7
--- /dev/null
+++ b/test/SemaCXX/cxx1z-init-statement-template.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -std=c++1z -verify -emit-llvm-only %s
+// expected-no-diagnostics
+
+// rdar://problem/33888545
+template <unsigned int BUFFER_SIZE> class Buffer {};
+
+class A {
+public:
+  int status;
+};
+
+template <unsigned int N> A parse(Buffer<N> buffer);
+
+template<unsigned int N>
+void init_in_if(Buffer<N> buffer) {
+  if (A a = parse(buffer); a.status > 0) {
+  }
+}
+
+template<unsigned int N>
+void init_in_switch(Buffer<N> buffer) {
+  switch (A a = parse(buffer); a.status) {
+    default:
+      break;
+  }
+}
+
+void test() {
+  Buffer<10> buffer;
+  init_in_if(buffer);
+  init_in_switch(buffer);
+}
diff --git a/test/SemaCXX/enum-attr.cpp b/test/SemaCXX/enum-attr.cpp
index 7726aff..92027ae 100644
--- a/test/SemaCXX/enum-attr.cpp
+++ b/test/SemaCXX/enum-attr.cpp
@@ -27,7 +27,7 @@
 void test() {
   enum Enum t0;
 
-  switch (t0) { // expected-warning{{enumeration value 'A1' not handled in switch}}
+  switch (t0) { // expected-warning{{enumeration value 'A1' not handled in switch}} expected-note {{add missing switch cases}}
   case A0: break;
   case 16: break; // expected-warning{{case value not in enumerated type}}
   }
@@ -40,7 +40,7 @@
 
   enum EnumClosed t1;
 
-  switch (t1) { // expected-warning{{enumeration value 'B1' not handled in switch}}
+  switch (t1) { // expected-warning{{enumeration value 'B1' not handled in switch}} expected-note {{add missing switch cases}}
   case B0: break;
   case 16: break; // expected-warning{{case value not in enumerated type}}
   }
@@ -53,7 +53,7 @@
 
   enum EnumOpen t2;
 
-  switch (t2) { // expected-warning{{enumeration value 'C1' not handled in switch}}
+  switch (t2) { // expected-warning{{enumeration value 'C1' not handled in switch}} expected-note {{add missing switch cases}}
   case C0: break;
   case 16: break;
   }
@@ -66,7 +66,7 @@
 
   enum EnumFlag t3;
 
-  switch (t3) { // expected-warning{{enumeration value 'D1' not handled in switch}}
+  switch (t3) { // expected-warning{{enumeration value 'D1' not handled in switch}} expected-note {{add missing switch cases}}
   case D0: break;
   case 9: break;
   case 16: break; // expected-warning{{case value not in enumerated type}}
@@ -80,7 +80,7 @@
 
   enum EnumFlagClosed t4;
 
-  switch (t4) { // expected-warning{{enumeration value 'E1' not handled in switch}}
+  switch (t4) { // expected-warning{{enumeration value 'E1' not handled in switch}} expected-note {{add missing switch cases}}
   case E0: break;
   case 9: break;
   case 16: break; // expected-warning{{case value not in enumerated type}}
@@ -94,7 +94,7 @@
 
   enum EnumFlagOpen t5;
 
-  switch (t5) { // expected-warning{{enumeration value 'F1' not handled in switch}}
+  switch (t5) { // expected-warning{{enumeration value 'F1' not handled in switch}} expected-note {{add missing switch cases}}
   case F0: break;
   case 9: break;
   case 16: break;
diff --git a/test/SemaCXX/enum.cpp b/test/SemaCXX/enum.cpp
index 6b0824b..cfe5760 100644
--- a/test/SemaCXX/enum.cpp
+++ b/test/SemaCXX/enum.cpp
@@ -110,3 +110,13 @@
 // expected-warning@-2 {{not an integral constant expression}}
 // expected-note@-3 {{value 28958703552 is outside the range of representable values}}
 #endif
+
+// PR28903
+struct PR28903 {
+  enum {
+    PR28903_A = (enum { // expected-error-re {{'PR28903::(anonymous enum at {{.*}})' cannot be defined in an enumeration}}
+      PR28903_B,
+      PR28903_C = PR28903_B
+    })
+  };
+};
diff --git a/test/SemaCXX/microsoft-varargs.cpp b/test/SemaCXX/microsoft-varargs.cpp
index 35f31a9..5b0f90e 100644
--- a/test/SemaCXX/microsoft-varargs.cpp
+++ b/test/SemaCXX/microsoft-varargs.cpp
@@ -20,3 +20,8 @@
   return __builtin_va_arg(ap, int);
 }
 
+void test___va_start_ignore_const(const char *format, ...) {
+  va_list args;
+  ((void)(__va_start(&args, (&const_cast<char &>(reinterpret_cast<const volatile char &>(format))), ((sizeof(format) + 4 - 1) & ~(4 - 1)), (&const_cast<char &>(reinterpret_cast<const volatile char &>(format))))));
+}
+
diff --git a/test/SemaCXX/scope-check.cpp b/test/SemaCXX/scope-check.cpp
index 9e00332..256f01b 100644
--- a/test/SemaCXX/scope-check.cpp
+++ b/test/SemaCXX/scope-check.cpp
@@ -193,7 +193,7 @@
 
   bool recurse() {
     MyEnum K;
-    switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}}
+    switch (K) { // expected-warning {{enumeration value 'something_invalid' not handled in switch}} expected-note {{add missing switch cases}}
     case something_valid:
     case what_am_i_thinking: // expected-error {{use of undeclared identifier}}
       int *X = 0;
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index 2d78f06..910e2c1 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -411,7 +411,7 @@
 
 void testAccess() {
   Figure obj;
-  switch (obj.type()) {  // expected-warning {{enumeration values 'SQUARE', 'TRIANGLE', and 'CIRCLE' not handled in switch}}
+  switch (obj.type()) {  // expected-warning {{enumeration values 'SQUARE', 'TRIANGLE', and 'CIRCLE' not handled in switch}} expected-note {{add missing switch cases}}
   case SQUARE:  // expected-error-re {{use of undeclared identifier 'SQUARE'{{$}}}}
   case TRIANGLE:  // expected-error-re {{use of undeclared identifier 'TRIANGLE'{{$}}}}
   case CIRCE:  // expected-error-re {{use of undeclared identifier 'CIRCE'{{$}}}}
diff --git a/test/SemaCXX/unavailable_aligned_allocation.cpp b/test/SemaCXX/unavailable_aligned_allocation.cpp
index 2ae5d2e..2000e0b 100644
--- a/test/SemaCXX/unavailable_aligned_allocation.cpp
+++ b/test/SemaCXX/unavailable_aligned_allocation.cpp
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.12.0 -fexceptions -faligned-allocation -faligned-alloc-unavailable -std=c++14 -verify %s
+// RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DIOS %s
+// RUN: %clang_cc1 -triple arm64-apple-ios10.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
+// RUN: %clang_cc1 -triple arm64-apple-tvos10.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DTVOS %s
+// RUN: %clang_cc1 -triple arm64-apple-tvos10.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
+// RUN: %clang_cc1 -triple armv7k-apple-watchos3.0.0 -fexceptions -faligned-alloc-unavailable -std=c++1z -verify -DWATCHOS %s
+// RUN: %clang_cc1 -triple armv7k-apple-watchos3.0.0 -fexceptions -std=c++1z -verify -DNO_ERRORS %s
 
 namespace std {
   typedef decltype(sizeof(0)) size_t;
@@ -56,44 +62,68 @@
 #ifdef NO_ERRORS
 // expected-no-diagnostics
 #else
-// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}}
+// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
 // expected-note@-17 {{if you supply your own aligned allocation functions}}
-// expected-error@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-18 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
 // expected-note@-19 {{if you supply your own aligned allocation functions}}
 
-// expected-error@-20 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}}
+// expected-error@-20 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
 // expected-note@-21 {{if you supply your own aligned allocation functions}}
-// expected-error@-22 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-22 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
 // expected-note@-23 {{if you supply your own aligned allocation functions}}
 
-// expected-error@-24 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-24 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
 // expected-note@-25 {{if you supply your own aligned allocation functions}}
 
-// expected-error@-26 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}}
+// expected-error@-26 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}}
 // expected-note@-27 {{if you supply your own aligned allocation functions}}
-// expected-error@-28 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}}
+// expected-error@-28 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}}
 // expected-note@-29 {{if you supply your own aligned allocation functions}}
 
-// expected-error@-29 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}}
+// expected-error@-29 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
 // expected-note@-30 {{if you supply your own aligned allocation functions}}
-// expected-error@-31 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-31 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
 // expected-note@-32 {{if you supply your own aligned allocation functions}}
 
-// expected-error@-33 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' possibly unavailable on}}
+// expected-error@-33 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on}}
 // expected-note@-34 {{if you supply your own aligned allocation functions}}
-// expected-error@-35 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-35 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
 // expected-note@-36 {{if you supply your own aligned allocation functions}}
 
-// expected-error@-37 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' possibly unavailable on}}
+// expected-error@-37 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on}}
 // expected-note@-38 {{if you supply your own aligned allocation functions}}
 
-// expected-error@-39 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}}
+// expected-error@-39 {{aligned allocation function of type 'void *(std::size_t, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}}
 // expected-note@-40 {{if you supply your own aligned allocation functions}}
-// expected-error@-41 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' possibly unavailable on}}
+// expected-error@-41 {{aligned deallocation function of type 'void (void *, std::align_val_t, const std::nothrow_t &) noexcept' is only available on}}
 // expected-note@-42 {{if you supply your own aligned allocation functions}}
 
 #endif
 
+void testOveralignedCheckOS() {
+  auto *p = new OveralignedS;
+}
+
+#ifdef NO_ERRORS
+// expected-no-diagnostics
+#else
+#if defined(IOS)
+// expected-error@-7 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on iOS 11 or newer}}
+// expected-error@-8 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on iOS 11 or newer}}}
+#elif defined(TVOS)
+// expected-error@-10 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on tvOS 11 or newer}}}
+// expected-error@-11 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on tvOS 11 or newer}}}
+#elif defined(WATCHOS)
+// expected-error@-13 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on watchOS 4 or newer}}}
+// expected-error@-14 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on watchOS 4 or newer}}}
+#else
+// expected-error@-16 {{aligned allocation function of type 'void *(unsigned long, enum std::align_val_t)' is only available on macOS 10.13 or newer}}}
+// expected-error@-17 {{aligned deallocation function of type 'void (void *, enum std::align_val_t) noexcept' is only available on macOS 10.13 or newer}}}
+#endif
+
+// expected-note@-20 2 {{if you supply your own aligned allocation functions}}
+#endif
+
 // No errors if user-defined aligned allocation functions are available.
 void *operator new(std::size_t __sz, std::align_val_t) {
   static char array[256];
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..62a20d1
--- /dev/null
+++ b/test/SemaObjC/attr-swift_newtype.c
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+// RUN: not %clang_cc1 -ast-dump %s | FileCheck %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 T5;
+typedef int T5 __attribute__((swift_wrapper(struct)));
+typedef int T5;
+// CHECK-LABEL: TypedefDecl {{.+}} T5 'int'
+// CHECK-NEXT: BuiltinType {{.+}} 'int'
+// CHECK-NEXT: TypedefDecl {{.+}} T5 'int'
+// CHECK-NEXT: BuiltinType {{.+}} 'int'
+// CHECK-NEXT: SwiftNewtypeAttr {{.+}} NK_Struct
+// CHECK-NEXT: TypedefDecl {{.+}} T5 'int'
+// CHECK-NEXT: BuiltinType {{.+}} 'int'
+// CHECK-NEXT: SwiftNewtypeAttr {{.+}} NK_Struct
+
+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/default-synthesize-1.m b/test/SemaObjC/default-synthesize-1.m
index 731aa86..573434b 100644
--- a/test/SemaObjC/default-synthesize-1.m
+++ b/test/SemaObjC/default-synthesize-1.m
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wobjc-missing-property-synthesis -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -fsyntax-only -Wobjc-missing-property-synthesis -verify -Wno-objc-root-class -triple=x86_64-apple-macos10.10 %s
 // rdar://11295716
 
 @interface NSObject 
@@ -141,3 +141,17 @@
     return _description; // expected-error {{use of undeclared identifier '_description'}}
 }
 @end
+
+@interface DontWarnOnUnavailable
+
+// No warning expected:
+@property (nonatomic, readonly) int un1 __attribute__((unavailable));
+@property (readwrite) int un2 __attribute__((availability(macos, unavailable)));
+
+@property (readwrite) int un3 __attribute__((availability(ios, unavailable))); // expected-warning {{auto property synthesis is synthesizing property not explicitly synthesized}}
+
+@end
+
+@implementation DontWarnOnUnavailable // expected-note {{detected while default synthesizing properties in class implementation}}
+
+@end
diff --git a/test/SemaObjC/format-strings-objc.m b/test/SemaObjC/format-strings-objc.m
index 767d5ac..e44bd3c 100644
--- a/test/SemaObjC/format-strings-objc.m
+++ b/test/SemaObjC/format-strings-objc.m
@@ -265,6 +265,21 @@
   NSLog(@"%2$[tt]@ %1$[tt]s", @"Foo", @"Bar"); // expected-warning {{object format flags cannot be used with 's' conversion specifier}}
 }
 
+// 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'}}
+
+  __builtin_os_log_format(buf, @"%{private}s", pc);
+  __builtin_os_log_format(buf, @"%@", nss);
+}
+
 // rdar://23622446
 @interface RD23622446_Tester: NSObject
 
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/typo-correction.m b/test/SemaObjC/typo-correction.m
index f19ec1a..47e0ab0 100644
--- a/test/SemaObjC/typo-correction.m
+++ b/test/SemaObjC/typo-correction.m
@@ -51,3 +51,23 @@
 }
 @end
 
+// rdar://problem/33102722
+// Typo correction for a property when it has as correction candidates
+// synthesized ivar and a class name, both at the same edit distance.
+@class TypoCandidate;
+
+__attribute__ (( __objc_root_class__ ))
+@interface PropertyType
+@property int x;
+@end
+
+__attribute__ (( __objc_root_class__ ))
+@interface InterfaceC
+@property(assign) PropertyType *typoCandidate; // expected-note {{'_typoCandidate' declared here}}
+@end
+
+@implementation InterfaceC
+-(void)method {
+  typoCandidate.x = 0; // expected-error {{use of undeclared identifier 'typoCandidate'; did you mean '_typoCandidate'?}}
+}
+@end
diff --git a/test/SemaObjCXX/typo-correction.mm b/test/SemaObjCXX/typo-correction.mm
index 5e33bfb..8dcda79 100644
--- a/test/SemaObjCXX/typo-correction.mm
+++ b/test/SemaObjCXX/typo-correction.mm
@@ -36,3 +36,22 @@
   float a = ((InvalidNameInIvarAndPropertyBase*)node)->_a; // expected-error {{use of undeclared identifier 'node'}}
   float b = ((InvalidNameInIvarAndPropertyBase*)node)._b; // expected-error {{use of undeclared identifier 'node'}}
 }
+
+// rdar://problem/33102722
+// Typo correction for a property when it has as correction candidates
+// synthesized ivar and a class name, both at the same edit distance.
+@class TypoCandidate;
+
+@interface PropertyType : NSObject
+@property int x;
+@end
+
+@interface InterfaceC : NSObject
+@property(assign) PropertyType *typoCandidate; // expected-note {{'_typoCandidate' declared here}}
+@end
+
+@implementation InterfaceC
+-(void)method {
+  typoCandidate.x = 0; // expected-error {{use of undeclared identifier 'typoCandidate'; did you mean '_typoCandidate'?}}
+}
+@end
diff --git a/test/SemaTemplate/crash-unparsed-exception.cpp b/test/SemaTemplate/crash-unparsed-exception.cpp
index 1226b35..3137d3f 100644
--- a/test/SemaTemplate/crash-unparsed-exception.cpp
+++ b/test/SemaTemplate/crash-unparsed-exception.cpp
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -fcxx-exceptions -fexceptions %s
+// expected-no-diagnostics
 
 struct A {
   virtual ~A();
@@ -11,7 +12,7 @@
     ~D() throw();
   };
   struct E : A {
-    D<int> d; //expected-error{{exception specification is not available until end of class definition}}
+    D<int> d;
   };
-  B<int> b; //expected-note{{in instantiation of template class 'B<int>' requested here}}
+  B<int> b;
 };
diff --git a/test/SemaTemplate/default-arguments-cxx0x.cpp b/test/SemaTemplate/default-arguments-cxx0x.cpp
index d9fa2b4..c24ed12 100644
--- a/test/SemaTemplate/default-arguments-cxx0x.cpp
+++ b/test/SemaTemplate/default-arguments-cxx0x.cpp
@@ -87,3 +87,30 @@
     A<1> m_target;
   };
 }
+
+// rdar://problem/34167492
+// Template B is instantiated during checking if defaulted A copy constructor
+// is constexpr. For this we check if S<int> copy constructor is constexpr. And
+// for this we check S constructor template with default argument that mentions
+// template B. In  turn, template instantiation triggers checking defaulted
+// members exception spec. The problem is that it checks defaulted members not
+// for instantiated class only, but all defaulted members so far. In this case
+// we try to check exception spec for A default constructor which requires
+// initializer for the field _a. But initializers are added after constexpr
+// check so we reject the code because cannot find _a initializer.
+namespace rdar34167492 {
+  template <typename T> struct B { using type = bool; };
+
+  template <typename T> struct S {
+    S() noexcept;
+
+    template <typename U, typename B<U>::type = true>
+    S(const S<U>&) noexcept;
+  };
+
+  class A {
+    A() noexcept = default;
+    A(const A&) noexcept = default;
+    S<int> _a{};
+  };
+}
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 4976332..662b853 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -9,6 +9,7 @@
 add_clang_subdirectory(clang-offload-bundler)
 
 add_clang_subdirectory(c-index-test)
+add_clang_subdirectory(IndexStore)
 
 add_clang_subdirectory(clang-rename)
 
@@ -32,3 +33,6 @@
 
 # libclang may require clang-tidy in clang-tools-extra.
 add_clang_subdirectory(libclang)
+
+add_clang_subdirectory(clang-refactor-test)
+
diff --git a/tools/IndexStore/CMakeLists.txt b/tools/IndexStore/CMakeLists.txt
new file mode 100644
index 0000000..8ad6499
--- /dev/null
+++ b/tools/IndexStore/CMakeLists.txt
@@ -0,0 +1,94 @@
+include(CheckIncludeFiles)
+
+set(SOURCES
+  IndexStore.cpp
+
+  ADDITIONAL_HEADERS
+  ../../include/indexstore/indexstore.h
+  ../../include/indexstore/IndexStoreCXX.h
+  )
+
+set(LIBS
+  clangDirectoryWatcher
+  clangIndex
+)
+
+set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/IndexStore.exports)
+
+set(ENABLE_SHARED SHARED)
+
+if(WIN32)
+  set(output_name "libIndexStore")
+else()
+  set(output_name "IndexStore")
+endif()
+
+# FIXME: needs to be ported to non-Apple platforms.
+if(APPLE)
+
+add_clang_library(IndexStore ${ENABLE_SHARED} ${ENABLE_STATIC}
+  OUTPUT_NAME ${output_name}
+  ${SOURCES}
+
+  LINK_LIBS
+  ${LIBS}
+
+  LINK_COMPONENTS
+  ${LLVM_TARGETS_TO_BUILD}
+  Core
+  Support
+  )
+
+set(INDEXSTORE_LIBRARY_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
+
+if(ENABLE_SHARED)
+  if(WIN32)
+    set_target_properties(IndexStore
+      PROPERTIES
+      VERSION ${INDEXSTORE_LIBRARY_VERSION}
+      DEFINE_SYMBOL _CINDEX_LIB_)
+  elseif(APPLE)
+    set(INDEXSTORE_LINK_FLAGS " -Wl,-compatibility_version -Wl,1")
+    set(INDEXSTORE_LINK_FLAGS "${INDEXSTORE_LINK_FLAGS} -Wl,-current_version -Wl,${INDEXSTORE_LIBRARY_VERSION}")
+
+    check_include_files("CoreServices/CoreServices.h" HAVE_CORESERVICES_H)
+    if(HAVE_CORESERVICES_H)
+      set(INDEXSTORE_LINK_FLAGS "${INDEXSTORE_LINK_FLAGS} -framework CoreServices")
+    endif()
+
+    set_property(TARGET IndexStore APPEND_STRING PROPERTY
+                 LINK_FLAGS ${INDEXSTORE_LINK_FLAGS})
+  else()
+    set_target_properties(IndexStore
+      PROPERTIES
+      VERSION ${INDEXSTORE_LIBRARY_VERSION}
+      DEFINE_SYMBOL _CINDEX_LIB_)
+  endif()
+endif()
+
+if (LLVM_INSTALL_TOOLCHAIN_ONLY)
+  install(TARGETS IndexStore
+    COMPONENT IndexStore
+    LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+    ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
+    RUNTIME DESTINATION bin)
+
+  if (NOT CMAKE_CONFIGURATION_TYPES)
+    add_custom_target(install-IndexStore
+                      DEPENDS IndexStore
+                      COMMAND "${CMAKE_COMMAND}"
+                              -DCMAKE_INSTALL_COMPONENT=IndexStore
+                              -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
+  endif()
+endif()
+
+set(INDEXSTORE_HEADERS_INSTALL_DESTINATION "local/include")
+
+install(DIRECTORY ../../include/indexstore
+  COMPONENT IndexStore
+  DESTINATION "${INDEXSTORE_HEADERS_INSTALL_DESTINATION}"
+  FILES_MATCHING
+  PATTERN "*.h"
+  PATTERN ".svn" EXCLUDE
+  )
+endif()
diff --git a/tools/IndexStore/IndexStore.cpp b/tools/IndexStore/IndexStore.cpp
new file mode 100644
index 0000000..4226524
--- /dev/null
+++ b/tools/IndexStore/IndexStore.cpp
@@ -0,0 +1,647 @@
+//===- IndexStore.cpp - Index store API -----------------------------------===//
+//
+//                     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 API for the index store.
+//
+//===----------------------------------------------------------------------===//
+
+#include "indexstore/indexstore.h"
+#include "clang/Index/IndexDataStore.h"
+#include "clang/Index/IndexDataStoreSymbolUtils.h"
+#include "clang/Index/IndexRecordReader.h"
+#include "clang/Index/IndexUnitReader.h"
+#include "clang/Index/IndexUnitWriter.h"
+#include "clang/DirectoryWatcher/DirectoryWatcher.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Chrono.h"
+#include <Block.h>
+
+using namespace clang;
+using namespace clang::index;
+using namespace llvm;
+
+static indexstore_string_ref_t toIndexStoreString(StringRef str) {
+  return indexstore_string_ref_t{ str.data(), str.size() };
+}
+
+static timespec toTimeSpec(sys::TimePoint<> tp) {
+  std::chrono::seconds sec = std::chrono::time_point_cast<std::chrono::seconds>(
+                 tp).time_since_epoch();
+  std::chrono::nanoseconds nsec =
+    std::chrono::time_point_cast<std::chrono::nanoseconds>(tp - sec)
+      .time_since_epoch();
+  timespec ts;
+  ts.tv_sec = sec.count();
+  ts.tv_nsec = nsec.count();
+  return ts;
+}
+
+namespace {
+
+struct IndexStoreError {
+  std::string Error;
+};
+
+} // anonymous namespace
+
+const char *
+indexstore_error_get_description(indexstore_error_t err) {
+  return static_cast<IndexStoreError*>(err)->Error.c_str();
+}
+
+void
+indexstore_error_dispose(indexstore_error_t err) {
+  delete static_cast<IndexStoreError*>(err);
+}
+
+unsigned
+indexstore_format_version(void) {
+  return IndexDataStore::getFormatVersion();
+}
+
+indexstore_t
+indexstore_store_create(const char *store_path, indexstore_error_t *c_error) {
+  std::unique_ptr<IndexDataStore> store;
+  std::string error;
+  store = IndexDataStore::create(store_path, error);
+  if (!store) {
+    if (c_error)
+      *c_error = new IndexStoreError{ error };
+    return nullptr;
+  }
+  return store.release();
+}
+
+void
+indexstore_store_dispose(indexstore_t store) {
+  delete static_cast<IndexDataStore*>(store);
+}
+
+#if INDEXSTORE_HAS_BLOCKS
+bool
+indexstore_store_units_apply(indexstore_t c_store, unsigned sorted,
+                            bool(^applier)(indexstore_string_ref_t unit_name)) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  return store->foreachUnitName(sorted, [&](StringRef unitName) -> bool {
+    return applier(toIndexStoreString(unitName));
+  });
+}
+
+size_t
+indexstore_unit_event_notification_get_events_count(indexstore_unit_event_notification_t c_evtnote) {
+  auto *evtnote = static_cast<IndexDataStore::UnitEventNotification*>(c_evtnote);
+  return evtnote->Events.size();
+}
+
+indexstore_unit_event_t
+indexstore_unit_event_notification_get_event(indexstore_unit_event_notification_t c_evtnote, size_t index) {
+  auto *evtnote = static_cast<IndexDataStore::UnitEventNotification*>(c_evtnote);
+  return (indexstore_unit_event_t)&evtnote->Events[index];
+}
+
+bool
+indexstore_unit_event_notification_is_initial(indexstore_unit_event_notification_t c_evtnote) {
+  auto *evtnote = static_cast<IndexDataStore::UnitEventNotification*>(c_evtnote);
+  return evtnote->IsInitial;
+}
+
+indexstore_unit_event_kind_t
+indexstore_unit_event_get_kind(indexstore_unit_event_t c_evt) {
+  auto *evt = static_cast<IndexDataStore::UnitEvent*>(c_evt);
+  indexstore_unit_event_kind_t k;
+  switch (evt->Kind) {
+    case IndexDataStore::UnitEventKind::Added:
+      k = INDEXSTORE_UNIT_EVENT_ADDED; break;
+    case IndexDataStore::UnitEventKind::Removed:
+      k = INDEXSTORE_UNIT_EVENT_REMOVED; break;
+    case IndexDataStore::UnitEventKind::Modified:
+      k = INDEXSTORE_UNIT_EVENT_MODIFIED; break;
+    case IndexDataStore::UnitEventKind::DirectoryDeleted:
+      k = INDEXSTORE_UNIT_EVENT_DIRECTORY_DELETED; break;
+  }
+  return k;
+}
+
+indexstore_string_ref_t
+indexstore_unit_event_get_unit_name(indexstore_unit_event_t c_evt) {
+  auto *evt = static_cast<IndexDataStore::UnitEvent*>(c_evt);
+  return toIndexStoreString(evt->UnitName);
+}
+
+timespec
+indexstore_unit_event_get_modification_time(indexstore_unit_event_t c_evt) {
+  auto *evt = static_cast<IndexDataStore::UnitEvent*>(c_evt);
+  return evt->ModTime;
+}
+
+void
+indexstore_store_set_unit_event_handler(indexstore_t c_store,
+                                    indexstore_unit_event_handler_t blk_handler) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  if (!blk_handler) {
+    store->setUnitEventHandler(nullptr);
+    return;
+  }
+
+  class BlockWrapper {
+    indexstore_unit_event_handler_t blk_handler;
+  public:
+    BlockWrapper(indexstore_unit_event_handler_t handler) {
+      blk_handler = Block_copy(handler);
+    }
+    BlockWrapper(const BlockWrapper &other) {
+      blk_handler = Block_copy(other.blk_handler);
+    }
+    ~BlockWrapper() {
+      Block_release(blk_handler);
+    }
+
+    void operator()(indexstore_unit_event_notification_t evt_note) const {
+      blk_handler(evt_note);
+    }
+  };
+
+  BlockWrapper handler(blk_handler);
+
+  store->setUnitEventHandler([handler](IndexDataStore::UnitEventNotification evtNote) {
+    handler(&evtNote);
+  });
+}
+#endif
+
+bool
+indexstore_store_start_unit_event_listening(indexstore_t c_store,
+                                            indexstore_unit_event_listen_options_t *client_opts,
+                                            size_t listen_options_struct_size,
+                                            indexstore_error_t *c_error) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  indexstore_unit_event_listen_options_t listen_opts;
+  memset(&listen_opts, 0, sizeof(listen_opts));
+  unsigned clientOptSize = listen_options_struct_size < sizeof(listen_opts)
+                             ? listen_options_struct_size : sizeof(listen_opts);
+  memcpy(&listen_opts, client_opts, clientOptSize);
+
+  std::string error;
+  auto createFn = [](StringRef Path, AbstractDirectoryWatcher::EventReceiver Receiver, bool waitInitialSync, std::string &Error)
+      -> std::unique_ptr<AbstractDirectoryWatcher> {
+    return DirectoryWatcher::create(Path, std::move(Receiver), waitInitialSync, Error);
+  };
+  bool err = store->startEventListening(createFn, listen_opts.wait_initial_sync, error);
+  if (err && c_error)
+    *c_error = new IndexStoreError{ error };
+  return err;
+}
+
+void
+indexstore_store_stop_unit_event_listening(indexstore_t c_store) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  store->stopEventListening();
+}
+
+void
+indexstore_store_discard_unit(indexstore_t c_store, const char *unit_name) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  store->discardUnit(unit_name);
+}
+
+void
+indexstore_store_discard_record(indexstore_t c_store, const char *record_name) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  store->discardRecord(record_name);
+}
+
+void
+indexstore_store_purge_stale_data(indexstore_t c_store) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  store->purgeStaleData();
+}
+
+indexstore_symbol_kind_t
+indexstore_symbol_get_kind(indexstore_symbol_t sym) {
+  return getIndexStoreKind(static_cast<IndexRecordDecl *>(sym)->SymInfo.Kind);
+}
+
+indexstore_symbol_subkind_t
+indexstore_symbol_get_subkind(indexstore_symbol_t sym) {
+  return getIndexStoreSubKind(static_cast<IndexRecordDecl *>(sym)->SymInfo.SubKind);
+}
+
+indexstore_symbol_language_t
+indexstore_symbol_get_language(indexstore_symbol_t sym) {
+  return getIndexStoreLang(static_cast<IndexRecordDecl *>(sym)->SymInfo.Lang);
+}
+
+uint64_t
+indexstore_symbol_get_properties(indexstore_symbol_t sym) {
+  return getIndexStoreProperties(static_cast<IndexRecordDecl *>(sym)->SymInfo.Properties);
+}
+
+uint64_t
+indexstore_symbol_get_roles(indexstore_symbol_t sym) {
+  return getIndexStoreRoles(static_cast<IndexRecordDecl *>(sym)->Roles);
+}
+
+uint64_t
+indexstore_symbol_get_related_roles(indexstore_symbol_t sym) {
+  return getIndexStoreRoles(static_cast<IndexRecordDecl *>(sym)->RelatedRoles);
+}
+
+indexstore_string_ref_t
+indexstore_symbol_get_name(indexstore_symbol_t sym) {
+  auto *D = static_cast<IndexRecordDecl*>(sym);
+  return toIndexStoreString(D->Name);
+}
+
+indexstore_string_ref_t
+indexstore_symbol_get_usr(indexstore_symbol_t sym) {
+  auto *D = static_cast<IndexRecordDecl*>(sym);
+  return toIndexStoreString(D->USR);
+}
+
+indexstore_string_ref_t
+indexstore_symbol_get_codegen_name(indexstore_symbol_t sym) {
+  auto *D = static_cast<IndexRecordDecl*>(sym);
+  return toIndexStoreString(D->CodeGenName);
+}
+
+uint64_t
+indexstore_symbol_relation_get_roles(indexstore_symbol_relation_t sym_rel) {
+  return getIndexStoreRoles(static_cast<IndexRecordRelation *>(sym_rel)->Roles);
+}
+
+indexstore_symbol_t
+indexstore_symbol_relation_get_symbol(indexstore_symbol_relation_t sym_rel) {
+  return (indexstore_symbol_t)static_cast<IndexRecordRelation*>(sym_rel)->Dcl;
+}
+
+indexstore_symbol_t
+indexstore_occurrence_get_symbol(indexstore_occurrence_t occur) {
+  return (indexstore_symbol_t)static_cast<IndexRecordOccurrence*>(occur)->Dcl;
+}
+
+#if INDEXSTORE_HAS_BLOCKS
+bool
+indexstore_occurrence_relations_apply(indexstore_occurrence_t occur,
+                      bool(^applier)(indexstore_symbol_relation_t symbol_rel)) {
+  auto *recOccur = static_cast<IndexRecordOccurrence*>(occur);
+  for (auto &rel : recOccur->Relations) {
+    if (!applier(&rel))
+      return false;
+  }
+  return true;
+}
+#endif
+
+uint64_t
+indexstore_occurrence_get_roles(indexstore_occurrence_t occur) {
+  return static_cast<IndexRecordOccurrence*>(occur)->Roles;
+}
+
+void
+indexstore_occurrence_get_line_col(indexstore_occurrence_t occur,
+                              unsigned *line, unsigned *column) {
+  auto *recOccur = static_cast<IndexRecordOccurrence*>(occur);
+  if (line)
+    *line = recOccur->Line;
+  if (column)
+    *column = recOccur->Column;
+}
+
+typedef void *indexstore_record_reader_t;
+
+indexstore_record_reader_t
+indexstore_record_reader_create(indexstore_t c_store, const char *record_name,
+                                indexstore_error_t *c_error) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  std::unique_ptr<IndexRecordReader> reader;
+  std::string error;
+  reader = IndexRecordReader::createWithRecordFilename(record_name,
+                                                       store->getFilePath(),
+                                                       error);
+  if (!reader) {
+    if (c_error)
+      *c_error = new IndexStoreError{ error };
+    return nullptr;
+  }
+  return reader.release();
+}
+
+void
+indexstore_record_reader_dispose(indexstore_record_reader_t rdr) {
+  auto *reader = static_cast<IndexRecordReader *>(rdr);
+  delete reader;
+}
+
+#if INDEXSTORE_HAS_BLOCKS
+/// Goes through the symbol data and passes symbols to \c receiver, for the
+/// symbol data that \c filter returns true on.
+///
+/// This allows allocating memory only for the record symbols that the caller is
+/// interested in.
+bool
+indexstore_record_reader_search_symbols(indexstore_record_reader_t rdr,
+    bool(^filter)(indexstore_symbol_t symbol, bool *stop),
+    void(^receiver)(indexstore_symbol_t symbol)) {
+  auto *reader = static_cast<IndexRecordReader *>(rdr);
+
+  auto filterFn = [&](const IndexRecordDecl &D) -> IndexRecordReader::DeclSearchReturn {
+    bool stop = false;
+    bool accept = filter((indexstore_symbol_t)&D, &stop);
+    return { accept, !stop };
+  };
+  auto receiverFn = [&](const IndexRecordDecl *D) {
+    receiver((indexstore_symbol_t)D);
+  };
+
+  return reader->searchDecls(filterFn, receiverFn);
+}
+
+bool
+indexstore_record_reader_symbols_apply(indexstore_record_reader_t rdr,
+                                        bool nocache,
+                                   bool(^applier)(indexstore_symbol_t symbol)) {
+  auto *reader = static_cast<IndexRecordReader *>(rdr);
+  auto receiverFn = [&](const IndexRecordDecl *D) -> bool {
+    return applier((indexstore_symbol_t)D);
+  };
+  return reader->foreachDecl(nocache, receiverFn);
+}
+
+bool
+indexstore_record_reader_occurrences_apply(indexstore_record_reader_t rdr,
+                                bool(^applier)(indexstore_occurrence_t occur)) {
+  auto *reader = static_cast<IndexRecordReader *>(rdr);
+  auto receiverFn = [&](const IndexRecordOccurrence &RO) -> bool {
+    return applier((indexstore_occurrence_t)&RO);
+  };
+  return reader->foreachOccurrence(receiverFn);
+}
+
+bool
+indexstore_record_reader_occurrences_in_line_range_apply(indexstore_record_reader_t rdr,
+                                                         unsigned line_start,
+                                                         unsigned line_count,
+                                bool(^applier)(indexstore_occurrence_t occur)) {
+  auto *reader = static_cast<IndexRecordReader *>(rdr);
+  auto receiverFn = [&](const IndexRecordOccurrence &RO) -> bool {
+    return applier((indexstore_occurrence_t)&RO);
+  };
+  return reader->foreachOccurrenceInLineRange(line_start, line_count, receiverFn);
+}
+
+/// \param symbols if non-zero \c symbols_count, indicates the list of symbols
+/// that we want to get occurrences for. An empty array indicates that we want
+/// occurrences for all symbols.
+/// \param related_symbols Same as \c symbols but for related symbols.
+bool
+indexstore_record_reader_occurrences_of_symbols_apply(indexstore_record_reader_t rdr,
+        indexstore_symbol_t *symbols, size_t symbols_count,
+        indexstore_symbol_t *related_symbols, size_t related_symbols_count,
+        bool(^applier)(indexstore_occurrence_t occur)) {
+  auto *reader = static_cast<IndexRecordReader *>(rdr);
+  auto receiverFn = [&](const IndexRecordOccurrence &RO) -> bool {
+    return applier((indexstore_occurrence_t)&RO);
+  };
+  return reader->foreachOccurrence({(IndexRecordDecl**)symbols, symbols_count},
+                                   {(IndexRecordDecl**)related_symbols, related_symbols_count},
+                                   receiverFn);
+}
+#endif
+
+size_t
+indexstore_store_get_unit_name_from_output_path(indexstore_t store,
+                                                const char *output_path,
+                                                char *name_buf,
+                                                size_t buf_size) {
+  SmallString<256> unitName;
+  IndexUnitWriter::getUnitNameForAbsoluteOutputFile(output_path, unitName);
+  size_t nameLen = unitName.size();
+  strlcpy(name_buf, unitName.c_str(), buf_size);
+  return nameLen;
+}
+
+bool
+indexstore_store_get_unit_modification_time(indexstore_t c_store,
+                                            const char *unit_name,
+                                            int64_t *seconds,
+                                            int64_t *nanoseconds,
+                                            indexstore_error_t *c_error) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  std::string error;
+  // FIXME: This provides mod time with second-only accuracy.
+  auto optModTime = IndexUnitReader::getModificationTimeForUnit(unit_name,
+                                              store->getFilePath(), error);
+  if (!optModTime) {
+    if (c_error)
+      *c_error = new IndexStoreError{ error };
+    return true;
+  }
+
+  timespec ts = toTimeSpec(*optModTime);
+  if (seconds)
+    *seconds = ts.tv_sec;
+  if (nanoseconds)
+    *nanoseconds = ts.tv_nsec;
+
+  return false;
+}
+
+indexstore_unit_reader_t
+indexstore_unit_reader_create(indexstore_t c_store, const char *unit_name,
+                              indexstore_error_t *c_error) {
+  IndexDataStore *store = static_cast<IndexDataStore*>(c_store);
+  std::unique_ptr<IndexUnitReader> reader;
+  std::string error;
+  reader = IndexUnitReader::createWithUnitFilename(unit_name,
+                                                   store->getFilePath(), error);
+  if (!reader) {
+    if (c_error)
+      *c_error = new IndexStoreError{ error };
+    return nullptr;
+  }
+  return reader.release();
+}
+
+void
+indexstore_unit_reader_dispose(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  delete reader;
+}
+
+indexstore_string_ref_t
+indexstore_unit_reader_get_provider_identifier(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return toIndexStoreString(reader->getProviderIdentifier());
+}
+
+indexstore_string_ref_t
+indexstore_unit_reader_get_provider_version(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return toIndexStoreString(reader->getProviderVersion());
+}
+
+void
+indexstore_unit_reader_get_modification_time(indexstore_unit_reader_t rdr,
+                                             int64_t *seconds,
+                                             int64_t *nanoseconds) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  // FIXME: This provides mod time with second-only accuracy.
+  sys::TimePoint<> timeVal = reader->getModificationTime();
+  timespec ts = toTimeSpec(timeVal);
+  if (seconds)
+    *seconds = ts.tv_sec;
+  if (nanoseconds)
+    *nanoseconds = ts.tv_nsec;
+}
+
+bool
+indexstore_unit_reader_is_system_unit(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return reader->isSystemUnit();
+}
+
+bool
+indexstore_unit_reader_is_module_unit(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return reader->isModuleUnit();
+}
+
+bool
+indexstore_unit_reader_is_debug_compilation(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return reader->isDebugCompilation();
+}
+
+bool
+indexstore_unit_reader_has_main_file(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return reader->hasMainFile();
+}
+
+indexstore_string_ref_t
+indexstore_unit_reader_get_main_file(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return toIndexStoreString(reader->getMainFilePath());
+}
+
+indexstore_string_ref_t
+indexstore_unit_reader_get_module_name(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return toIndexStoreString(reader->getModuleName());
+}
+
+indexstore_string_ref_t
+indexstore_unit_reader_get_working_dir(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return toIndexStoreString(reader->getWorkingDirectory());
+}
+
+indexstore_string_ref_t
+indexstore_unit_reader_get_output_file(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return toIndexStoreString(reader->getOutputFile());
+}
+
+indexstore_string_ref_t
+indexstore_unit_reader_get_sysroot_path(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return toIndexStoreString(reader->getSysrootPath());
+}
+
+indexstore_string_ref_t
+indexstore_unit_reader_get_target(indexstore_unit_reader_t rdr) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return toIndexStoreString(reader->getTarget());
+}
+
+indexstore_unit_dependency_kind_t
+indexstore_unit_dependency_get_kind(indexstore_unit_dependency_t c_dep) {
+  auto dep = static_cast<const IndexUnitReader::DependencyInfo*>(c_dep);
+  switch (dep->Kind) {
+  case IndexUnitReader::DependencyKind::Unit: return INDEXSTORE_UNIT_DEPENDENCY_UNIT;
+  case IndexUnitReader::DependencyKind::Record: return INDEXSTORE_UNIT_DEPENDENCY_RECORD;
+  case IndexUnitReader::DependencyKind::File: return INDEXSTORE_UNIT_DEPENDENCY_FILE;
+  }
+}
+
+bool
+indexstore_unit_dependency_is_system(indexstore_unit_dependency_t c_dep) {
+  auto dep = static_cast<const IndexUnitReader::DependencyInfo*>(c_dep);
+  return dep->IsSystem;
+}
+
+indexstore_string_ref_t
+indexstore_unit_dependency_get_filepath(indexstore_unit_dependency_t c_dep) {
+  auto dep = static_cast<const IndexUnitReader::DependencyInfo*>(c_dep);
+  return toIndexStoreString(dep->FilePath);
+}
+
+indexstore_string_ref_t
+indexstore_unit_dependency_get_modulename(indexstore_unit_dependency_t c_dep) {
+  auto dep = static_cast<const IndexUnitReader::DependencyInfo*>(c_dep);
+  return toIndexStoreString(dep->ModuleName);
+}
+
+indexstore_string_ref_t
+indexstore_unit_dependency_get_name(indexstore_unit_dependency_t c_dep) {
+  auto dep = static_cast<const IndexUnitReader::DependencyInfo*>(c_dep);
+  return toIndexStoreString(dep->UnitOrRecordName);
+}
+
+time_t
+indexstore_unit_dependency_get_modification_time(indexstore_unit_dependency_t c_dep) {
+  auto dep = static_cast<const IndexUnitReader::DependencyInfo*>(c_dep);
+  return dep->ModTime;
+}
+
+size_t
+indexstore_unit_dependency_get_file_size(indexstore_unit_dependency_t c_dep) {
+  auto dep = static_cast<const IndexUnitReader::DependencyInfo*>(c_dep);
+  return dep->FileSize;
+}
+
+indexstore_string_ref_t
+indexstore_unit_include_get_source_path(indexstore_unit_include_t c_inc) {
+  auto inc = static_cast<const IndexUnitReader::IncludeInfo*>(c_inc);
+  return toIndexStoreString(inc->SourcePath);
+}
+
+indexstore_string_ref_t
+indexstore_unit_include_get_target_path(indexstore_unit_include_t c_inc) {
+  auto inc = static_cast<const IndexUnitReader::IncludeInfo*>(c_inc);
+  return toIndexStoreString(inc->TargetPath);
+}
+
+unsigned
+indexstore_unit_include_get_source_line(indexstore_unit_include_t c_inc) {
+  auto inc = static_cast<const IndexUnitReader::IncludeInfo*>(c_inc);
+  return inc->SourceLine;
+}
+
+#if INDEXSTORE_HAS_BLOCKS
+bool
+indexstore_unit_reader_dependencies_apply(indexstore_unit_reader_t rdr,
+                             bool(^applier)(indexstore_unit_dependency_t)) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return reader->foreachDependency([&](const IndexUnitReader::DependencyInfo &depInfo) -> bool {
+    return applier((void*)&depInfo);
+  });
+}
+
+bool
+indexstore_unit_reader_includes_apply(indexstore_unit_reader_t rdr,
+                             bool(^applier)(indexstore_unit_include_t)) {
+  auto reader = static_cast<IndexUnitReader*>(rdr);
+  return reader->foreachInclude([&](const IndexUnitReader::IncludeInfo &incInfo) -> bool {
+    return applier((void*)&incInfo);
+  });
+}
+#endif
diff --git a/tools/IndexStore/IndexStore.exports b/tools/IndexStore/IndexStore.exports
new file mode 100644
index 0000000..70c174f
--- /dev/null
+++ b/tools/IndexStore/IndexStore.exports
@@ -0,0 +1,69 @@
+indexstore_error_get_description
+indexstore_error_dispose
+indexstore_format_version
+indexstore_store_create
+indexstore_store_dispose
+indexstore_store_get_unit_modification_time
+indexstore_store_get_unit_name_from_output_path
+indexstore_store_units_apply
+indexstore_store_set_unit_event_handler
+indexstore_store_start_unit_event_listening
+indexstore_store_stop_unit_event_listening
+indexstore_store_discard_unit
+indexstore_store_discard_record
+indexstore_store_purge_stale_data
+indexstore_symbol_get_kind
+indexstore_symbol_get_language
+indexstore_symbol_get_properties
+indexstore_symbol_get_roles
+indexstore_symbol_get_related_roles
+indexstore_symbol_get_subkind
+indexstore_symbol_get_name
+indexstore_symbol_get_usr
+indexstore_symbol_get_codegen_name
+indexstore_symbol_relation_get_roles
+indexstore_symbol_relation_get_symbol
+indexstore_occurrence_get_symbol
+indexstore_occurrence_get_roles
+indexstore_occurrence_get_line_col
+indexstore_occurrence_relations_apply
+indexstore_record_reader_create
+indexstore_record_reader_dispose
+indexstore_record_reader_search_symbols
+indexstore_record_reader_symbols_apply
+indexstore_record_reader_occurrences_apply
+indexstore_record_reader_occurrences_in_line_range_apply
+indexstore_record_reader_occurrences_of_symbols_apply
+indexstore_unit_dependency_get_kind
+indexstore_unit_dependency_get_filepath
+indexstore_unit_dependency_get_file_size
+indexstore_unit_dependency_get_modification_time
+indexstore_unit_dependency_get_modulename
+indexstore_unit_dependency_get_name
+indexstore_unit_dependency_is_system
+indexstore_unit_event_get_kind
+indexstore_unit_event_get_modification_time
+indexstore_unit_event_get_unit_name
+indexstore_unit_event_notification_get_event
+indexstore_unit_event_notification_get_events_count
+indexstore_unit_event_notification_is_initial
+indexstore_unit_reader_create
+indexstore_unit_reader_dispose
+indexstore_unit_reader_get_main_file
+indexstore_unit_reader_get_modification_time
+indexstore_unit_reader_get_module_name
+indexstore_unit_reader_get_provider_identifier
+indexstore_unit_reader_get_provider_version
+indexstore_unit_reader_get_working_dir
+indexstore_unit_reader_get_output_file
+indexstore_unit_reader_get_sysroot_path
+indexstore_unit_reader_get_target
+indexstore_unit_reader_dependencies_apply
+indexstore_unit_reader_includes_apply
+indexstore_unit_reader_has_main_file
+indexstore_unit_reader_is_debug_compilation
+indexstore_unit_reader_is_module_unit
+indexstore_unit_reader_is_system_unit
+indexstore_unit_include_get_source_path
+indexstore_unit_include_get_target_path
+indexstore_unit_include_get_source_line
diff --git a/tools/c-index-test/CMakeLists.txt b/tools/c-index-test/CMakeLists.txt
index ad990e0..c8d33b9 100644
--- a/tools/c-index-test/CMakeLists.txt
+++ b/tools/c-index-test/CMakeLists.txt
@@ -1,3 +1,5 @@
+include(CheckIncludeFiles)
+
 set(LLVM_LINK_COMPONENTS
   support
 )
@@ -5,8 +7,15 @@
 add_clang_executable(c-index-test
   c-index-test.c
   core_main.cpp
+  JSONAggregation.cpp
   )
 
+set(INDEXSTORE_LIB)
+set(CINDEXTEST_LIBS)
+if(APPLE)
+  set(INDEXSTORE_LIB IndexStore)
+endif()
+
 if(NOT MSVC)
   set_property(
     SOURCE c-index-test.c
@@ -19,16 +28,20 @@
     libclang_static
     clangCodeGen
     clangIndex
+    ${CINDEXTEST_LIBS}
   )
 else()
   target_link_libraries(c-index-test
     libclang
+    ${INDEXSTORE_LIB}
     clangAST
     clangBasic
     clangCodeGen
+    clangDirectoryWatcher
     clangFrontend
     clangIndex
     clangSerialization
+    ${CINDEXTEST_LIBS}
   )
 endif()
 
@@ -42,6 +55,13 @@
   target_link_libraries(c-index-test ${LIBXML2_LIBRARIES})
 endif()
 
+if(APPLE)
+  check_include_files("CoreServices/CoreServices.h" HAVE_CORESERVICES_H)
+  if(HAVE_CORESERVICES_H)
+    target_link_libraries(c-index-test "-framework CoreServices")
+  endif()
+endif()
+
 if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
   if(INTERNAL_INSTALL_PREFIX)
     set(INSTALL_DESTINATION "${INTERNAL_INSTALL_PREFIX}/bin")
diff --git a/tools/c-index-test/JSONAggregation.cpp b/tools/c-index-test/JSONAggregation.cpp
new file mode 100644
index 0000000..c7f4136
--- /dev/null
+++ b/tools/c-index-test/JSONAggregation.cpp
@@ -0,0 +1,409 @@
+//===--- JSONAggregation.cpp - Index data aggregation in JSON format ------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "JSONAggregation.h"
+#include "indexstore/IndexStoreCXX.h"
+#include "clang/Index/IndexDataStoreSymbolUtils.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang;
+using namespace clang::index;
+using namespace indexstore;
+using namespace llvm;
+
+#if INDEXSTORE_HAS_BLOCKS
+
+namespace {
+
+typedef size_t FilePathIndex;
+typedef size_t RecordIndex;
+typedef size_t SymbolIndex;
+
+struct UnitSourceInfo {
+  FilePathIndex FilePath;
+  SmallVector<RecordIndex, 2> AssociatedRecords;
+};
+
+struct UnitInfo {
+  std::string Name;
+  SmallVector<UnitSourceInfo, 8> Sources;
+  SmallVector<std::string, 3> UnitDepends;
+  FilePathIndex OutFile;
+  StringRef Triple;
+};
+
+struct SymbolInfo {
+  SymbolKind Kind;
+  SymbolLanguage Lang;
+  StringRef USR;
+  StringRef Name;
+  StringRef CodegenName;
+  SymbolRoleSet Roles = 0;
+  SymbolRoleSet RelatedRoles = 0;
+};
+
+struct SymbolRelationInfo {
+  SymbolIndex RelatedSymbol;
+  SymbolRoleSet Roles;
+  SymbolRelationInfo(SymbolIndex relSymbol, SymbolRoleSet roles)
+    : RelatedSymbol(relSymbol), Roles(roles) {}
+};
+
+struct SymbolOccurrenceInfo {
+  SymbolIndex Symbol;
+  SymbolRoleSet Roles = 0;
+  std::vector<SymbolRelationInfo> Relations;
+  unsigned Line;
+  unsigned Column;
+};
+
+struct RecordInfo {
+  SmallVector<SymbolOccurrenceInfo, 8> Occurrences;
+};
+
+class Aggregator {
+  IndexStore Store;
+
+  BumpPtrAllocator Allocator;
+
+  StringMap<FilePathIndex, BumpPtrAllocator &> FilePathIndices;
+  std::vector<StringRef> FilePaths;
+  StringMap<char, BumpPtrAllocator &> Triples;
+
+  std::vector<std::unique_ptr<UnitInfo>> Units;
+
+  StringMap<RecordIndex, BumpPtrAllocator &> RecordIndices;
+  std::vector<std::unique_ptr<RecordInfo>> Records;
+
+  StringMap<SymbolIndex, BumpPtrAllocator &> SymbolIndices;
+  std::vector<SymbolInfo> Symbols;
+
+public:
+  explicit Aggregator(IndexStore store)
+  : Store(std::move(store)),
+    FilePathIndices(Allocator),
+    Triples(Allocator),
+    RecordIndices(Allocator),
+    SymbolIndices(Allocator) {}
+
+  bool process();
+  void processUnit(StringRef name, IndexUnitReader &UnitReader);
+  void dumpJSON(raw_ostream &OS);
+
+private:
+  StringRef copyStr(StringRef str) {
+    if (str.empty())
+      return StringRef();
+    char *buf = Allocator.Allocate<char>(str.size());
+    std::copy(str.begin(), str.end(), buf);
+    return StringRef(buf, str.size());
+  }
+
+  StringRef getTripleString(StringRef inputTriple) {
+    return Triples.insert(std::make_pair(inputTriple, 0)).first->first();
+  }
+
+  FilePathIndex getFilePathIndex(StringRef path, StringRef workingDir);
+  RecordIndex getRecordIndex(StringRef recordFile);
+  SymbolIndex getSymbolIndex(IndexRecordSymbol sym);
+  std::unique_ptr<RecordInfo> processRecord(StringRef recordFile);
+};
+
+} // anonymous namespace
+
+bool Aggregator::process() {
+  bool succ = Store.foreachUnit(/*sorted=*/true, [&](StringRef unitName) -> bool {
+    std::string error;
+    auto unitReader = IndexUnitReader(Store, unitName, error);
+    if (!unitReader) {
+      errs() << "error opening unit file '" << unitName << "': " << error << '\n';
+      return false;
+    }
+
+    processUnit(unitName, unitReader);
+    return true;
+  });
+
+  return !succ;
+}
+
+void Aggregator::processUnit(StringRef name, IndexUnitReader &UnitReader) {
+  auto workDir = UnitReader.getWorkingDirectory();
+  auto unit = llvm::make_unique<UnitInfo>();
+  unit->Name = name;
+  unit->Triple = getTripleString(UnitReader.getTarget());
+  unit->OutFile = getFilePathIndex(UnitReader.getOutputFile(), workDir);
+
+  struct DepInfo {
+    UnitSourceInfo source;
+    std::string unitName;
+  };
+  SmallVector<DepInfo, 32> Deps;
+  UnitReader.foreachDependency([&](IndexUnitDependency dep) -> bool {
+    Deps.resize(Deps.size()+1);
+    auto &depInfo = Deps.back();
+    switch (dep.getKind()) {
+      case IndexUnitDependency::DependencyKind::Unit: {
+        depInfo.unitName = dep.getName();
+        StringRef filePath = dep.getFilePath();
+        if (!filePath.empty())
+          depInfo.source.FilePath = getFilePathIndex(filePath, workDir);
+        break;
+      }
+      case IndexUnitDependency::DependencyKind::Record: {
+        depInfo.source.FilePath = getFilePathIndex(dep.getFilePath(), workDir);
+        RecordIndex recIndex = getRecordIndex(dep.getName());
+        depInfo.source.AssociatedRecords.push_back(recIndex);
+        break;
+      }
+      case IndexUnitDependency::DependencyKind::File:
+        depInfo.source.FilePath = getFilePathIndex(dep.getFilePath(), workDir);
+    }
+    return true;
+  });
+
+  unit->Sources.reserve(Deps.size());
+  for (auto &dep : Deps) {
+    if (!dep.unitName.empty()) {
+      unit->UnitDepends.emplace_back(std::move(dep.unitName));
+    } else {
+      unit->Sources.push_back(std::move(dep.source));
+    }
+  }
+
+  Units.push_back(std::move(unit));
+}
+
+FilePathIndex Aggregator::getFilePathIndex(StringRef path, StringRef workingDir) {
+  StringRef absPath;
+  SmallString<128> absPathBuf;
+  if (sys::path::is_absolute(path) || workingDir.empty()) {
+    absPath = path;
+  } else {
+    absPathBuf = workingDir;
+    sys::path::append(absPathBuf, path);
+    absPath = absPathBuf.str();
+  }
+
+  auto pair = FilePathIndices.insert(std::make_pair(absPath, FilePaths.size()));
+  bool wasInserted = pair.second;
+  if (wasInserted) {
+    FilePaths.push_back(pair.first->first());
+  }
+  return pair.first->second;
+}
+
+RecordIndex Aggregator::getRecordIndex(StringRef recordFile) {
+  auto pair = RecordIndices.insert(std::make_pair(recordFile, Records.size()));
+  bool wasInserted = pair.second;
+  if (wasInserted) {
+    Records.push_back(processRecord(recordFile));
+  }
+  return pair.first->second;
+}
+
+std::unique_ptr<RecordInfo> Aggregator::processRecord(StringRef recordFile) {
+  std::string error;
+  auto recordReader = IndexRecordReader(Store, recordFile, error);
+  if (!recordReader) {
+    errs() << "failed reading record file: " << recordFile << '\n';
+    ::exit(1);
+  }
+  auto record = llvm::make_unique<RecordInfo>();
+  recordReader.foreachOccurrence([&](IndexRecordOccurrence idxOccur) -> bool {
+    SymbolIndex symIdx = getSymbolIndex(idxOccur.getSymbol());
+    SymbolInfo &symInfo = Symbols[symIdx];
+    symInfo.Roles |= idxOccur.getRoles();
+    SymbolOccurrenceInfo occurInfo;
+    occurInfo.Symbol = symIdx;
+    idxOccur.foreachRelation([&](IndexSymbolRelation rel) -> bool {
+      SymbolIndex relsymIdx = getSymbolIndex(rel.getSymbol());
+      SymbolInfo &relsymInfo = Symbols[relsymIdx];
+      relsymInfo.RelatedRoles |= rel.getRoles();
+      occurInfo.Relations.emplace_back(relsymIdx, rel.getRoles());
+      return true;
+    });
+    occurInfo.Roles = idxOccur.getRoles();
+    std::tie(occurInfo.Line, occurInfo.Column) = idxOccur.getLineCol();
+    record->Occurrences.push_back(std::move(occurInfo));
+    return true;
+  });
+  return record;
+}
+
+SymbolIndex Aggregator::getSymbolIndex(IndexRecordSymbol sym) {
+  auto pair = SymbolIndices.insert(std::make_pair(sym.getUSR(), Symbols.size()));
+  bool wasInserted = pair.second;
+  if (wasInserted) {
+    SymbolInfo symInfo;
+    symInfo.Kind = getSymbolKind(sym.getKind());
+    symInfo.Lang = getSymbolLanguage(sym.getLanguage());
+    symInfo.USR = pair.first->first();
+    symInfo.Name = copyStr(sym.getName());
+    symInfo.CodegenName = copyStr(sym.getCodegenName());
+    Symbols.push_back(std::move(symInfo));
+  }
+  return pair.first->second;
+}
+
+
+void Aggregator::dumpJSON(raw_ostream &OS) {
+  OS << "{\n";
+  OS.indent(2) << "\"files\": [\n";
+  for (unsigned i = 0, e = FilePaths.size(); i != e; ++i) {
+    OS.indent(4) << '\"' << FilePaths[i] << '\"';
+    if (i < e-1) OS << ',';
+    OS << '\n';
+  }
+  OS.indent(2) << "],\n";
+
+  OS.indent(2) << "\"symbols\": [\n";
+  for (unsigned i = 0, e = Symbols.size(); i != e; ++i) {
+    OS.indent(4) << "{\n";
+    SymbolInfo &symInfo = Symbols[i];
+    OS.indent(6) << "\"kind\": \"" << getSymbolKindString(symInfo.Kind) << "\",\n";
+    OS.indent(6) << "\"lang\": \"" << getSymbolLanguageString(symInfo.Lang) << "\",\n";
+    OS.indent(6) << "\"usr\": \"" << symInfo.USR << "\",\n";
+    OS.indent(6) << "\"name\": \"" << symInfo.Name << "\",\n";
+    if (!symInfo.CodegenName.empty())
+      OS.indent(6) << "\"codegen\": \"" << symInfo.CodegenName << "\",\n";
+    OS.indent(6) << "\"roles\": \"";
+    printSymbolRoles(symInfo.Roles, OS);
+    OS << '\"';
+    if (symInfo.RelatedRoles != 0) {
+      OS << ",\n";
+      OS.indent(6) << "\"rel-roles\": \"";
+      printSymbolRoles(symInfo.RelatedRoles, OS);
+      OS << '\"';
+    }
+    OS << '\n';
+    OS.indent(4) << "}";
+    if (i < e-1) OS << ',';
+    OS << '\n';
+  }
+  OS.indent(2) << "],\n";
+
+  OS.indent(2) << "\"records\": [\n";
+  for (unsigned i = 0, e = Records.size(); i != e; ++i) {
+    OS.indent(4) << "{\n";
+    RecordInfo &recInfo = *Records[i];
+    OS.indent(6) << "\"occurrences\": [\n";
+    for (unsigned oi = 0, oe = recInfo.Occurrences.size(); oi != oe; ++oi) {
+      OS.indent(8) << "{\n";
+      SymbolOccurrenceInfo &occurInfo = recInfo.Occurrences[oi];
+      OS.indent(10) << "\"symbol\": " << occurInfo.Symbol << ",\n";
+      OS.indent(10) << "\"line\": " << occurInfo.Line << ",\n";
+      OS.indent(10) << "\"col\": " << occurInfo.Column << ",\n";
+      OS.indent(10) << "\"roles\": \"";
+      printSymbolRoles(occurInfo.Roles, OS);
+      OS << '\"';
+      if (!occurInfo.Relations.empty()) {
+        OS << ",\n";
+        OS.indent(10) << "\"relations\": [\n";
+        for (unsigned ri = 0, re = occurInfo.Relations.size(); ri != re; ++ri) {
+          OS.indent(12) << "{\n";
+          SymbolRelationInfo &relInfo = occurInfo.Relations[ri];
+          OS.indent(14) << "\"symbol\": " << relInfo.RelatedSymbol << ",\n";
+          OS.indent(14) << "\"rel-roles\": \"";
+          printSymbolRoles(relInfo.Roles, OS);
+          OS << "\"\n";
+          OS.indent(12) << "}";
+          if (ri < re-1) OS << ',';
+          OS << '\n';
+        }
+        OS.indent(10) << "]\n";
+      }
+      OS << '\n';
+      OS.indent(8) << "}";
+      if (oi < oe-1) OS << ',';
+      OS << '\n';
+    }
+    OS.indent(6) << "]\n";
+    OS.indent(4) << "}";
+    if (i < e-1) OS << ',';
+    OS << '\n';
+  }
+  OS.indent(2) << "],\n";
+
+  StringMap<size_t> UnitIndicesByName;
+  for (unsigned i = 0, e = Units.size(); i != e; ++i) {
+    UnitInfo &unit = *Units[i];
+    UnitIndicesByName[unit.Name] = i;
+  }
+
+  OS.indent(2) << "\"units\": [\n";
+  for (unsigned i = 0, e = Units.size(); i != e; ++i) {
+    OS.indent(4) << "{\n";
+    UnitInfo &unit = *Units[i];
+    OS.indent(6) << "\"triple\": \"" << unit.Triple << "\",\n";
+    OS.indent(6) << "\"out-file\": " << unit.OutFile << ",\n";
+    if (!unit.UnitDepends.empty()) {
+      OS.indent(6) << "\"unit-dependencies\": [";
+      for (unsigned ui = 0, ue = unit.UnitDepends.size(); ui != ue; ++ui) {
+        OS << UnitIndicesByName[unit.UnitDepends[ui]];
+        if (ui < ue-1) OS << ", ";
+      }
+      OS << "],\n";
+    }
+    OS.indent(6) << "\"sources\": [\n";
+    for (unsigned si = 0, se = unit.Sources.size(); si != se; ++si) {
+      OS.indent(8) << "{\n";
+      UnitSourceInfo &source = unit.Sources[si];
+      OS.indent(10) << "\"file\": " << source.FilePath;
+      if (!source.AssociatedRecords.empty()) {
+        OS << ",\n";
+        OS.indent(10) << "\"records\": [";
+        for (unsigned ri = 0, re = source.AssociatedRecords.size(); ri != re; ++ri) {
+          OS << source.AssociatedRecords[ri];
+          if (ri < re-1) OS << ", ";
+        }
+        OS << ']';
+      }
+      OS << '\n';
+      OS.indent(8) << "}";
+      if (si < se-1) OS << ',';
+      OS << '\n';
+    }
+    OS.indent(6) << "]\n";
+    OS.indent(4) << "}";
+    if (i < e-1) OS << ',';
+    OS << '\n';
+  }
+  OS.indent(2) << "]\n";
+  OS << "}\n";
+}
+
+
+bool index::aggregateDataAsJSON(StringRef StorePath, raw_ostream &OS) {
+  std::string error;
+  auto dataStore = IndexStore(StorePath, error);
+  if (!dataStore) {
+    errs() << "error opening store path '" << StorePath << "': " << error << '\n';
+    return true;
+  }
+
+  // Explicitely avoid doing any memory cleanup for aggregator since the process
+  // is going to exit when we are done.
+  Aggregator *aggregator = new Aggregator(std::move(dataStore));
+  bool err = aggregator->process();
+  if (err)
+    return true;
+  aggregator->dumpJSON(OS);
+  return false;
+}
+
+#else
+
+bool index::aggregateDataAsJSON(StringRef StorePath, raw_ostream &OS) {
+  return true;
+}
+#endif
diff --git a/tools/c-index-test/JSONAggregation.h b/tools/c-index-test/JSONAggregation.h
new file mode 100644
index 0000000..5224ce8
--- /dev/null
+++ b/tools/c-index-test/JSONAggregation.h
@@ -0,0 +1,24 @@
+//===--- JSONAggregation.h - Index data aggregation in JSON format --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_CINDEXTEST_JSONAGGREGATION_H
+#define LLVM_CLANG_TOOLS_CINDEXTEST_JSONAGGREGATION_H
+
+#include "clang/Basic/LLVM.h"
+
+namespace clang {
+namespace index {
+
+/// Returns true if an error occurred, false otherwise.
+bool aggregateDataAsJSON(StringRef StorePath, raw_ostream &OS);
+
+} // end namespace index
+} // end namespace clang
+
+#endif
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index cf3581e..36b7703 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -110,6 +110,10 @@
   case CXError_ASTReadError:
     fprintf(stderr, "Failure: AST deserialization error occurred\n");
     return;
+
+  default:
+    fprintf(stderr, "Failure (other)\n");
+    return;
   }
 }
 
diff --git a/tools/c-index-test/core_main.cpp b/tools/c-index-test/core_main.cpp
index c255f54..298c55c 100644
--- a/tools/c-index-test/core_main.cpp
+++ b/tools/c-index-test/core_main.cpp
@@ -7,6 +7,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "JSONAggregation.h"
+#include "indexstore/IndexStoreCXX.h"
+#include "clang/DirectoryWatcher/DirectoryWatcher.h"
 #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -14,14 +17,31 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Index/IndexingAction.h"
 #include "clang/Index/IndexDataConsumer.h"
+#include "clang/Index/IndexDataStoreSymbolUtils.h"
+#include "clang/Index/IndexRecordReader.h"
+#include "clang/Index/IndexUnitReader.h"
 #include "clang/Index/USRGeneration.h"
 #include "clang/Index/CodegenNameGenerator.h"
 #include "clang/Serialization/ASTReader.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/PrettyStackTrace.h"
 
+#define HAVE_CORESERVICES 0
+
+#if defined(__has_include)
+#if __has_include(<CoreServices/CoreServices.h>)
+
+#include <CoreServices/CoreServices.h>
+#undef HAVE_CORESERVICES
+#define HAVE_CORESERVICES 1
+
+#endif
+#endif
+
 using namespace clang;
 using namespace clang::index;
 using namespace llvm;
@@ -33,6 +53,11 @@
 enum class ActionType {
   None,
   PrintSourceSymbols,
+  PrintRecord,
+  PrintUnit,
+  PrintStoreFormatVersion,
+  AggregateAsJSON,
+  WatchDir,
 };
 
 namespace options {
@@ -43,9 +68,26 @@
 Action(cl::desc("Action:"), cl::init(ActionType::None),
        cl::values(
           clEnumValN(ActionType::PrintSourceSymbols,
-                     "print-source-symbols", "Print symbols from source")),
+                     "print-source-symbols", "Print symbols from source"),
+          clEnumValN(ActionType::PrintRecord,
+                     "print-record", "Print record info"),
+          clEnumValN(ActionType::PrintUnit,
+                     "print-unit", "Print unit info"),
+          clEnumValN(ActionType::PrintStoreFormatVersion,
+                     "print-store-format-version", "Print store format version"),
+          clEnumValN(ActionType::AggregateAsJSON,
+                     "aggregate-json", "Aggregate index data in JSON format"),
+          clEnumValN(ActionType::WatchDir,
+                     "watch-dir", "Watch directory for file events")),
        cl::cat(IndexTestCoreCategory));
 
+static cl::opt<std::string>
+OutputFile("o", cl::desc("output file"),
+           cl::cat(IndexTestCoreCategory));
+
+static cl::list<std::string>
+InputFiles(cl::Positional, cl::desc("<filename>..."));
+
 static cl::extrahelp MoreHelp(
   "\nAdd \"-- <compiler arguments>\" at the end to setup the compiler "
   "invocation\n"
@@ -65,6 +107,10 @@
   ModuleFormat("fmodule-format", cl::init("raw"),
         cl::desc("Container format for clang modules and PCH, 'raw' or 'obj'"));
 
+static cl::opt<std::string>
+FilePathAndRange("filepath",
+               cl::desc("File path that can optionally include a line range"));
+
 }
 } // anonymous namespace
 
@@ -235,6 +281,305 @@
   return false;
 }
 
+#if INDEXSTORE_HAS_BLOCKS
+
+//===----------------------------------------------------------------------===//
+// Print Record
+//===----------------------------------------------------------------------===//
+
+static void printSymbol(const IndexRecordDecl &Rec, raw_ostream &OS);
+static void printSymbol(const IndexRecordOccurrence &Rec, raw_ostream &OS);
+
+static int printRecord(StringRef Filename, raw_ostream &OS) {
+  std::string Error;
+  auto Reader = IndexRecordReader::createWithFilePath(Filename, Error);
+  if (!Reader) {
+    errs() << Error << '\n';
+    return true;
+  }
+
+  Reader->foreachDecl(/*noCache=*/true, [&](const IndexRecordDecl *Rec)->bool {
+    printSymbol(*Rec, OS);
+    return true;
+  });
+  OS << "------------\n";
+  Reader->foreachOccurrence([&](const IndexRecordOccurrence &Rec)->bool {
+    printSymbol(Rec, OS);
+    return true;
+  });
+
+  return false;
+};
+
+//===----------------------------------------------------------------------===//
+// Print Store Records
+//===----------------------------------------------------------------------===//
+
+static void printSymbol(indexstore::IndexRecordSymbol Sym, raw_ostream &OS);
+static void printSymbol(indexstore::IndexRecordOccurrence Occur, raw_ostream &OS);
+
+static bool printStoreRecord(indexstore::IndexStore &Store, StringRef RecName,
+                             StringRef FilePath, raw_ostream &OS) {
+  std::string Error;
+  indexstore::IndexRecordReader Reader(Store, RecName, Error);
+  if (!Reader) {
+    errs() << "error loading record: " << Error << "\n";
+    return true;
+  }
+
+  StringRef Filename = sys::path::filename(FilePath);
+  OS << Filename << '\n';
+  OS << "------------\n";
+  Reader.foreachSymbol(/*noCache=*/true, [&](indexstore::IndexRecordSymbol Sym) -> bool {
+    printSymbol(Sym, OS);
+    return true;
+  });
+  OS << "------------\n";
+  Reader.foreachOccurrence([&](indexstore::IndexRecordOccurrence Occur)->bool {
+    printSymbol(Occur, OS);
+    return true;
+  });
+
+  return false;
+}
+
+static int printStoreRecords(StringRef StorePath, raw_ostream &OS) {
+  std::string Error;
+  indexstore::IndexStore Store(StorePath, Error);
+  if (!Store) {
+    errs() << "error loading store: " << Error << "\n";
+    return 1;
+  }
+
+  bool Success = Store.foreachUnit(/*sorted=*/true, [&](StringRef UnitName) -> bool {
+    indexstore::IndexUnitReader Reader(Store, UnitName, Error);
+    if (!Reader) {
+      errs() << "error loading unit: " << Error << "\n";
+      return false;
+    }
+    return Reader.foreachDependency([&](indexstore::IndexUnitDependency Dep) -> bool {
+      if (Dep.getKind() == indexstore::IndexUnitDependency::DependencyKind::Record) {
+        bool Err = printStoreRecord(Store, Dep.getName(), Dep.getFilePath(), OS);
+        OS << '\n';
+        return !Err;
+      }
+      return true;
+    });
+  });
+
+  return !Success;
+}
+
+static std::string findRecordNameForFile(indexstore::IndexStore &store,
+                                         StringRef filePath) {
+  std::string recName;
+  store.foreachUnit(/*sorted=*/false, [&](StringRef unitName) -> bool {
+    std::string error;
+    indexstore::IndexUnitReader Reader(store, unitName, error);
+    if (!Reader) {
+      errs() << "error loading unit: " << error << "\n";
+      return false;
+    }
+    Reader.foreachDependency([&](indexstore::IndexUnitDependency Dep) -> bool {
+      if (Dep.getKind() == indexstore::IndexUnitDependency::DependencyKind::Record) {
+        if (Dep.getFilePath() == filePath) {
+          recName = Dep.getName();
+          return false;
+        }
+        return true;
+      }
+      return true;
+    });
+    return true;
+  });
+  return recName;
+}
+
+static int printStoreFileRecord(StringRef storePath, StringRef filePath,
+                                Optional<unsigned> lineStart, unsigned lineCount,
+                                raw_ostream &OS) {
+  std::string error;
+  indexstore::IndexStore store(storePath, error);
+  if (!store) {
+    errs() << "error loading store: " << error << "\n";
+    return 1;
+  }
+
+  std::string recName = findRecordNameForFile(store, filePath);
+  if (recName.empty()) {
+    errs() << "could not find record for '" << filePath << "'\n";
+    return 1;
+  }
+
+  if (!lineStart.hasValue())
+    return printStoreRecord(store, recName, filePath, OS);
+
+  indexstore::IndexRecordReader Reader(store, recName, error);
+  if (!Reader) {
+    errs() << "error loading record: " << error << "\n";
+    return 1;
+  }
+
+  Reader.foreachOccurrenceInLineRange(*lineStart, lineCount, [&](indexstore::IndexRecordOccurrence Occur)->bool {
+    printSymbol(Occur, OS);
+    return true;
+  });
+
+  return 0;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Print Unit
+//===----------------------------------------------------------------------===//
+
+static int printUnit(StringRef Filename, raw_ostream &OS) {
+  std::string Error;
+  auto Reader = IndexUnitReader::createWithFilePath(Filename, Error);
+  if (!Reader) {
+    errs() << Error << '\n';
+    return true;
+  }
+
+  OS << "provider: " << Reader->getProviderIdentifier() << '-' << Reader->getProviderVersion() << '\n';
+  OS << "is-system: " << Reader->isSystemUnit() << '\n';
+  OS << "is-module: " << Reader->isModuleUnit() << '\n';
+  OS << "module-name: " << (Reader->getModuleName().empty() ? "<none>" : Reader->getModuleName()) << '\n';
+  OS << "has-main: " << Reader->hasMainFile() << '\n';
+  OS << "main-path: " << Reader->getMainFilePath() << '\n';
+  OS << "work-dir: " << Reader->getWorkingDirectory() << '\n';
+  OS << "out-file: " << Reader->getOutputFile() << '\n';
+  OS << "target: " << Reader->getTarget() << '\n';
+  OS << "is-debug: " << Reader->isDebugCompilation() << '\n';
+  OS << "DEPEND START\n";
+  unsigned NumDepends = 0;
+  Reader->foreachDependency([&](const IndexUnitReader::DependencyInfo &Dep) -> bool {
+    switch (Dep.Kind) {
+    case IndexUnitReader::DependencyKind::Unit:
+      OS << "Unit | "; break;
+    case IndexUnitReader::DependencyKind::Record:
+      OS << "Record | "; break;
+    case IndexUnitReader::DependencyKind::File:
+      OS << "File | "; break;
+    }
+    OS << (Dep.IsSystem ? "system" : "user");
+    OS << " | ";
+    if (!Dep.ModuleName.empty())
+      OS << Dep.ModuleName << " | ";
+    OS << Dep.FilePath << " | " << Dep.UnitOrRecordName << " | ";
+    OS << Dep.ModTime << " | " << Dep.FileSize << '\n';
+    ++NumDepends;
+    return true;
+  });
+  OS << "DEPEND END (" << NumDepends << ")\n";
+  OS << "INCLUDE START\n";
+  unsigned NumIncludes = 0;
+  Reader->foreachInclude([&](const IndexUnitReader::IncludeInfo &Inc) -> bool {
+    OS << Inc.SourcePath << ":" << Inc.SourceLine << " | ";
+    OS << Inc.TargetPath << '\n';
+    ++NumIncludes;
+    return true;
+  });
+  OS << "INCLUDE END (" << NumIncludes << ")\n";
+
+  return false;
+};
+
+//===----------------------------------------------------------------------===//
+// Print Store Units
+//===----------------------------------------------------------------------===//
+
+static bool printStoreUnit(indexstore::IndexStore &Store, StringRef UnitName,
+                           raw_ostream &OS) {
+  std::string Error;
+  indexstore::IndexUnitReader Reader(Store, UnitName, Error);
+  if (!Reader) {
+    errs() << "error loading unit: " << Error << "\n";
+    return true;
+  }
+
+  OS << "provider: " << Reader.getProviderIdentifier() << '-' << Reader.getProviderVersion() << '\n';
+  OS << "is-system: " << Reader.isSystemUnit() << '\n';
+  OS << "is-module: " << Reader.isModuleUnit() << '\n';
+  OS << "module-name: " << (Reader.getModuleName().empty() ? "<none>" : Reader.getModuleName()) << '\n';
+  OS << "has-main: " << Reader.hasMainFile() << '\n';
+  OS << "main-path: " << Reader.getMainFilePath() << '\n';
+  OS << "work-dir: " << Reader.getWorkingDirectory() << '\n';
+  OS << "out-file: " << Reader.getOutputFile() << '\n';
+  OS << "target: " << Reader.getTarget() << '\n';
+  OS << "is-debug: " << Reader.isDebugCompilation() << '\n';
+  OS << "DEPEND START\n";
+  unsigned NumDepends = 0;
+  Reader.foreachDependency([&](indexstore::IndexUnitDependency Dep) -> bool {
+    switch (Dep.getKind()) {
+    case indexstore::IndexUnitDependency::DependencyKind::Unit:
+      OS << "Unit | "; break;
+    case indexstore::IndexUnitDependency::DependencyKind::Record:
+      OS << "Record | "; break;
+    case indexstore::IndexUnitDependency::DependencyKind::File:
+      OS << "File | "; break;
+    }
+    OS << (Dep.isSystem() ? "system" : "user");
+    OS << " | ";
+    if (!Dep.getModuleName().empty())
+      OS << Dep.getModuleName() << " | ";
+    OS << Dep.getFilePath() << " | " << Dep.getName() << " | ";
+    OS << Dep.getModificationTime() << '\n';
+    ++NumDepends;
+    return true;
+  });
+  OS << "DEPEND END (" << NumDepends << ")\n";
+  OS << "INCLUDE START\n";
+  unsigned NumIncludes = 0;
+  Reader.foreachInclude([&](indexstore::IndexUnitInclude Inc) -> bool {
+    OS << Inc.getSourcePath() << ":" << Inc.getSourceLine() << " | ";
+    OS << Inc.getTargetPath() << '\n';
+    ++NumIncludes;
+    return true;
+  });
+  OS << "INCLUDE END (" << NumIncludes << ")\n";
+
+  return false;
+}
+
+static int printStoreUnits(StringRef StorePath, raw_ostream &OS) {
+  std::string Error;
+  indexstore::IndexStore Store(StorePath, Error);
+  if (!Store) {
+    errs() << "error loading store: " << Error << "\n";
+    return 1;
+  }
+
+  bool Success = Store.foreachUnit(/*sorted=*/true, [&](StringRef UnitName) -> bool {
+    OS << UnitName << '\n';
+    OS << "--------\n";
+    bool err = printStoreUnit(Store, UnitName, OS);
+    OS << '\n';
+    return !err;
+  });
+
+  return !Success;
+}
+
+
+#else
+
+static int printUnit(StringRef Filename, raw_ostream &OS) {
+  return 1;
+}
+
+static int printStoreUnits(StringRef StorePath, raw_ostream &OS) {
+  return 1;
+}
+
+static int printStoreFileRecord(StringRef storePath, StringRef filePath,
+                                Optional<unsigned> lineStart, unsigned lineCount,
+                                raw_ostream &OS) {
+  return 1;
+}
+
+#endif
+
 //===----------------------------------------------------------------------===//
 // Helper Utils
 //===----------------------------------------------------------------------===//
@@ -266,10 +611,210 @@
   }
 }
 
+#if INDEXSTORE_HAS_BLOCKS
+
+static void printSymbol(const IndexRecordDecl &Rec, raw_ostream &OS) {
+  printSymbolInfo(Rec.SymInfo, OS);
+  OS << " | ";
+
+  if (Rec.Name.empty())
+    OS << "<no-name>";
+  else
+    OS << Rec.Name;
+  OS << " | ";
+
+  if (Rec.USR.empty())
+    OS << "<no-usr>";
+  else
+    OS << Rec.USR;
+  OS << " | ";
+
+  if (Rec.CodeGenName.empty())
+    OS << "<no-cgname>";
+  else
+    OS << Rec.CodeGenName;
+  OS << " | ";
+
+  printSymbolRoles(Rec.Roles, OS);
+  OS << " - ";
+  printSymbolRoles(Rec.RelatedRoles, OS);
+  OS << '\n';
+}
+
+static void printSymbol(const IndexRecordOccurrence &Rec, raw_ostream &OS) {
+  OS << Rec.Line << ':' << Rec.Column << " | ";
+  printSymbolInfo(Rec.Dcl->SymInfo, OS);
+  OS << " | ";
+
+  if (Rec.Dcl->USR.empty())
+    OS << "<no-usr>";
+  else
+    OS << Rec.Dcl->USR;
+  OS << " | ";
+
+  printSymbolRoles(Rec.Roles, OS);
+  OS << " | ";
+  OS << "rel: " << Rec.Relations.size() << '\n';
+  for (auto &Rel : Rec.Relations) {
+    OS << '\t';
+    printSymbolRoles(Rel.Roles, OS);
+    OS << " | ";
+    if (Rel.Dcl->USR.empty())
+      OS << "<no-usr>";
+    else
+      OS << Rel.Dcl->USR;
+    OS << '\n';
+  }
+}
+
+static void printSymbol(indexstore::IndexRecordSymbol Sym, raw_ostream &OS) {
+  SymbolInfo SymInfo{getSymbolKind(Sym.getKind()),
+                     getSymbolSubKind(Sym.getSubKind()),
+                     SymbolPropertySet(Sym.getProperties()),
+                     getSymbolLanguage(Sym.getLanguage())};
+
+  printSymbolInfo(SymInfo, OS);
+  OS << " | ";
+
+  if (Sym.getName().empty())
+    OS << "<no-name>";
+  else
+    OS << Sym.getName();
+  OS << " | ";
+
+  if (Sym.getUSR().empty())
+    OS << "<no-usr>";
+  else
+    OS << Sym.getUSR();
+  OS << " | ";
+
+  if (Sym.getCodegenName().empty())
+    OS << "<no-cgname>";
+  else
+    OS << Sym.getCodegenName();
+  OS << " | ";
+
+  printSymbolRoles(Sym.getRoles(), OS);
+  OS << " - ";
+  printSymbolRoles(Sym.getRelatedRoles(), OS);
+  OS << '\n';
+}
+
+static void printSymbol(indexstore::IndexRecordOccurrence Occur, raw_ostream &OS) {
+  OS << Occur.getLineCol().first << ':' << Occur.getLineCol().second << " | ";
+  auto Sym = Occur.getSymbol();
+  SymbolInfo SymInfo{getSymbolKind(Sym.getKind()),
+                     getSymbolSubKind(Sym.getSubKind()),
+                     SymbolPropertySet(Sym.getProperties()),
+                     getSymbolLanguage(Sym.getLanguage())};
+
+  printSymbolInfo(SymInfo, OS);
+  OS << " | ";
+
+  if (Sym.getUSR().empty())
+    OS << "<no-usr>";
+  else
+    OS << Sym.getUSR();
+  OS << " | ";
+
+  unsigned NumRelations = 0;
+  Occur.foreachRelation([&](indexstore::IndexSymbolRelation) {
+    ++NumRelations;
+    return true;
+  });
+
+  printSymbolRoles(Occur.getRoles(), OS);
+  OS << " | ";
+  OS << "rel: " << NumRelations << '\n';
+  Occur.foreachRelation([&](indexstore::IndexSymbolRelation Rel) {
+    OS << '\t';
+    printSymbolRoles(Rel.getRoles(), OS);
+    OS << " | ";
+    auto Sym = Rel.getSymbol();
+    if (Sym.getUSR().empty())
+      OS << "<no-usr>";
+    else
+      OS << Sym.getUSR();
+    OS << '\n';
+    return true;
+  });
+}
+
+#else
+
+static int printRecord(StringRef Filename, raw_ostream &OS) {
+  return 1;
+}
+static int printStoreRecords(StringRef StorePath, raw_ostream &OS) {
+  return 1;
+}
+
+#endif
+
+static int watchDirectory(StringRef dirPath) {
+  raw_ostream &OS = outs();
+  auto receiver = [&](ArrayRef<DirectoryWatcher::Event> Events, bool isInitial) {
+    for (auto evt : Events) {
+      switch (evt.Kind) {
+        case DirectoryWatcher::EventKind::Added:
+          OS << "added: "; break;
+        case DirectoryWatcher::EventKind::Modified:
+          OS << "modified: "; break;
+        case DirectoryWatcher::EventKind::Removed:
+          OS << "removed: "; break;
+        case DirectoryWatcher::EventKind::DirectoryDeleted:
+          OS << "dir deleted: "; break;
+
+      }
+      OS << evt.Filename << '\n';
+    }
+  };
+  std::string Error;
+  auto watcher = DirectoryWatcher::create(dirPath, receiver,
+                                          /*waitInitialSync=*/true, Error);
+  if (!watcher) {
+    errs() << "failed creating directory watcher: " << Error << '\n';
+    return 1;
+  }
+#if HAVE_CORESERVICES
+  dispatch_main();
+#else
+  return 1;
+#endif
+}
+
 //===----------------------------------------------------------------------===//
 // Command line processing.
 //===----------------------------------------------------------------------===//
 
+bool deconstructPathAndRange(StringRef input,
+                             std::string &filepath,
+                             Optional<unsigned> &lineStart,
+                             unsigned &lineCount) {
+  StringRef path, range;
+  std::tie(path, range) = input.split(':');
+  StringRef start, end;
+  std::tie(start, end) = range.split(':');
+  filepath = path;
+  lineCount = 0;
+  if (start.empty())
+    return false;
+  unsigned num;
+  if (start.getAsInteger(10, num)) {
+    errs() << "couldn't convert to integer: " << start << '\n';
+    return true;
+  }
+  lineStart = num;
+  if (end.empty())
+    return false;
+  if (end.getAsInteger(10, num)) {
+    errs() << "couldn't convert to integer: " << end << '\n';
+    return true;
+  }
+  lineCount = num-lineStart.getValue();
+  return false;
+}
+
 int indextest_core_main(int argc, const char **argv) {
   sys::PrintStackTraceOnErrorSignal(argv[0]);
   PrettyStackTraceProgram X(argc, argv);
@@ -305,5 +850,75 @@
     return printSourceSymbols(CompArgs, options::DumpModuleImports, options::IncludeLocals);
   }
 
+  if (options::Action == ActionType::PrintRecord) {
+    if (!options::FilePathAndRange.empty()) {
+      std::string filepath;
+      Optional<unsigned> lineStart;
+      unsigned lineCount;
+      if (deconstructPathAndRange(options::FilePathAndRange,
+                                  filepath, lineStart, lineCount))
+        return 1;
+
+      if (options::InputFiles.empty()) {
+        errs() << "error: missing index store path\n";
+        return 1;
+      }
+      return printStoreFileRecord(options::InputFiles[0], filepath, lineStart, lineCount, outs());
+    }
+
+    if (options::InputFiles.empty()) {
+      errs() << "error: missing input file or directory\n";
+      return 1;
+    }
+
+    if (sys::fs::is_directory(options::InputFiles[0]))
+      return printStoreRecords(options::InputFiles[0], outs());
+    else
+      return printRecord(options::InputFiles[0], outs());
+  }
+
+  if (options::Action == ActionType::PrintUnit) {
+    if (options::InputFiles.empty()) {
+      errs() << "error: missing input file or directory\n";
+      return 1;
+    }
+
+    if (sys::fs::is_directory(options::InputFiles[0]))
+      return printStoreUnits(options::InputFiles[0], outs());
+    else
+      return printUnit(options::InputFiles[0], outs());
+  }
+
+#if INDEXSTORE_HAS_BLOCKS
+  if (options::Action == ActionType::PrintStoreFormatVersion) {
+    outs() << indexstore::IndexStore::formatVersion() << '\n';
+  }
+#endif
+
+  if (options::Action == ActionType::AggregateAsJSON) {
+    if (options::InputFiles.empty()) {
+      errs() << "error: missing input data store directory\n";
+      return 1;
+    }
+    StringRef storePath = options::InputFiles[0];
+    if (options::OutputFile.empty())
+      return aggregateDataAsJSON(storePath, outs());
+    std::error_code EC;
+    raw_fd_ostream OS(options::OutputFile, EC, llvm::sys::fs::F_None);
+    if (EC) {
+      errs() << "failed to open output file: " << EC.message() << '\n';
+      return 1;
+    }
+    return aggregateDataAsJSON(storePath, OS);
+  }
+
+  if (options::Action == ActionType::WatchDir) {
+    if (options::InputFiles.empty()) {
+      errs() << "error: missing directory path\n";
+      return 1;
+    }
+    return watchDirectory(options::InputFiles[0]);
+  }
+
   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-refactor-test/CMakeLists.txt b/tools/clang-refactor-test/CMakeLists.txt
new file mode 100644
index 0000000..f742327
--- /dev/null
+++ b/tools/clang-refactor-test/CMakeLists.txt
@@ -0,0 +1,23 @@
+set(LLVM_LINK_COMPONENTS
+  support
+  )
+
+add_clang_executable(clang-refactor-test
+  ClangRefactorTest.cpp
+  )
+
+if (LLVM_BUILD_STATIC)
+  target_link_libraries(clang-refactor-test
+    libclang_static
+  )
+else()
+  target_link_libraries(clang-refactor-test
+    libclang
+    clangBasic
+    clangFrontend
+    clangRewrite
+    clangTooling
+    clangToolingCore
+    clangToolingRefactor
+  )
+endif()
diff --git a/tools/clang-refactor-test/ClangRefactorTest.cpp b/tools/clang-refactor-test/ClangRefactorTest.cpp
new file mode 100644
index 0000000..424d130
--- /dev/null
+++ b/tools/clang-refactor-test/ClangRefactorTest.cpp
@@ -0,0 +1,1388 @@
+//===--- ClangRefactorTest.cpp - ------------------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file implements a clang-refactor-test tool that is used to test the
+//  refactoring library in Clang.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang-c/Refactor.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Frontend/CommandLineSourceLoc.h"
+#include "clang/Tooling/Refactor/SymbolName.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/LineIterator.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace opts {
+
+static cl::OptionCategory
+    ClangRefactorTestOptions("clang-refactor-test common options");
+
+cl::SubCommand RenameInitiateSubcommand(
+    "rename-initiate", "Initiate renaming in an initial translation unit");
+
+cl::SubCommand RenameInitiateUSRSubcommand(
+    "rename-initiate-usr",
+    "Initiate renaming in an translation unit on a specific declaration");
+
+cl::SubCommand RenameIndexedFileSubcommand(
+    "rename-indexed-file",
+    "Initiate renaming and find occurrences in an indexed file");
+
+cl::SubCommand ListRefactoringActionsSubcommand("list-actions",
+                                                "Print the list of the "
+                                                "refactoring actions that can "
+                                                "be performed at the specified "
+                                                "location");
+
+cl::SubCommand InitiateActionSubcommand("initiate",
+                                        "Initiate a refactoring action");
+
+cl::SubCommand
+    PerformActionSubcommand("perform",
+                            "Initiate and perform a refactoring action");
+
+const cl::desc
+    AtOptionDescription("The location at which the refactoring should be "
+                        "initiated (<file>:<line>:<column>)");
+
+const cl::desc InRangeOptionDescription(
+    "The location(s) at which the refactoring should be "
+    "initiated (<file>:<line>:<column>-<last-column>)");
+
+const cl::desc SelectedRangeOptionDescription(
+    "The selected source range in which the refactoring should be "
+    "initiated (<file>:<line>:<column>-<line>:<column>)");
+
+static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
+
+namespace rename {
+static cl::list<std::string> AtLocation("at", AtOptionDescription, cl::Required,
+                                        cl::cat(ClangRefactorTestOptions),
+                                        cl::sub(RenameInitiateSubcommand),
+                                        cl::OneOrMore);
+
+static cl::opt<std::string>
+    USR("usr", cl::desc("The USR of the declaration that should be renamed"),
+        cl::cat(ClangRefactorTestOptions), cl::sub(RenameInitiateUSRSubcommand),
+        cl::Required);
+
+static cl::opt<std::string>
+    NewName("new-name", cl::desc("The new name to change the symbol to."),
+            cl::Required, cl::cat(ClangRefactorTestOptions),
+            cl::sub(RenameInitiateSubcommand),
+            cl::sub(RenameInitiateUSRSubcommand));
+
+static cl::list<std::string>
+    IndexedNames("name", cl::desc("The names of the renamed symbols"),
+                 cl::Required, cl::OneOrMore, cl::cat(ClangRefactorTestOptions),
+                 cl::sub(RenameIndexedFileSubcommand));
+
+static cl::list<std::string> IndexedNewNames(
+    "new-name", cl::desc("The new name to change the symbol to."), cl::Required,
+    cl::OneOrMore, cl::cat(ClangRefactorTestOptions),
+    cl::sub(RenameIndexedFileSubcommand));
+
+static cl::opt<std::string>
+    IndexedSymbolKind("indexed-symbol-kind",
+                      cl::desc("The kind of the indexed symbol."), cl::Optional,
+                      cl::cat(ClangRefactorTestOptions),
+                      cl::sub(RenameIndexedFileSubcommand));
+
+static cl::opt<std::string>
+    IndexedFileName("indexed-file", cl::desc("The name of the indexed file"),
+                    cl::Required, cl::cat(ClangRefactorTestOptions),
+                    cl::sub(RenameIndexedFileSubcommand));
+
+static cl::list<std::string>
+    IndexedLocations("indexed-at",
+                     cl::desc("The location of an indexed occurrence "
+                              "([<kind>|<symbol-index>:]<line>:<column>)"),
+                     cl::ZeroOrMore, cl::cat(ClangRefactorTestOptions),
+                     cl::sub(RenameIndexedFileSubcommand));
+
+static cl::opt<bool> AvoidTextual(
+    "no-textual-matches", cl::desc("Avoid searching for textual matches"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(RenameIndexedFileSubcommand));
+
+static cl::opt<bool> DumpSymbols(
+    "dump-symbols", cl::desc("Dump the information about the renamed symbols"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(RenameInitiateSubcommand),
+    cl::sub(RenameInitiateUSRSubcommand));
+}
+
+namespace listActions {
+cl::opt<std::string> AtLocation("at", AtOptionDescription, cl::Required,
+                                cl::cat(ClangRefactorTestOptions),
+                                cl::sub(ListRefactoringActionsSubcommand));
+
+cl::opt<std::string> SelectedRange("selected", SelectedRangeOptionDescription,
+                                   cl::cat(ClangRefactorTestOptions),
+                                   cl::sub(ListRefactoringActionsSubcommand));
+
+cl::opt<bool> DumpRawActionType(
+    "dump-raw-action-type",
+    cl::desc("Prints the action type integer value for each listed action"),
+    cl::cat(ClangRefactorTestOptions),
+    cl::sub(ListRefactoringActionsSubcommand));
+}
+
+namespace initiateAndPerform {
+cl::list<std::string> InLocationRanges("in", cl::ZeroOrMore,
+                                       InRangeOptionDescription,
+                                       cl::cat(ClangRefactorTestOptions),
+                                       cl::sub(InitiateActionSubcommand));
+
+cl::list<std::string> AtLocations("at", cl::ZeroOrMore, AtOptionDescription,
+                                  cl::cat(ClangRefactorTestOptions),
+                                  cl::sub(InitiateActionSubcommand),
+                                  cl::sub(PerformActionSubcommand));
+
+cl::list<std::string> SelectedRanges("selected", cl::ZeroOrMore,
+                                     SelectedRangeOptionDescription,
+                                     cl::cat(ClangRefactorTestOptions),
+                                     cl::sub(InitiateActionSubcommand),
+                                     cl::sub(PerformActionSubcommand));
+
+cl::opt<std::string> ActionName("action", cl::Required,
+                                cl::desc("The name of the refactoring action"),
+                                cl::cat(ClangRefactorTestOptions),
+                                cl::sub(InitiateActionSubcommand),
+                                cl::sub(PerformActionSubcommand));
+
+cl::opt<bool> LocationAgnostic(
+    "location-agnostic",
+    cl::desc(
+        "Ignore the location of initiation when verifying result consistency"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(InitiateActionSubcommand));
+
+cl::opt<unsigned> CandidateIndex(
+    "candidate",
+    cl::desc(
+        "The index of the refactoring candidate which should be performed"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(PerformActionSubcommand));
+
+cl::opt<std::string> ContinuationFile(
+    "continuation-file",
+    cl::desc("The source file in which the continuation should run"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(PerformActionSubcommand));
+
+cl::opt<std::string> QueryResults(
+    "query-results", cl::desc("The indexer query results that should be passed "
+                              "into the continuation"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(PerformActionSubcommand));
+
+cl::opt<bool> EmitAssociatedInfo(
+    "emit-associated", cl::desc("Dump additional associated information"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(PerformActionSubcommand));
+}
+
+cl::opt<bool> Apply(
+    "apply",
+    cl::desc(
+        "Apply the changes and print the modified file to standard output"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(PerformActionSubcommand),
+    cl::sub(RenameInitiateSubcommand), cl::sub(RenameIndexedFileSubcommand));
+
+cl::opt<bool>
+    Diff("diff",
+         cl::desc("Display the replaced text in red when -apply is specified"),
+         cl::cat(ClangRefactorTestOptions), cl::sub(PerformActionSubcommand),
+         cl::sub(RenameInitiateSubcommand),
+         cl::sub(RenameIndexedFileSubcommand));
+
+cl::opt<int> Context("context", cl::desc("How many lines of context should be "
+                                         "displayed when -apply is specified"),
+                     cl::cat(ClangRefactorTestOptions),
+                     cl::sub(PerformActionSubcommand),
+                     cl::sub(RenameInitiateSubcommand),
+                     cl::sub(RenameIndexedFileSubcommand));
+
+static cl::opt<std::string> FileName(
+    cl::Positional, cl::desc("<filename>"), cl::Required,
+    cl::cat(ClangRefactorTestOptions), cl::sub(RenameInitiateSubcommand),
+    cl::sub(RenameInitiateUSRSubcommand), cl::sub(RenameIndexedFileSubcommand),
+    cl::sub(ListRefactoringActionsSubcommand),
+    cl::sub(InitiateActionSubcommand), cl::sub(PerformActionSubcommand));
+
+static cl::opt<bool> IgnoreFilenameForInitiationTU(
+    "ignore-filename-for-initiation-tu", cl::Optional,
+    cl::cat(ClangRefactorTestOptions), cl::sub(RenameIndexedFileSubcommand));
+
+static cl::list<std::string> CompilerArguments(
+    cl::ConsumeAfter, cl::desc("<arguments to be passed to the compiler>"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(RenameInitiateSubcommand),
+    cl::sub(RenameInitiateUSRSubcommand), cl::sub(RenameIndexedFileSubcommand),
+    cl::sub(ListRefactoringActionsSubcommand),
+    cl::sub(InitiateActionSubcommand), cl::sub(PerformActionSubcommand));
+
+static cl::opt<std::string> ImplementationTU(
+    "implementation-tu", cl::desc("The name of the implementation TU"),
+    cl::cat(ClangRefactorTestOptions), cl::sub(RenameInitiateSubcommand));
+}
+
+static const char *renameOccurrenceKindString(CXSymbolOccurrenceKind Kind,
+                                              bool IsLocal,
+                                              bool IsMacroExpansion) {
+  switch (Kind) {
+  case CXSymbolOccurrence_MatchingSymbol:
+    return IsMacroExpansion ? "macro" : IsLocal ? "rename local" : "rename";
+  case CXSymbolOccurrence_MatchingSelector:
+    assert(!IsLocal && "Objective-C selector renames must be global");
+    return IsMacroExpansion ? "selector in macro" : "selector";
+  case CXSymbolOccurrence_MatchingImplicitProperty:
+    assert(!IsLocal);
+    return IsMacroExpansion ? "implicit-property in macro"
+                            : "implicit-property";
+  case CXSymbolOccurrence_MatchingCommentString:
+    return "comment";
+  case CXSymbolOccurrence_MatchingDocCommentString:
+    return "documentation";
+  case CXSymbolOccurrence_MatchingFilename:
+    return "filename";
+  case CXSymbolOccurrence_ExtractedDeclaration:
+    return "extracted-decl";
+  case CXSymbolOccurrence_ExtractedDeclaration_Reference:
+    return "extracted-decl-ref";
+  }
+}
+
+static int apply(ArrayRef<CXRefactoringReplacement> Replacements,
+                 StringRef Filename) {
+  // Assume that the replacements are sorted.
+  auto Result = MemoryBuffer::getFile(Filename);
+  if (!Result) {
+    errs() << "Failed to open " << Filename << "\n";
+    return 1;
+  }
+
+  raw_ostream &OS = outs();
+
+  int Context = opts::Context;
+
+  MemoryBuffer &Buffer = **Result;
+  std::vector<std::pair<StringRef, std::vector<CXRefactoringReplacement>>>
+      Lines;
+  for (auto I = line_iterator(Buffer, /*SkipBlanks=*/false),
+            E = line_iterator();
+       I != E; ++I)
+    Lines.push_back(
+        std::make_pair(*I, std::vector<CXRefactoringReplacement>()));
+  unsigned FlushedLine = 1;
+  auto FlushUntil = [&](unsigned Line) {
+    // Adjust the first flushed line if needed when printing in context mode.
+    if (FlushedLine == 1 && Context)
+      FlushedLine = std::max(int(Line) - Context, 1);
+    for (; FlushedLine < Line; ++FlushedLine) {
+      const auto &Line = Lines[FlushedLine - 1];
+      if (Line.second.empty()) {
+        OS << Line.first << "\n";
+        continue;
+      }
+
+      unsigned I = 0;
+      for (const CXRefactoringReplacement &Replacement : Line.second) {
+        OS << Line.first.substr(I, Replacement.Range.Begin.Column - 1 - I);
+        if (opts::Diff) {
+          OS.changeColor(raw_ostream::RED, false, true);
+          OS << Line.first.substr(Replacement.Range.Begin.Column - 1,
+                                  Replacement.Range.End.Column - 1 -
+                                      (Replacement.Range.Begin.Column - 1));
+        }
+        OS.changeColor(raw_ostream::GREEN);
+        OS << clang_getCString(Replacement.ReplacementString);
+        OS.resetColor();
+        I = Replacement.Range.End.Column - 1;
+      }
+      OS << Line.first.substr(I);
+      if (I < Line.first.size() || opts::Diff)
+        OS << "\n";
+    }
+  };
+
+  int EndLineMax = 0;
+  for (const CXRefactoringReplacement &Replacement : Replacements) {
+    EndLineMax = std::max(int(Replacement.Range.End.Line), EndLineMax);
+    unsigned StartingLine = Replacement.Range.Begin.Line;
+    FlushUntil(StartingLine);
+    if (Replacement.Range.End.Line == StartingLine) {
+      Lines[StartingLine - 1].second.push_back(Replacement);
+      continue;
+    }
+    // Multi-line replacements have to be split
+    for (unsigned I = StartingLine; I <= Replacement.Range.End.Line; ++I) {
+      CXRefactoringReplacement NewReplacement;
+      if (I == Replacement.Range.End.Line)
+        NewReplacement.ReplacementString = Replacement.ReplacementString;
+      else
+        // FIXME: This is a hack to workaround the fact that the API doesn't
+        // provide a way to create a null string. This should be fixed when
+        // upstreaming.
+        NewReplacement.ReplacementString = {0, 0};
+      NewReplacement.Range.Begin.Line = I;
+      NewReplacement.Range.Begin.Column =
+          I == StartingLine ? Replacement.Range.Begin.Column : 1;
+      NewReplacement.Range.End.Line = I;
+      NewReplacement.Range.End.Column = I == Replacement.Range.End.Line
+                                            ? Replacement.Range.End.Column
+                                            : Lines[I - 1].first.size() + 1;
+      NewReplacement.AssociatedData = nullptr;
+      Lines[I - 1].second.push_back(NewReplacement);
+    }
+  }
+  FlushUntil(Context ? std::min(int(Lines.size()), EndLineMax + Context) + 1
+                     : Lines.size() + 2);
+  // Print out a dividor when printing in the context mode.
+  if (Context) {
+    for (int I = 0; I < 80; ++I)
+      OS << '-';
+    OS << "\n";
+  }
+  return 0;
+}
+
+/// Converts the given renamed \p Occurrence into a string value that represents
+/// this occurrence.
+static std::string
+occurrenceToString(const CXSymbolOccurrence &Occurrence, bool IsLocal,
+                   const tooling::SymbolName &NewName,
+                   const tooling::SymbolName &ExpectedReplacementStrings,
+                   StringRef Filename) {
+  std::string Str;
+  llvm::raw_string_ostream OS(Str);
+  OS << renameOccurrenceKindString(Occurrence.Kind, IsLocal,
+                                   Occurrence.IsMacroExpansion)
+     << ' ';
+  if (!Filename.empty())
+    OS << '"' << Filename << "\" ";
+
+  bool FirstRange = true;
+  assert(NewName.size() >= Occurrence.NumNamePieces &&
+         "new name doesn't match the number of pieces");
+  for (unsigned J = 0; J != Occurrence.NumNamePieces; ++J) {
+    if (!FirstRange) // TODO
+      OS << ", ";
+
+    // Print the replacement string if it doesn't match the expected string.
+    if (NewName[J] != ExpectedReplacementStrings[J])
+      OS << '"' << NewName[J] << "\" ";
+
+    CXFileRange Range = Occurrence.NamePieces[J];
+    OS << Range.Begin.Line << ":" << Range.Begin.Column << " -> "
+       << Range.End.Line << ":" << Range.End.Column;
+    FirstRange = false;
+  }
+  return OS.str();
+}
+
+static CXCursorKind
+renameIndexedOccurrenceKindStringToKind(StringRef Str, CXCursorKind Default) {
+  return llvm::StringSwitch<CXCursorKind>(Str)
+      .Case("objc-im", CXCursor_ObjCInstanceMethodDecl)
+      .Case("objc-cm", CXCursor_ObjCClassMethodDecl)
+      .Case("objc-message", CXCursor_ObjCMessageExpr)
+      .Case("include", CXCursor_InclusionDirective)
+      .Default(Default);
+}
+
+/// Parses the string passed as the -indexed-at argument.
+std::pair<CXRenamedIndexedSymbolLocation, unsigned>
+parseIndexedOccurrence(StringRef IndexedOccurrence,
+                       CXCursorKind DefaultCursorKind) {
+  StringRef LineColumnLoc = IndexedOccurrence;
+  CXCursorKind Kind = DefaultCursorKind;
+  unsigned SymbolIndex = 0;
+  if (LineColumnLoc.count(':') > 1) {
+    std::pair<StringRef, StringRef> Split = LineColumnLoc.split(':');
+    // The first value is either the kind or the symbol index.
+    if (Split.first.getAsInteger(10, SymbolIndex)) {
+      if (Split.second.count(':') > 1) {
+        std::pair<StringRef, StringRef> SecondSplit = Split.second.split(':');
+        if (SecondSplit.first.getAsInteger(10, SymbolIndex))
+          assert(false && "expected symbol index");
+        Split.second = SecondSplit.second;
+      }
+      Kind = renameIndexedOccurrenceKindStringToKind(Split.first, Kind);
+    }
+    LineColumnLoc = Split.second;
+  }
+  auto Loc = std::string("-:") + LineColumnLoc.str();
+  auto Location = ParsedSourceLocation::FromString(Loc);
+  return std::make_pair(
+      CXRenamedIndexedSymbolLocation{{Location.Line, Location.Column}, Kind},
+      SymbolIndex);
+}
+
+/// Compare the produced occurrences to the expected occurrences that were
+/// gathered at the first location. Return true if the occurrences are
+/// different.
+static bool compareOccurrences(ArrayRef<std::string> ExpectedReplacements,
+                               CXSymbolOccurrencesResult Occurrences,
+                               bool IsLocal,
+                               const tooling::SymbolName &NewSymbolName,
+                               bool PrintFilenames) {
+  unsigned NumFiles = clang_SymbolOccurrences_getNumFiles(Occurrences);
+  size_t ExpectedReplacementIndex = 0;
+  for (unsigned FileIndex = 0; FileIndex < NumFiles; ++FileIndex) {
+    CXSymbolOccurrencesInFile FileResult;
+    clang_SymbolOccurrences_getOccurrencesForFile(Occurrences, FileIndex,
+                                                  &FileResult);
+    StringRef Filename =
+        PrintFilenames ? clang_getCString(FileResult.Filename) : "";
+
+    for (unsigned I = 0; I != FileResult.NumOccurrences; ++I) {
+      std::string Replacement =
+          occurrenceToString(FileResult.Occurrences[I], IsLocal, NewSymbolName,
+                             NewSymbolName, Filename);
+      if (ExpectedReplacementIndex >= ExpectedReplacements.size() ||
+          Replacement != ExpectedReplacements[ExpectedReplacementIndex])
+        return true;
+      ++ExpectedReplacementIndex;
+    }
+  }
+  // Verify that all of the expected replacements were checked.
+  return ExpectedReplacementIndex != ExpectedReplacements.size();
+}
+
+struct ImplementationTUWrapper {
+  CXTranslationUnit TU = nullptr;
+
+  ImplementationTUWrapper() {}
+  ~ImplementationTUWrapper() { clang_disposeTranslationUnit(TU); }
+
+  ImplementationTUWrapper(const ImplementationTUWrapper &) = delete;
+  ImplementationTUWrapper &operator=(const ImplementationTUWrapper &) = delete;
+
+  bool load(CXRefactoringAction Action, CXIndex CIdx,
+            ArrayRef<const char *> Args);
+};
+
+bool ImplementationTUWrapper::load(CXRefactoringAction Action, CXIndex CIdx,
+                                   ArrayRef<const char *> Args) {
+  if (!clang_RefactoringAction_requiresImplementationTU(Action))
+    return false;
+  CXString USR =
+      clang_RefactoringAction_getUSRThatRequiresImplementationTU(Action);
+  outs() << "Implementation TU USR: '" << clang_getCString(USR) << "'\n";
+  clang_disposeString(USR);
+  if (!TU) {
+    CXErrorCode Err = clang_parseTranslationUnit2(
+        CIdx, opts::ImplementationTU.c_str(), Args.data(), Args.size(), 0, 0,
+        CXTranslationUnit_KeepGoing, &TU);
+    if (Err != CXError_Success) {
+      errs() << "error: failed to load implementation TU '"
+             << opts::ImplementationTU << "'\n";
+      return true;
+    }
+  }
+  CXErrorCode Err = clang_RefactoringAction_addImplementationTU(Action, TU);
+  if (Err != CXError_Success) {
+    errs() << "error: failed to add implementation TU '"
+           << opts::ImplementationTU << "'\n";
+    return true;
+  }
+  return false;
+}
+
+static bool reportNewNameError(CXErrorCode Err) {
+  std::string NewName = opts::RenameIndexedFileSubcommand
+                            ? opts::rename::IndexedNewNames[0]
+                            : opts::rename::NewName;
+  if (Err == CXError_RefactoringNameSizeMismatch)
+    errs() << "error: the number of strings in the new name '" << NewName
+           << "' doesn't match the the number of strings in the old name\n";
+  else if (Err == CXError_RefactoringNameInvalid)
+    errs() << "error: invalid new name '" << NewName << "'\n";
+  else
+    return true;
+  return false;
+}
+
+int rename(CXTranslationUnit TU, CXIndex CIdx, ArrayRef<const char *> Args) {
+  assert(!opts::RenameIndexedFileSubcommand);
+  // Contains the renamed source replacements for the first location. It is
+  // compared to replacements from follow-up renames to ensure that all renames
+  // give the same result.
+  std::vector<std::string> ExpectedReplacements;
+  // Should we print out the filenames. False by default, but true when multiple
+  // files are modified.
+  bool PrintFilenames = false;
+  ImplementationTUWrapper ImplementationTU;
+
+  auto RenameAt = [&](const ParsedSourceLocation &Location,
+                      const std::string &USR) -> int {
+    CXRefactoringAction RenamingAction;
+    CXErrorCode Err;
+    CXDiagnosticSet Diags = nullptr;
+    if (USR.empty()) {
+      CXSourceLocation Loc =
+          clang_getLocation(TU, clang_getFile(TU, Location.FileName.c_str()),
+                            Location.Line, Location.Column);
+      Err = clang_Refactoring_initiateAction(
+          TU, Loc, clang_getNullRange(), CXRefactor_Rename,
+          /*Options=*/nullptr, &RenamingAction, &Diags);
+    } else {
+      Err = clang_Refactoring_initiateActionOnDecl(
+          TU, USR.c_str(), CXRefactor_Rename, /*Options=*/nullptr,
+          &RenamingAction, nullptr);
+    }
+    if (Err != CXError_Success) {
+      errs() << "error: could not rename symbol "
+             << (USR.empty() ? "at the given location\n"
+                             : "with the given USR\n");
+      if (USR.empty()) {
+        unsigned NumDiags = clang_getNumDiagnosticsInSet(Diags);
+        for (unsigned DiagID = 0; DiagID < NumDiags; ++DiagID) {
+          CXDiagnostic Diag = clang_getDiagnosticInSet(Diags, DiagID);
+          CXString Spelling = clang_getDiagnosticSpelling(Diag);
+          errs() << clang_getCString(Spelling) << "\n";
+          clang_disposeString(Spelling);
+        }
+      }
+      clang_disposeDiagnosticSet(Diags);
+      return 1;
+    }
+    clang_disposeDiagnosticSet(Diags);
+
+    if (ImplementationTU.load(RenamingAction, CIdx, Args))
+      return 1;
+
+    Err = clang_Refactoring_initiateRenamingOperation(RenamingAction);
+    if (Err != CXError_Success) {
+      errs() << "error: failed to initiate the renaming operation!\n";
+      return 1;
+    }
+
+    bool IsLocal = clang_RefactoringAction_getInitiatedActionType(
+                       RenamingAction) == CXRefactor_Rename_Local;
+
+    unsigned NumSymbols = clang_RenamingOperation_getNumSymbols(RenamingAction);
+    if (opts::rename::DumpSymbols) {
+      outs() << "Renaming " << NumSymbols << " symbols\n";
+      for (unsigned I = 0; I < NumSymbols; ++I) {
+        CXString USR =
+            clang_RenamingOperation_getUSRForSymbol(RenamingAction, I);
+        outs() << "'" << clang_getCString(USR) << "'\n";
+        clang_disposeString(USR);
+      }
+    }
+
+    CXSymbolOccurrencesResult Occurrences;
+    Occurrences = clang_Refactoring_findSymbolOccurrencesInInitiationTU(
+        RenamingAction, Args.data(), Args.size(), 0, 0);
+
+    clang_RefactoringAction_dispose(RenamingAction);
+
+    // FIXME: This is a hack
+    LangOptions LangOpts;
+    LangOpts.ObjC1 = true;
+    tooling::SymbolName NewSymbolName(opts::rename::NewName, LangOpts);
+
+    if (ExpectedReplacements.empty()) {
+      if (opts::Apply) {
+        // FIXME: support --apply.
+      }
+
+      unsigned NumFiles = clang_SymbolOccurrences_getNumFiles(Occurrences);
+      if (NumFiles > 1)
+        PrintFilenames = true;
+      // Convert the occurrences to strings
+      for (unsigned FileIndex = 0; FileIndex < NumFiles; ++FileIndex) {
+        CXSymbolOccurrencesInFile FileResult;
+        clang_SymbolOccurrences_getOccurrencesForFile(Occurrences, FileIndex,
+                                                      &FileResult);
+        StringRef Filename =
+            PrintFilenames ? clang_getCString(FileResult.Filename) : "";
+        for (unsigned I = 0; I != FileResult.NumOccurrences; ++I)
+          ExpectedReplacements.push_back(
+              occurrenceToString(FileResult.Occurrences[I], IsLocal,
+                                 NewSymbolName, NewSymbolName, Filename));
+      }
+      clang_SymbolOccurrences_dispose(Occurrences);
+      return 0;
+    }
+    // Compare the produced occurrences to the expected occurrences that were
+    // gathered at the first location.
+    bool AreOccurrencesDifferent =
+        compareOccurrences(ExpectedReplacements, Occurrences, IsLocal,
+                           NewSymbolName, PrintFilenames);
+    clang_SymbolOccurrences_dispose(Occurrences);
+    if (!AreOccurrencesDifferent)
+      return 0;
+    errs() << "error: occurrences for a rename at " << Location.FileName << ":"
+           << Location.Line << ":" << Location.Column
+           << " differ to occurrences from the rename at the first location!\n";
+    return 1;
+  };
+
+  std::vector<ParsedSourceLocation> ParsedLocations;
+  for (const auto &I : enumerate(opts::rename::AtLocation)) {
+    auto Location = ParsedSourceLocation::FromString(I.value());
+    if (Location.FileName.empty()) {
+      errs()
+          << "error: The -at option must use the <file:line:column> format\n";
+      return 1;
+    }
+    ParsedLocations.push_back(Location);
+  }
+
+  if (opts::RenameInitiateUSRSubcommand) {
+    if (RenameAt(ParsedSourceLocation(), opts::rename::USR))
+      return 1;
+  } else {
+    assert(!ParsedLocations.empty() && "No -at locations");
+
+    for (const auto &Location : ParsedLocations) {
+      if (RenameAt(Location, ""))
+        return 1;
+    }
+  }
+
+  // Print the produced renamed replacements
+  if (opts::Apply)
+    return 0;
+  for (const auto &Replacement : ExpectedReplacements)
+    outs() << Replacement << "\n";
+  if (ExpectedReplacements.empty())
+    outs() << "no replacements found\n";
+  return 0;
+}
+
+int renameIndexedFile(CXIndex CIdx, ArrayRef<const char *> Args) {
+  assert(opts::RenameIndexedFileSubcommand);
+
+  // Compute the number of symbols.
+  unsigned NumSymbols = opts::rename::IndexedNames.size();
+
+  // Get the occurrences of a symbol.
+  CXCursorKind DefaultCursorKind = renameIndexedOccurrenceKindStringToKind(
+      opts::rename::IndexedSymbolKind, CXCursor_NotImplemented);
+  std::vector<std::vector<CXIndexedSymbolLocation>> IndexedOccurrences(
+      NumSymbols, std::vector<CXIndexedSymbolLocation>());
+  for (const auto &IndexedOccurrence : opts::rename::IndexedLocations) {
+    auto Occurrence =
+        parseIndexedOccurrence(IndexedOccurrence, DefaultCursorKind);
+    unsigned SymbolIndex = Occurrence.second;
+    assert(SymbolIndex < IndexedOccurrences.size() && "Invalid symbol index");
+    IndexedOccurrences[SymbolIndex].push_back(CXIndexedSymbolLocation{
+        Occurrence.first.Location, Occurrence.first.CursorKind});
+  }
+
+  // Create the indexed symbols.
+  std::vector<CXIndexedSymbol> IndexedSymbols;
+  for (const auto &I : llvm::enumerate(IndexedOccurrences)) {
+    const auto &Occurrences = I.value();
+    const char *Name =
+        opts::rename::IndexedNames[opts::rename::IndexedNames.size() < 2
+                                       ? 0
+                                       : I.index()]
+            .c_str();
+    IndexedSymbols.push_back({Occurrences.data(), (unsigned)Occurrences.size(),
+                              DefaultCursorKind, Name});
+  }
+
+  CXRefactoringOptionSet Options = nullptr;
+  if (opts::rename::AvoidTextual) {
+    Options = clang_RefactoringOptionSet_create();
+    clang_RefactoringOptionSet_add(Options,
+                                   CXRefactorOption_AvoidTextualMatches);
+  }
+
+  CXSymbolOccurrencesResult Occurrences;
+  CXErrorCode Err = clang_Refactoring_findSymbolOccurrencesInIndexedFile(
+      IndexedSymbols.data(), IndexedSymbols.size(), CIdx,
+      opts::rename::IndexedFileName.c_str(), Args.data(), Args.size(), 0, 0,
+      Options, &Occurrences);
+  if (Err != CXError_Success) {
+    if (reportNewNameError(Err))
+      errs() << "error: failed to perform indexed file rename\n";
+    return 1;
+  }
+
+  if (Options)
+    clang_RefactoringOptionSet_dispose(Options);
+
+  // Should we print out the filenames. False by default, but true when multiple
+  // files are modified.
+  bool PrintFilenames = false;
+  unsigned NumFiles = clang_SymbolOccurrences_getNumFiles(Occurrences);
+  if (NumFiles > 1)
+    PrintFilenames = true;
+
+  LangOptions LangOpts;
+  LangOpts.ObjC1 = true;
+  tooling::SymbolName ExpectedReplacementStrings(
+      opts::rename::IndexedNewNames[0], LangOpts);
+
+  // Print the occurrences.
+  bool HasReplacements = false;
+  for (unsigned FileIndex = 0; FileIndex < NumFiles; ++FileIndex) {
+    CXSymbolOccurrencesInFile FileResult;
+    clang_SymbolOccurrences_getOccurrencesForFile(Occurrences, FileIndex,
+                                                  &FileResult);
+    StringRef Filename =
+        PrintFilenames ? clang_getCString(FileResult.Filename) : "";
+    HasReplacements = FileResult.NumOccurrences;
+    for (unsigned I = 0; I != FileResult.NumOccurrences; ++I) {
+      unsigned SymbolIndex = FileResult.Occurrences[I].SymbolIndex;
+      const char *NewName =
+          opts::rename::IndexedNewNames[opts::rename::IndexedNewNames.size() < 2
+                                            ? 0
+                                            : SymbolIndex]
+              .c_str();
+      LangOptions LangOpts;
+      LangOpts.ObjC1 = true;
+      tooling::SymbolName NewSymbolName(NewName, LangOpts);
+
+      outs() << occurrenceToString(FileResult.Occurrences[I], /*IsLocal*/ false,
+                                   NewSymbolName, ExpectedReplacementStrings,
+                                   Filename)
+             << "\n";
+    }
+  }
+  if (!HasReplacements)
+    outs() << "no replacements found\n";
+  clang_SymbolOccurrences_dispose(Occurrences);
+  return 0;
+}
+
+/// Returns the last column number of a line in a file.
+static unsigned lastColumnForFile(StringRef Filename, unsigned LineNo) {
+  auto Buf = llvm::MemoryBuffer::getFile(Filename);
+  if (!Buf)
+    return 0;
+  unsigned LineCount = 1;
+  for (llvm::line_iterator Lines(**Buf, /*SkipBlanks=*/false);
+       !Lines.is_at_end(); ++Lines, ++LineCount) {
+    if (LineNo == LineCount)
+      return Lines->size() + 1;
+  }
+  return 0;
+}
+
+struct ParsedSourceLineRange : ParsedSourceLocation {
+  unsigned MaxColumn;
+
+  ParsedSourceLineRange() {}
+  ParsedSourceLineRange(const ParsedSourceLocation &Loc)
+      : ParsedSourceLocation(Loc), MaxColumn(Loc.Column) {}
+
+  static Optional<ParsedSourceLineRange> FromString(StringRef Str) {
+    std::pair<StringRef, StringRef> RangeSplit = Str.rsplit('-');
+    auto PSL = ParsedSourceLocation::FromString(RangeSplit.first);
+    ParsedSourceLineRange Result;
+    Result.FileName = std::move(PSL.FileName);
+    Result.Line = PSL.Line;
+    Result.Column = PSL.Column;
+    if (Result.FileName.empty())
+      return None;
+    if (RangeSplit.second == "end")
+      Result.MaxColumn = lastColumnForFile(Result.FileName, Result.Line);
+    else if (RangeSplit.second.getAsInteger(10, Result.MaxColumn))
+      return None;
+    if (Result.MaxColumn < Result.Column)
+      return None;
+    return Result;
+  }
+};
+
+struct ParsedSourceRange {
+  ParsedSourceLocation Begin, End;
+
+  ParsedSourceRange(const ParsedSourceLocation &Begin,
+                    const ParsedSourceLocation &End)
+      : Begin(Begin), End(End) {}
+
+  static Optional<ParsedSourceRange> FromString(StringRef Str) {
+    std::pair<StringRef, StringRef> RangeSplit = Str.rsplit('-');
+    auto Begin = ParsedSourceLocation::FromString(RangeSplit.first);
+    if (Begin.FileName.empty())
+      return None;
+    std::string EndString = Begin.FileName + ":" + RangeSplit.second.str();
+    auto End = ParsedSourceLocation::FromString(EndString);
+    if (End.FileName.empty())
+      return None;
+    return ParsedSourceRange(Begin, End);
+  }
+};
+
+int listRefactoringActions(CXTranslationUnit TU) {
+  auto Location =
+      ParsedSourceLocation::FromString(opts::listActions::AtLocation);
+  if (Location.FileName.empty()) {
+    errs() << "error: The -at option must use the <file:line:column> format\n";
+    return 1;
+  }
+  CXSourceRange Range;
+  if (!opts::listActions::SelectedRange.empty()) {
+    auto SelectionRange =
+        ParsedSourceRange::FromString(opts::listActions::SelectedRange);
+    if (!SelectionRange) {
+      errs() << "error: The -selected option must use the "
+                "<file:line:column-line:column> format\n";
+      return 1;
+    }
+    auto Begin = SelectionRange.getValue().Begin;
+    auto End = SelectionRange.getValue().End;
+    CXFile File = clang_getFile(TU, Begin.FileName.c_str());
+    Range =
+        clang_getRange(clang_getLocation(TU, File, Begin.Line, Begin.Column),
+                       clang_getLocation(TU, File, End.Line, End.Column));
+  } else
+    Range = clang_getNullRange();
+  CXSourceLocation Loc =
+      clang_getLocation(TU, clang_getFile(TU, Location.FileName.c_str()),
+                        Location.Line, Location.Column);
+  CXRefactoringActionSet ActionSet;
+  CXRefactoringActionSetWithDiagnostics FailedActionSet;
+  CXErrorCode Err =
+      clang_Refactoring_findActionsWithInitiationFailureDiagnosicsAt(
+          TU, Loc, Range, /*Options=*/nullptr, &ActionSet, &FailedActionSet);
+  if (FailedActionSet.NumActions) {
+    errs() << "Failed to initiate " << FailedActionSet.NumActions
+           << " actions because:\n";
+    for (unsigned I = 0; I < FailedActionSet.NumActions; ++I) {
+      errs() << clang_getCString(clang_RefactoringActionType_getName(
+                    FailedActionSet.Actions[I].Action))
+             << ":";
+      CXDiagnosticSet Diags = FailedActionSet.Actions[I].Diagnostics;
+      unsigned NumDiags = clang_getNumDiagnosticsInSet(Diags);
+      for (unsigned DiagID = 0; DiagID < NumDiags; ++DiagID) {
+        CXDiagnostic Diag = clang_getDiagnosticInSet(Diags, DiagID);
+        CXString Spelling = clang_getDiagnosticSpelling(Diag);
+        errs() << ' ' << clang_getCString(Spelling);
+        clang_disposeString(Spelling);
+      }
+      errs() << "\n";
+    }
+  }
+  if (Err == CXError_RefactoringActionUnavailable)
+    errs() << "No refactoring actions are available at the given location\n";
+  if (Err != CXError_Success)
+    return 1;
+  // Print the list of refactoring actions.
+  outs() << "Found " << ActionSet.NumActions << " actions:\n";
+  for (unsigned I = 0; I < ActionSet.NumActions; ++I) {
+    outs() << clang_getCString(
+        clang_RefactoringActionType_getName(ActionSet.Actions[I]));
+    if (opts::listActions::DumpRawActionType)
+      outs() << "(" << ActionSet.Actions[I] << ")";
+    outs() << "\n";
+  }
+  clang_RefactoringActionSet_dispose(&ActionSet);
+  clang_RefactoringActionSetWithDiagnostics_dispose(&FailedActionSet);
+  return 0;
+}
+
+static std::string locationToString(CXSourceLocation Loc) {
+  unsigned Line, Column;
+  clang_getFileLocation(Loc, nullptr, &Line, &Column, nullptr);
+  std::string S;
+  llvm::raw_string_ostream OS(S);
+  OS << Line << ':' << Column;
+  return OS.str();
+}
+
+static std::string rangeToString(CXSourceRange Range) {
+  return locationToString(clang_getRangeStart(Range)) + " -> " +
+         locationToString(clang_getRangeEnd(Range));
+}
+
+static std::string
+refactoringCandidatesToString(CXRefactoringCandidateSet Candidates) {
+  std::string Results = "with multiple candidates:";
+  for (unsigned I = 0; I < Candidates.NumCandidates; ++I) {
+    Results += "\n";
+    Results += clang_getCString(Candidates.Candidates[I].Description);
+  }
+  return Results;
+}
+
+static void printEscaped(StringRef Str, raw_ostream &OS) {
+  size_t Pos = Str.find('\n');
+  OS << Str.substr(0, Pos);
+  if (Pos == StringRef::npos)
+    return;
+  OS << "\\n";
+  printEscaped(Str.substr(Pos + 1), OS);
+}
+
+bool printRefactoringReplacements(
+    CXRefactoringResult Result, CXRefactoringContinuation Continuation,
+    CXRefactoringContinuation CurrentContinuation) {
+  CXRefactoringReplacements Replacements =
+      clang_RefactoringResult_getSourceReplacements(Result);
+  if (Replacements.NumFileReplacementSets == 0) {
+    if (CurrentContinuation)
+      return false;
+    errs() << "error: no replacements produced!\n";
+    return true;
+  }
+  // Print out the produced results.
+  for (unsigned FileIndex = 0; FileIndex < Replacements.NumFileReplacementSets;
+       ++FileIndex) {
+    const CXRefactoringFileReplacementSet &FileSet =
+        Replacements.FileReplacementSets[FileIndex];
+    if (opts::Apply) {
+      apply(llvm::makeArrayRef(FileSet.Replacements, FileSet.NumReplacements),
+            clang_getCString(FileSet.Filename));
+      continue;
+    }
+    for (unsigned I = 0; I < FileSet.NumReplacements; ++I) {
+      const CXRefactoringReplacement &Replacement = FileSet.Replacements[I];
+
+      if (Continuation) {
+        // Always print the filenames in with continuations.
+        outs() << '"' << clang_getCString(FileSet.Filename) << "\" ";
+      }
+      outs() << '"';
+      printEscaped(clang_getCString(Replacement.ReplacementString), outs());
+      outs() << "\" ";
+      CXFileRange Range = Replacement.Range;
+      outs() << Range.Begin.Line << ":" << Range.Begin.Column << " -> "
+             << Range.End.Line << ":" << Range.End.Column;
+      if (opts::initiateAndPerform::EmitAssociatedInfo) {
+        CXRefactoringReplacementAssociatedSymbolOccurrences Info =
+            clang_RefactoringReplacement_getAssociatedSymbolOccurrences(
+                Replacement);
+        for (const CXSymbolOccurrence &SymbolOccurrence :
+             llvm::makeArrayRef(Info.AssociatedSymbolOccurrences,
+                                Info.NumAssociatedSymbolOccurrences)) {
+          outs() << " [Symbol " << renameOccurrenceKindString(
+                                       SymbolOccurrence.Kind, /*IsLocal*/ false,
+                                       SymbolOccurrence.IsMacroExpansion)
+                 << ' ' << SymbolOccurrence.SymbolIndex;
+          for (const auto &Piece :
+               llvm::makeArrayRef(SymbolOccurrence.NamePieces,
+                                  SymbolOccurrence.NumNamePieces)) {
+            outs() << ' ' << Piece.Begin.Line << ":" << Piece.Begin.Column
+                   << " -> " << Piece.End.Line << ":" << Piece.End.Column;
+          }
+          outs() << ']';
+        }
+      }
+      outs() << "\n";
+    }
+  }
+  return false;
+}
+
+/// Returns the last column number of a line in a file.
+static std::string queryResultsForFile(StringRef Filename, StringRef Name,
+                                       StringRef FileSubstitution) {
+  auto Buf = llvm::MemoryBuffer::getFile(Filename);
+  if (!Buf)
+    return "<invalid>";
+  StringRef Buffer = (*Buf)->getBuffer();
+  std::string Label = Name.str() + ":";
+  size_t I = Buffer.find(Label);
+  if (I == StringRef::npos)
+    return "<invalid>";
+  I = I + Label.size();
+  auto Result = Buffer.substr(I, Buffer.find('\n', I) - I);
+  std::string Sub1 = llvm::Regex("%s").sub(FileSubstitution, Result);
+  return llvm::Regex("%S").sub(llvm::sys::path::parent_path(FileSubstitution),
+                               Sub1);
+}
+
+static Optional<std::pair<unsigned, unsigned>>
+findSelectionLocInSource(StringRef Buffer, StringRef Label) {
+  size_t I = Buffer.find(Label);
+  if (I == StringRef::npos)
+    return None;
+  I = I + Label.size();
+  auto LocParts =
+      Buffer.substr(I, Buffer.find_first_of("\n/", I) - I).trim().split(":");
+  unsigned CurrentLine = Buffer.take_front(I).count('\n') + 1;
+  if (LocParts.second.empty())
+    return None;
+  StringRef LineString = LocParts.first;
+  unsigned Line, Column;
+  enum ExprKind { Literal, Add, Sub };
+  ExprKind Expr = LineString.startswith("+")
+                      ? Add
+                      : LineString.startswith("-") ? Sub : Literal;
+  if (LineString.drop_front(Expr != Literal ? 1 : 0).getAsInteger(10, Line))
+    return None;
+  if (Expr == Add)
+    Line += CurrentLine;
+  else if (Expr == Sub)
+    Line = CurrentLine - Line;
+  if (LocParts.second.getAsInteger(10, Column))
+    return None;
+  return std::make_pair(Line, Column);
+}
+
+static Optional<ParsedSourceLocation> selectionLocForFile(StringRef Filename,
+                                                          StringRef Name) {
+  auto Buf = llvm::MemoryBuffer::getFile(Filename);
+  if (!Buf)
+    return None;
+
+  StringRef Buffer = (*Buf)->getBuffer();
+  std::string Label = Name.str() + ":";
+  auto Start = findSelectionLocInSource(Buffer, Label);
+  if (!Start)
+    return None;
+  // Create the resulting source location.
+  // FIXME: Parse can be avoided.
+  std::string Str;
+  llvm::raw_string_ostream OS(Str);
+  OS << Filename << ":" << Start->first << ":" << Start->second;
+  return ParsedSourceLocation::FromString(OS.str());
+}
+
+static Optional<ParsedSourceRange> selectionRangeForFile(StringRef Filename,
+                                                         StringRef Name) {
+  auto Buf = llvm::MemoryBuffer::getFile(Filename);
+  if (!Buf)
+    return None;
+
+  StringRef Buffer = (*Buf)->getBuffer();
+  std::string BeginLabel = Name.str() + "-begin:";
+  std::string EndLabel = Name.str() + "-end:";
+  auto Start = findSelectionLocInSource(Buffer, BeginLabel);
+  auto End = findSelectionLocInSource(Buffer, EndLabel);
+  if (!Start || !End)
+    return None;
+  // Create the resulting source range.
+  // FIXME: Parse can be avoided.
+  std::string Str;
+  llvm::raw_string_ostream OS(Str);
+  OS << Filename << ":" << Start->first << ":" << Start->second << "-"
+     << End->first << ":" << End->second;
+  return ParsedSourceRange::FromString(OS.str());
+}
+
+bool performOperation(CXRefactoringAction Action, ArrayRef<const char *> Args,
+                      CXIndex CIdx) {
+  if (opts::initiateAndPerform::CandidateIndex.getNumOccurrences()) {
+    if (clang_RefactoringAction_selectRefactoringCandidate(
+            Action, opts::initiateAndPerform::CandidateIndex)) {
+      errs() << "error: failed to select the refactoring candidate!\n";
+      return true;
+    }
+  }
+  CXRefactoringOptionSet Options = nullptr;
+  CXString FailureReason;
+  CXRefactoringResult Result = clang_Refactoring_performOperation(
+      Action, Args.data(), Args.size(), nullptr, 0, Options, &FailureReason);
+  if (!Result) {
+    errs() << "error: failed to perform the refactoring operation";
+    if (const char *Reason = clang_getCString(FailureReason))
+      errs() << " (" << Reason << ')';
+    errs() << "!\n";
+    clang_disposeString(FailureReason);
+    return true;
+  }
+  CXRefactoringContinuation Continuation =
+      clang_RefactoringResult_getContinuation(Result);
+  bool AreReplacementsInvalid =
+      printRefactoringReplacements(Result, Continuation, Continuation);
+  clang_RefactoringResult_dispose(Result);
+  if (AreReplacementsInvalid) {
+    clang_RefactoringContinuation_dispose(Continuation);
+    return true;
+  }
+  if (!Continuation)
+    return false;
+  assert(clang_RefactoringContinuation_getNumIndexerQueries(Continuation) !=
+             0 &&
+         "Missing indexer queries?");
+  std::string QueryResults = queryResultsForFile(
+      opts::FileName, opts::initiateAndPerform::QueryResults,
+      /*FileSubstitution=*/opts::initiateAndPerform::ContinuationFile);
+  clang_RefactoringContinuation_loadSerializedIndexerQueryResults(
+      Continuation, /*Source=*/QueryResults.c_str());
+  CXDiagnosticSet Diags =
+      clang_RefactoringContinuation_verifyBeforeFinalizing(Continuation);
+  if (Diags) {
+    llvm::errs() << "error: continuation failed: ";
+    for (unsigned I = 0, E = clang_getNumDiagnosticsInSet(Diags); I != E; ++I) {
+      CXDiagnostic Diag = clang_getDiagnosticInSet(Diags, I);
+      CXString Spelling = clang_getDiagnosticSpelling(Diag);
+      errs() << clang_getCString(Spelling) << "\n";
+      clang_disposeString(Spelling);
+      clang_disposeDiagnostic(Diag);
+    }
+    clang_RefactoringContinuation_dispose(Continuation);
+    clang_disposeDiagnosticSet(Diags);
+    return true;
+  }
+  clang_RefactoringContinuation_finalizeEvaluationInInitationTU(Continuation);
+  // Load the continuation TU.
+  CXTranslationUnit ContinuationTU;
+  CXErrorCode Err = clang_parseTranslationUnit2(
+      CIdx, opts::initiateAndPerform::ContinuationFile.c_str(), Args.data(),
+      Args.size(), 0, 0, CXTranslationUnit_KeepGoing, &ContinuationTU);
+  if (Err != CXError_Success) {
+    errs() << "error: failed to load '"
+           << opts::initiateAndPerform::ContinuationFile.c_str() << "'\n";
+    clang_RefactoringContinuation_dispose(Continuation);
+    return true;
+  }
+  Result = clang_RefactoringContinuation_continueOperationInTU(
+      Continuation, ContinuationTU, &FailureReason);
+  if (!Result) {
+    errs() << "error: failed to perform the refactoring continuation";
+    if (const char *Reason = clang_getCString(FailureReason))
+      errs() << " (" << Reason << ')';
+    errs() << "!\n";
+    clang_disposeString(FailureReason);
+    clang_disposeTranslationUnit(ContinuationTU);
+    clang_RefactoringContinuation_dispose(Continuation);
+    return true;
+  }
+  // FIXME: Continuations can be chained in the future.
+  AreReplacementsInvalid =
+      printRefactoringReplacements(Result, Continuation, nullptr);
+  clang_RefactoringResult_dispose(Result);
+  clang_disposeTranslationUnit(ContinuationTU);
+  clang_RefactoringContinuation_dispose(Continuation);
+  return AreReplacementsInvalid;
+}
+
+int initiateAndPerformAction(CXTranslationUnit TU, ArrayRef<const char *> Args,
+                             CXIndex CIdx) {
+  std::vector<ParsedSourceLineRange> Ranges;
+  std::vector<ParsedSourceRange> SelectionRanges;
+  for (const auto &Range : opts::initiateAndPerform::InLocationRanges) {
+    auto ParsedLineRange = ParsedSourceLineRange::FromString(Range);
+    if (!ParsedLineRange) {
+      errs()
+          << "error: The -in option must use the <file:line:column[-column]> "
+             "format\n";
+      return 1;
+    }
+    Ranges.push_back(ParsedLineRange.getValue());
+  }
+  for (const auto &Range : opts::initiateAndPerform::AtLocations) {
+    if (!StringRef(Range).contains(':')) {
+      auto ParsedLocation = selectionLocForFile(opts::FileName, Range);
+      if (!ParsedLocation) {
+        errs() << "error: The -at option must use the <file:line:column> "
+                  "format\n";
+        return 1;
+      }
+      Ranges.push_back(*ParsedLocation);
+      continue;
+    }
+    // TODO: Remove old location in arguments in favour of new testing
+    // locations.
+    auto ParsedLocation = ParsedSourceLocation::FromString(Range);
+    if (ParsedLocation.FileName.empty()) {
+      errs() << "error: The -at option must use the <file:line:column> "
+                "format\n";
+      return 1;
+    }
+    Ranges.push_back(ParsedLocation);
+  }
+  for (const auto &Range : opts::initiateAndPerform::SelectedRanges) {
+    auto ParsedRange = StringRef(Range).contains(':')
+                           ? ParsedSourceRange::FromString(Range)
+                           : selectionRangeForFile(opts::FileName, Range);
+    if (!ParsedRange) {
+      errs() << "error: The -selected option must use the "
+                "<file:line:column-line:column> format or refer to the name of "
+                "the selection specifier in the source\n";
+      return 1;
+    }
+    SelectionRanges.push_back(ParsedRange.getValue());
+  }
+  if (Ranges.empty() && SelectionRanges.empty()) {
+    errs() << "error: -in or -at options must be specified at least once!";
+    return 1;
+  }
+  if (!Ranges.empty() && !SelectionRanges.empty()) {
+    errs() << "error: -in or -at options can't be used with -selected!";
+    return 1;
+  }
+
+  auto ActionTypeOrNone = StringSwitch<Optional<CXRefactoringActionType>>(
+                              opts::initiateAndPerform::ActionName)
+#define REFACTORING_OPERATION_ACTION(Name, Spelling, Command)                  \
+  .Case(Command, CXRefactor_##Name)
+#define REFACTORING_OPERATION_SUB_ACTION(Name, Parent, Spelling, Command)      \
+  .Case(Command, CXRefactor_##Parent##_##Name)
+#include "clang/Tooling/Refactor/RefactoringActions.def"
+                              .Default(None);
+  if (!ActionTypeOrNone) {
+    errs() << "error: invalid action '" << opts::initiateAndPerform::ActionName
+           << "'\n";
+    return 1;
+  }
+  CXRefactoringActionType ActionType = *ActionTypeOrNone;
+
+  Optional<bool> Initiated;
+  Optional<std::string> InitiationFailureReason;
+  Optional<std::string> LocationCandidateInformation;
+  auto InitiateAndPerform =
+      [&](const ParsedSourceLocation &Location, unsigned Column,
+          Optional<ParsedSourceRange> SelectionRange = None) -> bool {
+    CXSourceLocation Loc =
+        clang_getLocation(TU, clang_getFile(TU, Location.FileName.c_str()),
+                          Location.Line, Column);
+    CXSourceRange Range;
+    if (SelectionRange) {
+      auto Begin = SelectionRange.getValue().Begin;
+      auto End = SelectionRange.getValue().End;
+      CXFile File = clang_getFile(TU, Begin.FileName.c_str());
+      Range =
+          clang_getRange(clang_getLocation(TU, File, Begin.Line, Begin.Column),
+                         clang_getLocation(TU, File, End.Line, End.Column));
+    } else
+      Range = clang_getNullRange();
+    CXRefactoringAction Action;
+    CXString FailureReason;
+    CXErrorCode Err = clang_Refactoring_initiateActionAt(
+        TU, Loc, Range, ActionType, /*Options=*/nullptr, &Action,
+        &FailureReason);
+    std::string ReasonString;
+    if (const char *Reason = clang_getCString(FailureReason))
+      ReasonString = Reason;
+    clang_disposeString(FailureReason);
+    if (InitiationFailureReason.hasValue() &&
+        InitiationFailureReason.getValue() != ReasonString) {
+      errs() << "error: inconsistent results in a single action range!\n";
+      return true;
+    }
+    InitiationFailureReason = std::move(ReasonString);
+    if (Err == CXError_RefactoringActionUnavailable) {
+      if (Initiated.hasValue() && Initiated.getValue()) {
+        errs() << "error: inconsistent results in a single action range!\n";
+        return true;
+      }
+      Initiated = false;
+    } else if (Err != CXError_Success)
+      return true;
+    else if (Initiated.hasValue() && !Initiated.getValue()) {
+      errs() << "error: inconsistent results in a single action range!\n";
+      return true;
+    } else
+      Initiated = true;
+
+    CXRefactoringCandidateSet Candidates;
+    if (clang_RefactoringAction_getRefactoringCandidates(Action, &Candidates) ==
+            CXError_Success &&
+        Candidates.NumCandidates > 1) {
+      std::string CandidateString = refactoringCandidatesToString(Candidates);
+      if (LocationCandidateInformation) {
+        if (*LocationCandidateInformation != CandidateString) {
+          errs() << "error: inconsistent results in a single action range!\n";
+          return true;
+        }
+      } else
+        LocationCandidateInformation = CandidateString;
+    } else if (opts::InitiateActionSubcommand &&
+               !opts::initiateAndPerform::LocationAgnostic) {
+      CXSourceRange Range =
+          clang_RefactoringAction_getSourceRangeOfInterest(Action);
+      std::string LocationString =
+          std::string("at ") +
+          (!clang_Range_isNull(Range)
+               ? SelectionRange ? rangeToString(Range)
+                                : locationToString(clang_getRangeStart(Range))
+               : "<unknown>");
+      if (!LocationCandidateInformation.hasValue())
+        LocationCandidateInformation = LocationString;
+      else if (LocationCandidateInformation.getValue() != LocationString) {
+        errs() << "error: inconsistent results in a single action range!\n";
+        return true;
+      }
+    }
+
+    if (!*Initiated)
+      return false;
+
+    bool Failed = opts::PerformActionSubcommand
+                      ? performOperation(Action, Args, CIdx)
+                      : false;
+    clang_RefactoringAction_dispose(Action);
+    return Failed;
+  };
+
+  // Iterate over all of the possible locations and perform the initiation
+  // at each range.
+  for (const ParsedSourceLineRange &LineRange : Ranges) {
+    for (unsigned Column = LineRange.Column; Column <= LineRange.MaxColumn;
+         ++Column) {
+      if (InitiateAndPerform(LineRange, Column))
+        return 1;
+    }
+  }
+
+  for (const ParsedSourceRange &SelectionRange : SelectionRanges) {
+    if (InitiateAndPerform(SelectionRange.Begin, SelectionRange.Begin.Column,
+                           SelectionRange))
+      return 1;
+  }
+
+  if (!Initiated.getValue()) {
+    errs() << "Failed to initiate the refactoring action";
+    if (InitiationFailureReason.hasValue() &&
+        !InitiationFailureReason.getValue().empty())
+      errs() << " (" << InitiationFailureReason.getValue() << ')';
+    errs() << "!\n";
+    return 1;
+  }
+  if (opts::InitiateActionSubcommand) {
+    outs() << "Initiated the '" << opts::initiateAndPerform::ActionName
+           << "' action";
+    if (!opts::initiateAndPerform::LocationAgnostic)
+      outs() << ' ' << LocationCandidateInformation.getValue();
+    outs() << "\n";
+  }
+  return 0;
+}
+
+int main(int argc, const char **argv) {
+  cl::HideUnrelatedOptions(opts::ClangRefactorTestOptions);
+
+  cl::ParseCommandLineOptions(argc, argv, "Clang refactoring test tool\n");
+  cl::PrintOptionValues();
+
+  CXIndex CIdx = clang_createIndex(0, 0);
+
+  std::vector<const char *> Args;
+  for (const auto &Arg : opts::CompilerArguments) {
+    Args.push_back(Arg.c_str());
+  }
+  CXTranslationUnit TU;
+  CXErrorCode Err = clang_parseTranslationUnit2(
+      CIdx,
+      opts::IgnoreFilenameForInitiationTU ? nullptr : opts::FileName.c_str(),
+      Args.data(), Args.size(), 0, 0, CXTranslationUnit_KeepGoing, &TU);
+  if (Err != CXError_Success) {
+    errs() << "error: failed to load '" << opts::FileName << "'\n";
+    return 1;
+  }
+
+  if (opts::RenameInitiateSubcommand || opts::RenameInitiateUSRSubcommand)
+    return rename(TU, CIdx, Args);
+  else if (opts::RenameIndexedFileSubcommand)
+    return renameIndexedFile(CIdx, Args);
+  else if (opts::ListRefactoringActionsSubcommand)
+    return listRefactoringActions(TU);
+  else if (opts::InitiateActionSubcommand || opts::PerformActionSubcommand)
+    return initiateAndPerformAction(TU, Args, CIdx);
+
+  clang_disposeTranslationUnit(TU);
+  clang_disposeIndex(CIdx);
+
+  return 0;
+}
diff --git a/tools/diagtool/DiagnosticNames.cpp b/tools/diagtool/DiagnosticNames.cpp
index a08da89..00af854 100644
--- a/tools/diagtool/DiagnosticNames.cpp
+++ b/tools/diagtool/DiagnosticNames.cpp
@@ -41,6 +41,7 @@
 #include "clang/Basic/DiagnosticCommentKinds.inc"
 #include "clang/Basic/DiagnosticSemaKinds.inc"
 #include "clang/Basic/DiagnosticAnalysisKinds.inc"
+#include "clang/Basic/DiagnosticRefactoringKinds.inc"
 #undef DIAG
 };
 
@@ -84,6 +85,11 @@
   return nullptr;
 }
 
+llvm::iterator_range<diagtool::GroupRecord::subgroup_iterator>
+GroupRecord::subgroups() const {
+  return llvm::make_range(subgroup_begin(), subgroup_end());
+}
+
 GroupRecord::diagnostics_iterator GroupRecord::diagnostics_begin() const {
   return DiagArrays + Members;
 }
@@ -92,6 +98,11 @@
   return nullptr;
 }
 
+llvm::iterator_range<diagtool::GroupRecord::diagnostics_iterator>
+GroupRecord::diagnostics() const {
+  return llvm::make_range(diagnostics_begin(), diagnostics_end());
+}
+
 llvm::ArrayRef<GroupRecord> diagtool::getDiagnosticGroups() {
   return llvm::makeArrayRef(OptionTable);
 }
diff --git a/tools/diagtool/DiagnosticNames.h b/tools/diagtool/DiagnosticNames.h
index ac1a098..598ae6a 100644
--- a/tools/diagtool/DiagnosticNames.h
+++ b/tools/diagtool/DiagnosticNames.h
@@ -20,7 +20,7 @@
     const char *NameStr;
     short DiagID;
     uint8_t NameLen;
-    
+
     llvm::StringRef getName() const {
       return llvm::StringRef(NameStr, NameLen);
     }
@@ -80,7 +80,7 @@
       bool operator==(group_iterator &Other) const {
         return CurrentID == Other.CurrentID;
       }
-      
+
       bool operator!=(group_iterator &Other) const {
         return CurrentID != Other.CurrentID;
       }
@@ -89,10 +89,12 @@
     typedef group_iterator<GroupRecord> subgroup_iterator;
     subgroup_iterator subgroup_begin() const;
     subgroup_iterator subgroup_end() const;
+    llvm::iterator_range<subgroup_iterator> subgroups() const;
 
     typedef group_iterator<DiagnosticRecord> diagnostics_iterator;
     diagnostics_iterator diagnostics_begin() const;
     diagnostics_iterator diagnostics_end() const;
+    llvm::iterator_range<diagnostics_iterator> diagnostics() const;
 
     bool operator<(llvm::StringRef Other) const {
       return getName() < Other;
diff --git a/tools/diagtool/ListWarnings.cpp b/tools/diagtool/ListWarnings.cpp
index 3e6e883..8bf9df9 100644
--- a/tools/diagtool/ListWarnings.cpp
+++ b/tools/diagtool/ListWarnings.cpp
@@ -23,7 +23,7 @@
 DEF_DIAGTOOL("list-warnings",
              "List warnings and their corresponding flags",
              ListWarnings)
-  
+
 using namespace clang;
 using namespace diagtool;
 
@@ -31,20 +31,19 @@
 struct Entry {
   llvm::StringRef DiagName;
   llvm::StringRef Flag;
-  
+
   Entry(llvm::StringRef diagN, llvm::StringRef flag)
     : DiagName(diagN), Flag(flag) {}
-  
+
   bool operator<(const Entry &x) const { return DiagName < x.DiagName; }
 };
 }
 
 static void printEntries(std::vector<Entry> &entries, llvm::raw_ostream &out) {
-  for (std::vector<Entry>::iterator it = entries.begin(), ei = entries.end();
-       it != ei; ++it) {
-    out << "  " << it->DiagName;
-    if (!it->Flag.empty())
-      out << " [-W" << it->Flag << "]";
+  for (const Entry &E : entries) {
+    out << "  " << E.DiagName;
+    if (!E.Flag.empty())
+      out << " [-W" << E.Flag << "]";
     out << '\n';
   }
 }
@@ -52,23 +51,18 @@
 int ListWarnings::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
   std::vector<Entry> Flagged, Unflagged;
   llvm::StringMap<std::vector<unsigned> > flagHistogram;
-  
-  ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();
 
-  for (ArrayRef<DiagnosticRecord>::iterator di = AllDiagnostics.begin(),
-                                            de = AllDiagnostics.end();
-       di != de; ++di) {
-    unsigned diagID = di->DiagID;
-    
+  for (const DiagnosticRecord &DR : getBuiltinDiagnosticsByName()) {
+    const unsigned diagID = DR.DiagID;
+
     if (DiagnosticIDs::isBuiltinNote(diagID))
       continue;
-        
+
     if (!DiagnosticIDs::isBuiltinWarningOrExtension(diagID))
       continue;
-  
-    Entry entry(di->getName(),
-                DiagnosticIDs::getWarningOptionForDiag(diagID));
-    
+
+    Entry entry(DR.getName(), DiagnosticIDs::getWarningOptionForDiag(diagID));
+
     if (entry.Flag.empty())
       Unflagged.push_back(entry);
     else {
@@ -76,24 +70,24 @@
       flagHistogram[entry.Flag].push_back(diagID);
     }
   }
-  
+
   out << "Warnings with flags (" << Flagged.size() << "):\n";
   printEntries(Flagged, out);
-  
+
   out << "Warnings without flags (" << Unflagged.size() << "):\n";
   printEntries(Unflagged, out);
 
   out << "\nSTATISTICS:\n\n";
 
-  double percentFlagged = ((double) Flagged.size()) 
-    / (Flagged.size() + Unflagged.size()) * 100.0;
-  
-  out << "  Percentage of warnings with flags: " 
-      << llvm::format("%.4g",percentFlagged) << "%\n";
-  
+  double percentFlagged =
+      ((double)Flagged.size()) / (Flagged.size() + Unflagged.size()) * 100.0;
+
+  out << "  Percentage of warnings with flags: "
+      << llvm::format("%.4g", percentFlagged) << "%\n";
+
   out << "  Number of unique flags: "
       << flagHistogram.size() << '\n';
-  
+
   double avgDiagsPerFlag = (double) Flagged.size() / flagHistogram.size();
   out << "  Average number of diagnostics per flag: "
       << llvm::format("%.4g", avgDiagsPerFlag) << '\n';
@@ -102,7 +96,7 @@
       << flagHistogram["pedantic"].size() << '\n';
 
   out << '\n';
-  
+
   return 0;
 }
 
diff --git a/tools/diagtool/ShowEnabledWarnings.cpp b/tools/diagtool/ShowEnabledWarnings.cpp
index e6ea786..513abc1 100644
--- a/tools/diagtool/ShowEnabledWarnings.cpp
+++ b/tools/diagtool/ShowEnabledWarnings.cpp
@@ -112,17 +112,14 @@
   // which ones are turned on.
   // FIXME: It would be very nice to print which flags are turning on which
   // diagnostics, but this can be done with a diff.
-  ArrayRef<DiagnosticRecord> AllDiagnostics = getBuiltinDiagnosticsByName();
   std::vector<PrettyDiag> Active;
 
-  for (ArrayRef<DiagnosticRecord>::iterator I = AllDiagnostics.begin(),
-                                            E = AllDiagnostics.end();
-       I != E; ++I) {
-    unsigned DiagID = I->DiagID;
-    
+  for (const DiagnosticRecord &DR : getBuiltinDiagnosticsByName()) {
+    unsigned DiagID = DR.DiagID;
+
     if (DiagnosticIDs::isBuiltinNote(DiagID))
       continue;
-    
+
     if (!DiagnosticIDs::isBuiltinWarningOrExtension(DiagID))
       continue;
 
@@ -132,17 +129,16 @@
       continue;
 
     StringRef WarningOpt = DiagnosticIDs::getWarningOptionForDiag(DiagID);
-    Active.push_back(PrettyDiag(I->getName(), WarningOpt, DiagLevel));
+    Active.push_back(PrettyDiag(DR.getName(), WarningOpt, DiagLevel));
   }
 
   // Print them all out.
-  for (std::vector<PrettyDiag>::const_iterator I = Active.begin(),
-       E = Active.end(); I != E; ++I) {
+  for (const PrettyDiag &PD : Active) {
     if (ShouldShowLevels)
-      Out << getCharForLevel(I->Level) << "  ";
-    Out << I->Name;
-    if (!I->Flag.empty())
-      Out << " [-W" << I->Flag << "]";
+      Out << getCharForLevel(PD.Level) << "  ";
+    Out << PD.Name;
+    if (!PD.Flag.empty())
+      Out << " [-W" << PD.Flag << "]";
     Out << '\n';
   }
 
diff --git a/tools/diagtool/TreeView.cpp b/tools/diagtool/TreeView.cpp
index 07af944..b4846b5 100644
--- a/tools/diagtool/TreeView.cpp
+++ b/tools/diagtool/TreeView.cpp
@@ -32,10 +32,10 @@
 public:
   llvm::raw_ostream &out;
   const bool ShowColors;
-  bool FlagsOnly;
+  bool Internal;
 
   TreePrinter(llvm::raw_ostream &out)
-      : out(out), ShowColors(hasColors(out)), FlagsOnly(false) {}
+      : out(out), ShowColors(hasColors(out)), Internal(false) {}
 
   void setColor(llvm::raw_ostream::Colors Color) {
     if (ShowColors)
@@ -54,28 +54,42 @@
     return Diags.isIgnored(DiagID, SourceLocation());
   }
 
+  static bool enabledByDefault(const GroupRecord &Group) {
+    for (const DiagnosticRecord &DR : Group.diagnostics()) {
+      if (isIgnored(DR.DiagID))
+        return false;
+    }
+
+    for (const GroupRecord &GR : Group.subgroups()) {
+      if (!enabledByDefault(GR))
+        return false;
+    }
+
+    return true;
+  }
+
   void printGroup(const GroupRecord &Group, unsigned Indent = 0) {
     out.indent(Indent * 2);
 
-    setColor(llvm::raw_ostream::YELLOW);
+    if (enabledByDefault(Group))
+      setColor(llvm::raw_ostream::GREEN);
+    else
+      setColor(llvm::raw_ostream::YELLOW);
+
     out << "-W" << Group.getName() << "\n";
     resetColor();
 
     ++Indent;
-    for (GroupRecord::subgroup_iterator I = Group.subgroup_begin(),
-                                        E = Group.subgroup_end();
-         I != E; ++I) {
-      printGroup(*I, Indent);
+    for (const GroupRecord &GR : Group.subgroups()) {
+      printGroup(GR, Indent);
     }
 
-    if (!FlagsOnly) {
-      for (GroupRecord::diagnostics_iterator I = Group.diagnostics_begin(),
-                                             E = Group.diagnostics_end();
-           I != E; ++I) {
-        if (ShowColors && !isIgnored(I->DiagID))
+    if (Internal) {
+      for (const DiagnosticRecord &DR : Group.diagnostics()) {
+        if (ShowColors && !isIgnored(DR.DiagID))
           setColor(llvm::raw_ostream::GREEN);
         out.indent(Indent * 2);
-        out << I->getName();
+        out << DR.getName();
         resetColor();
         out << "\n";
       }
@@ -107,12 +121,9 @@
     ArrayRef<GroupRecord> AllGroups = getDiagnosticGroups();
     llvm::DenseSet<unsigned> NonRootGroupIDs;
 
-    for (ArrayRef<GroupRecord>::iterator I = AllGroups.begin(),
-                                         E = AllGroups.end();
-         I != E; ++I) {
-      for (GroupRecord::subgroup_iterator SI = I->subgroup_begin(),
-                                          SE = I->subgroup_end();
-           SI != SE; ++SI) {
+    for (const GroupRecord &GR : AllGroups) {
+      for (auto SI = GR.subgroup_begin(), SE = GR.subgroup_end(); SI != SE;
+           ++SI) {
         NonRootGroupIDs.insert((unsigned)SI.getID());
       }
     }
@@ -139,16 +150,16 @@
 };
 
 static void printUsage() {
-  llvm::errs() << "Usage: diagtool tree [--flags-only] [<diagnostic-group>]\n";
+  llvm::errs() << "Usage: diagtool tree [--internal] [<diagnostic-group>]\n";
 }
 
 int TreeView::run(unsigned int argc, char **argv, llvm::raw_ostream &out) {
   // First check our one flag (--flags-only).
-  bool FlagsOnly = false;
+  bool Internal = false;
   if (argc > 0) {
     StringRef FirstArg(*argv);
-    if (FirstArg.equals("--flags-only")) {
-      FlagsOnly = true;
+    if (FirstArg.equals("--internal")) {
+      Internal = true;
       --argc;
       ++argv;
     }
@@ -175,7 +186,7 @@
   }
 
   TreePrinter TP(out);
-  TP.FlagsOnly = FlagsOnly;
+  TP.Internal = Internal;
   TP.showKey();
   return ShowAll ? TP.showAll() : TP.showGroup(RootGroup);
 }
diff --git a/tools/driver/CMakeLists.txt b/tools/driver/CMakeLists.txt
index 901b6d6..0e77fc2 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/cc1as_main.cpp b/tools/driver/cc1as_main.cpp
index 2fc2b50..4ede950 100644
--- a/tools/driver/cc1as_main.cpp
+++ b/tools/driver/cc1as_main.cpp
@@ -356,7 +356,7 @@
     PIC = false;
   }
 
-  MOFI->InitMCObjectFileInfo(Triple(Opts.Triple), PIC, CodeModel::Default, Ctx);
+  MOFI->InitMCObjectFileInfo(Triple(Opts.Triple), PIC, Ctx);
   if (Opts.SaveTemporaryLabels)
     Ctx.setAllowTemporaryLabels(false);
   if (Opts.GenDwarfForAssembly)
diff --git a/tools/driver/driver.cpp b/tools/driver/driver.cpp
index 9f37c42..fd85a56 100644
--- a/tools/driver/driver.cpp
+++ b/tools/driver/driver.cpp
@@ -205,6 +205,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,
@@ -306,6 +308,8 @@
     return cc1_main(argv.slice(2), argv[0], GetExecutablePathVP);
   if (Tool == "as")
     return cc1as_main(argv.slice(2), argv[0], GetExecutablePathVP);
+  if (Tool == "apinotes")
+    return cc1apinotes_main(argv.slice(2), argv[0], GetExecutablePathVP);
 
   // Reject unknown tools.
   llvm::errs() << "error: unknown integrated tool '" << Tool << "'\n";
diff --git a/tools/libclang/CIndexDiagnostic.cpp b/tools/libclang/CIndexDiagnostic.cpp
index 4e47b25..9ac1819 100644
--- a/tools/libclang/CIndexDiagnostic.cpp
+++ b/tools/libclang/CIndexDiagnostic.cpp
@@ -146,7 +146,20 @@
 
   CXDiagnosticSetImpl *CurrentSet;
   CXDiagnosticSetImpl *MainSet;
-};  
+};
+
+class CXStoredDiagnosticSet : public CXDiagnosticSetImpl {
+  llvm::SmallVector<StoredDiagnostic, 2> Diags;
+
+public:
+  CXStoredDiagnosticSet(ArrayRef<StoredDiagnostic> Diags,
+                        const LangOptions &LangOpts)
+      : CXDiagnosticSetImpl(/*isManaged=*/true),
+        Diags(Diags.begin(), Diags.end()) {
+    for (const auto &Diag : this->Diags)
+      appendDiagnostic(llvm::make_unique<CXStoredDiagnostic>(Diag, LangOpts));
+  }
+};
 }
 
 CXDiagnosticSetImpl *cxdiag::lazyCreateDiags(CXTranslationUnit TU,
@@ -196,6 +209,11 @@
   return static_cast<CXDiagnosticSetImpl*>(TU->Diagnostics);
 }
 
+CXDiagnosticSetImpl *cxdiag::createStoredDiags(ArrayRef<StoredDiagnostic> Diags,
+                                               const LangOptions &LangOpts) {
+  return new CXStoredDiagnosticSet(Diags, LangOpts);
+}
+
 //-----------------------------------------------------------------------------
 // C Interface Routines
 //-----------------------------------------------------------------------------
diff --git a/tools/libclang/CIndexDiagnostic.h b/tools/libclang/CIndexDiagnostic.h
index 9f40698..468f9bc 100644
--- a/tools/libclang/CIndexDiagnostic.h
+++ b/tools/libclang/CIndexDiagnostic.h
@@ -14,6 +14,7 @@
 #define LLVM_CLANG_TOOLS_LIBCLANG_CINDEXDIAGNOSTIC_H
 
 #include "clang-c/Index.h"
+#include "clang/Basic/LLVM.h"
 #include <memory>
 #include <vector>
 #include <assert.h>
@@ -158,6 +159,9 @@
 namespace cxdiag {
 CXDiagnosticSetImpl *lazyCreateDiags(CXTranslationUnit TU,
                                      bool checkIfChanged = false);
+
+CXDiagnosticSetImpl *createStoredDiags(ArrayRef<StoredDiagnostic> Diags,
+                                       const LangOptions &LangOpts);
 } // end namespace cxdiag
 
 } // end namespace clang
diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt
index 2dd6703..dbad06a 100644
--- a/tools/libclang/CMakeLists.txt
+++ b/tools/libclang/CMakeLists.txt
@@ -9,6 +9,7 @@
   CIndexInclusionStack.cpp
   CIndexUSRs.cpp
   CIndexer.cpp
+  CRefactor.cpp
   CXComment.cpp
   CXCursor.cpp
   CXIndexDataConsumer.cpp
@@ -35,6 +36,7 @@
 
 set(LIBS
   clangAST
+  clangAPINotes
   clangBasic
   clangFrontend
   clangIndex
diff --git a/tools/libclang/CRefactor.cpp b/tools/libclang/CRefactor.cpp
new file mode 100644
index 0000000..45f21ba
--- /dev/null
+++ b/tools/libclang/CRefactor.cpp
@@ -0,0 +1,1948 @@
+//===- CRefactor.cpp - Refactoring API hooks ------------------------------===//
+//
+//                     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 Clang-C refactoring library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CIndexDiagnostic.h"
+#include "CIndexer.h"
+#include "CLog.h"
+#include "CXCursor.h"
+#include "CXSourceLocation.h"
+#include "CXString.h"
+#include "CXTranslationUnit.h"
+#include "clang-c/Refactor.h"
+#include "clang/AST/ASTConsumer.h"
+#include "clang/Basic/DiagnosticCategories.h"
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/Utils.h"
+#include "clang/Index/USRGeneration.h"
+#include "clang/Tooling/Refactor/IndexerQuery.h"
+#include "clang/Tooling/Refactor/RefactoringActionFinder.h"
+#include "clang/Tooling/Refactor/RefactoringActions.h"
+#include "clang/Tooling/Refactor/RefactoringOperation.h"
+#include "clang/Tooling/Refactor/RefactoringOptions.h"
+#include "clang/Tooling/Refactor/RenameIndexedFile.h"
+#include "clang/Tooling/Refactor/RenamingOperation.h"
+#include "clang/Tooling/Refactor/SymbolOccurrenceFinder.h"
+#include "clang/Tooling/Refactor/USRFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
+#include <set>
+#include <vector>
+
+using namespace clang;
+using namespace clang::tooling;
+
+static RefactoringActionType
+translateRefactoringActionType(CXRefactoringActionType Action) {
+  switch (Action) {
+#define REFACTORING_ACTION(Name, Spelling)                                     \
+  case CXRefactor_##Name:                                                      \
+    return RefactoringActionType::Name;
+#include "clang/Tooling/Refactor/RefactoringActions.def"
+  }
+}
+
+static CXRefactoringActionType
+translateRefactoringActionType(RefactoringActionType Action) {
+  switch (Action) {
+#define REFACTORING_ACTION(Name, Spelling)                                     \
+  case RefactoringActionType::Name:                                            \
+    return CXRefactor_##Name;
+#include "clang/Tooling/Refactor/RefactoringActions.def"
+  }
+}
+
+static CXSymbolOccurrenceKind
+translateOccurrenceKind(rename::SymbolOccurrence::OccurrenceKind Kind) {
+  switch (Kind) {
+  case rename::SymbolOccurrence::MatchingSymbol:
+    return CXSymbolOccurrence_MatchingSymbol;
+  case rename::SymbolOccurrence::MatchingSelector:
+    return CXSymbolOccurrence_MatchingSelector;
+  case rename::SymbolOccurrence::MatchingImplicitProperty:
+    return CXSymbolOccurrence_MatchingImplicitProperty;
+  case rename::SymbolOccurrence::MatchingComment:
+    return CXSymbolOccurrence_MatchingCommentString;
+  case rename::SymbolOccurrence::MatchingDocComment:
+    return CXSymbolOccurrence_MatchingDocCommentString;
+  case rename::SymbolOccurrence::MatchingFilename:
+    return CXSymbolOccurrence_MatchingFilename;
+  }
+}
+
+namespace {
+
+// TODO: Remove
+class RenamingResult {
+  struct RenamedNameString {
+    CXString NewString;
+    unsigned OldLength;
+  };
+  typedef SmallVector<RenamedNameString, 4> SymbolNameInfo;
+  std::vector<SymbolNameInfo> NameInfo;
+
+  /// The set of files that have to be modified.
+  llvm::SmallVector<CXString, 2> Filenames;
+  llvm::SpecificBumpPtrAllocator<CXRefactoringReplacement_Old> Replacements;
+  std::vector<std::vector<CXRenamedSymbolOccurrence>> Occurrences;
+
+  void addOccurrence(const rename::SymbolOccurrence &RenamedOccurrence,
+                     const SourceManager &SM, const LangOptions &LangOpts) {
+    CXRefactoringReplacement_Old *OccurrenceReplacements =
+        Replacements.Allocate(RenamedOccurrence.locations().size());
+
+    unsigned I = 0;
+    const auto &SymbolNameInfo = NameInfo[RenamedOccurrence.SymbolIndex];
+    if (!RenamedOccurrence.IsMacroExpansion &&
+        RenamedOccurrence.Kind != rename::SymbolOccurrence::MatchingComment &&
+        RenamedOccurrence.Kind != rename::SymbolOccurrence::MatchingDocComment)
+      assert(RenamedOccurrence.locations().size() == SymbolNameInfo.size());
+    for (const auto &Location : RenamedOccurrence.locations()) {
+      CXSourceRange Range = cxloc::translateSourceRange(
+          SM, LangOpts,
+          CharSourceRange::getCharRange(RenamedOccurrence.getLocationRange(
+              Location, SymbolNameInfo[I].OldLength)));
+      CXFileLocation Begin, End;
+      clang_getFileLocation(clang_getRangeStart(Range), nullptr, &Begin.Line,
+                            &Begin.Column, nullptr);
+      clang_getFileLocation(clang_getRangeEnd(Range), nullptr, &End.Line,
+                            &End.Column, nullptr);
+
+      OccurrenceReplacements[I] = CXRefactoringReplacement_Old{
+          {Begin, End},
+          RenamedOccurrence.IsMacroExpansion ? cxstring::createNull()
+                                             : SymbolNameInfo[I].NewString};
+      ++I;
+    }
+
+    Occurrences.back().push_back(CXRenamedSymbolOccurrence{
+        OccurrenceReplacements, I,
+        translateOccurrenceKind(RenamedOccurrence.Kind),
+        RenamedOccurrence.IsMacroExpansion});
+  }
+
+public:
+  RenamingResult(ArrayRef<SymbolName> NewNames,
+                 ArrayRef<rename::Symbol> Symbols) {
+    assert(NewNames.size() == Symbols.size());
+    for (size_t I = 0, E = NewNames.size(); I != E; ++I) {
+      const auto &NewName = NewNames[I];
+      const auto &OldName = Symbols[I].Name;
+
+      assert(NewName.size() == OldName.size());
+      SymbolNameInfo Info;
+      for (size_t I = 0, E = NewName.size(); I != E; ++I)
+        Info.push_back(RenamedNameString{cxstring::createDup(NewName[I]),
+                                         (unsigned)OldName[I].size()});
+      NameInfo.push_back(std::move(Info));
+    }
+  }
+
+  // FIXME: Don't duplicate code, Use just one constructor.
+  RenamingResult(ArrayRef<SymbolName> NewNames, ArrayRef<SymbolName> OldNames) {
+    assert(NewNames.size() == OldNames.size());
+    for (size_t I = 0, E = NewNames.size(); I != E; ++I) {
+      const auto &NewName = NewNames[I];
+      const auto &OldName = OldNames[I];
+
+      assert(NewName.size() == OldName.size());
+      SymbolNameInfo Info;
+      for (size_t I = 0, E = NewName.size(); I != E; ++I)
+        Info.push_back(RenamedNameString{cxstring::createDup(NewName[I]),
+                                         (unsigned)OldName[I].size()});
+      NameInfo.push_back(std::move(Info));
+    }
+  }
+
+  ~RenamingResult() {
+    for (const auto &SymbolInfo : NameInfo)
+      for (const auto &NameString : SymbolInfo)
+        clang_disposeString(NameString.NewString);
+    for (const auto &Filename : Filenames)
+      clang_disposeString(Filename);
+  }
+
+  void
+  handleTUResults(CXTranslationUnit TU,
+                  llvm::MutableArrayRef<rename::SymbolOccurrence> Results) {
+    ASTUnit *Unit = cxtu::getASTUnit(TU);
+    assert(Unit && "Invalid TU");
+    auto &Ctx = Unit->getASTContext();
+
+    // Find the set of files that have to be modified and gather the indices of
+    // the occurrences for each file.
+    const SourceManager &SM = Ctx.getSourceManager();
+    typedef std::set<rename::SymbolOccurrence> OccurrenceSet;
+    llvm::StringMap<OccurrenceSet> FilenamesToSymbolOccurrences;
+    for (auto &Occurrence : Results) {
+      const std::pair<FileID, unsigned> DecomposedLocation =
+          SM.getDecomposedLoc(Occurrence.locations()[0]);
+      const FileEntry *Entry = SM.getFileEntryForID(DecomposedLocation.first);
+      assert(Entry && "Invalid file entry");
+      auto &FileOccurrences =
+          FilenamesToSymbolOccurrences
+              .try_emplace(Entry->getName(), OccurrenceSet())
+              .first->getValue();
+      FileOccurrences.insert(std::move(Occurrence));
+    }
+
+    // Create the filenames
+    for (const auto &FilenameCount : FilenamesToSymbolOccurrences)
+      Filenames.push_back(cxstring::createDup(FilenameCount.getKey()));
+
+    unsigned FileIndex = 0;
+    for (const auto &RenamedOccurrences : FilenamesToSymbolOccurrences) {
+      assert(clang_getCString(Filenames[FileIndex]) ==
+                 RenamedOccurrences.getKey() &&
+             "Unstable iteration order");
+      Occurrences.push_back(std::vector<CXRenamedSymbolOccurrence>());
+      for (const auto &Occurrence : RenamedOccurrences.getValue())
+        addOccurrence(Occurrence, SM, Ctx.getLangOpts());
+      ++FileIndex;
+    }
+  }
+
+  void addMainFilename(const SourceManager &SM) {
+    assert(Filenames.empty() && "Main filename should be added only once");
+    Filenames.push_back(cxstring::createDup(
+        SM.getFileEntryForID(SM.getMainFileID())->getName()));
+    Occurrences.push_back(std::vector<CXRenamedSymbolOccurrence>());
+  }
+
+  void
+  handleSingleFileTUResults(const ASTContext &Ctx,
+                            ArrayRef<rename::SymbolOccurrence> Occurrences) {
+    addMainFilename(Ctx.getSourceManager());
+    for (const auto &Occurrence : Occurrences)
+      addOccurrence(Occurrence, Ctx.getSourceManager(), Ctx.getLangOpts());
+  }
+
+  void handleIndexedFileOccurrence(const rename::SymbolOccurrence &Occurrence,
+                                   const SourceManager &SM,
+                                   const LangOptions &LangOpts) {
+    if (Filenames.empty()) {
+      addMainFilename(SM);
+    }
+    addOccurrence(Occurrence, SM, LangOpts);
+  }
+
+  ArrayRef<CXRenamedSymbolOccurrence> getOccurrences(unsigned FileIndex) const {
+    return Occurrences[FileIndex];
+  }
+
+  ArrayRef<CXString> getFilenames() const { return Filenames; }
+};
+
+class SymbolOccurrencesResult {
+  struct SymbolNamePiece {
+    unsigned OldLength;
+  };
+  typedef SmallVector<SymbolNamePiece, 4> SymbolNameInfo;
+  std::vector<SymbolNameInfo> NameInfo;
+
+  /// The set of files that have to be modified.
+  llvm::SmallVector<CXString, 2> Filenames;
+  llvm::SpecificBumpPtrAllocator<CXFileRange> Ranges;
+  std::vector<std::vector<CXSymbolOccurrence>> SymbolOccurrences;
+
+  void addOccurrence(const rename::SymbolOccurrence &RenamedOccurrence,
+                     const SourceManager &SM, const LangOptions &LangOpts) {
+    ArrayRef<SourceLocation> Locations = RenamedOccurrence.locations();
+    CXFileRange *OccurrenceRanges = Ranges.Allocate(Locations.size());
+
+    unsigned I = 0;
+    const auto &SymbolNameInfo = NameInfo[RenamedOccurrence.SymbolIndex];
+    if (!RenamedOccurrence.IsMacroExpansion &&
+        RenamedOccurrence.Kind != rename::SymbolOccurrence::MatchingComment &&
+        RenamedOccurrence.Kind != rename::SymbolOccurrence::MatchingDocComment)
+      assert(Locations.size() == SymbolNameInfo.size());
+    for (const auto &Location : Locations) {
+      CXSourceRange Range = cxloc::translateSourceRange(
+          SM, LangOpts,
+          CharSourceRange::getCharRange(RenamedOccurrence.getLocationRange(
+              Location, SymbolNameInfo[I].OldLength)));
+      CXFileLocation Begin, End;
+      clang_getFileLocation(clang_getRangeStart(Range), nullptr, &Begin.Line,
+                            &Begin.Column, nullptr);
+      clang_getFileLocation(clang_getRangeEnd(Range), nullptr, &End.Line,
+                            &End.Column, nullptr);
+      OccurrenceRanges[I] = CXFileRange{Begin, End};
+      ++I;
+    }
+
+    SymbolOccurrences.back().push_back(CXSymbolOccurrence{
+        OccurrenceRanges, /*NumNamePieces=*/I,
+        translateOccurrenceKind(RenamedOccurrence.Kind),
+        RenamedOccurrence.IsMacroExpansion, RenamedOccurrence.SymbolIndex});
+  }
+
+public:
+  SymbolOccurrencesResult(ArrayRef<rename::Symbol> Symbols) {
+    for (const auto &Symbol : Symbols) {
+      const SymbolName &Name = Symbol.Name;
+      SymbolNameInfo Info;
+      for (size_t I = 0, E = Name.size(); I != E; ++I)
+        Info.push_back(SymbolNamePiece{(unsigned)Name[I].size()});
+      NameInfo.push_back(std::move(Info));
+    }
+  }
+
+  SymbolOccurrencesResult(ArrayRef<SymbolName> Names) {
+    for (const SymbolName &Name : Names) {
+      SymbolNameInfo Info;
+      for (size_t I = 0, E = Name.size(); I != E; ++I)
+        Info.push_back(SymbolNamePiece{(unsigned)Name[I].size()});
+      NameInfo.push_back(std::move(Info));
+    }
+  }
+
+  ~SymbolOccurrencesResult() {
+    for (const auto &Filename : Filenames)
+      clang_disposeString(Filename);
+  }
+
+  void
+  handleTUResults(CXTranslationUnit TU,
+                  llvm::MutableArrayRef<rename::SymbolOccurrence> Results) {
+    ASTUnit *Unit = cxtu::getASTUnit(TU);
+    assert(Unit && "Invalid TU");
+    auto &Ctx = Unit->getASTContext();
+
+    // Find the set of files that have to be modified and gather the indices of
+    // the occurrences for each file.
+    const SourceManager &SM = Ctx.getSourceManager();
+    typedef std::set<rename::SymbolOccurrence> OccurrenceSet;
+    llvm::StringMap<OccurrenceSet> FilenamesToSymbolOccurrences;
+    for (auto &Occurrence : Results) {
+      const std::pair<FileID, unsigned> DecomposedLocation =
+          SM.getDecomposedLoc(Occurrence.locations()[0]);
+      const FileEntry *Entry = SM.getFileEntryForID(DecomposedLocation.first);
+      assert(Entry && "Invalid file entry");
+      auto &FileOccurrences =
+          FilenamesToSymbolOccurrences
+              .try_emplace(Entry->getName(), OccurrenceSet())
+              .first->getValue();
+      FileOccurrences.insert(std::move(Occurrence));
+    }
+
+    // Create the filenames
+    for (const auto &FilenameCount : FilenamesToSymbolOccurrences)
+      Filenames.push_back(cxstring::createDup(FilenameCount.getKey()));
+
+    unsigned FileIndex = 0;
+    for (const auto &RenamedOccurrences : FilenamesToSymbolOccurrences) {
+      assert(clang_getCString(Filenames[FileIndex]) ==
+                 RenamedOccurrences.getKey() &&
+             "Unstable iteration order");
+      SymbolOccurrences.push_back(std::vector<CXSymbolOccurrence>());
+      for (const auto &Occurrence : RenamedOccurrences.getValue())
+        addOccurrence(Occurrence, SM, Ctx.getLangOpts());
+      ++FileIndex;
+    }
+  }
+
+  void addMainFilename(const SourceManager &SM) {
+    assert(Filenames.empty() && "Main filename should be added only once");
+    Filenames.push_back(cxstring::createDup(
+        SM.getFileEntryForID(SM.getMainFileID())->getName()));
+    SymbolOccurrences.push_back(std::vector<CXSymbolOccurrence>());
+  }
+
+  void handleIndexedFileOccurrence(const rename::SymbolOccurrence &Occurrence,
+                                   const SourceManager &SM,
+                                   const LangOptions &LangOpts) {
+    if (Filenames.empty()) {
+      addMainFilename(SM);
+    }
+    addOccurrence(Occurrence, SM, LangOpts);
+  }
+
+  ArrayRef<CXSymbolOccurrence> getOccurrences(unsigned FileIndex) const {
+    return SymbolOccurrences[FileIndex];
+  }
+
+  ArrayRef<CXString> getFilenames() const { return Filenames; }
+};
+
+class RenamingAction {
+public:
+  LangOptions LangOpts;
+  IdentifierTable IDs;
+  // TODO: Remove
+  SmallVector<SymbolName, 4> NewNames;
+  SymbolOperation Operation;
+
+  RenamingAction(const LangOptions &LangOpts, SymbolOperation Operation)
+      : LangOpts(LangOpts), IDs(LangOpts), Operation(std::move(Operation)) {}
+
+  /// \brief Sets the new renaming name and returns CXError_Success on success.
+  // TODO: Remove
+  CXErrorCode setNewName(StringRef Name) {
+    SymbolName NewSymbolName(Name, LangOpts);
+    if (NewSymbolName.size() != Operation.symbols()[0].Name.size())
+      return CXError_RefactoringNameSizeMismatch;
+    if (!rename::isNewNameValid(NewSymbolName, Operation, IDs, LangOpts))
+      return CXError_RefactoringNameInvalid;
+    rename::determineNewNames(std::move(NewSymbolName), Operation, NewNames,
+                              LangOpts);
+    return CXError_Success;
+  }
+
+  // TODO: Remove
+  CXString usrForSymbolAt(unsigned Index) {
+    llvm::SmallVector<char, 128> Buff;
+    if (index::generateUSRForDecl(Operation.symbols()[Index].FoundDecl, Buff))
+      return cxstring::createNull();
+    return cxstring::createDup(StringRef(Buff.begin(), Buff.size()));
+  }
+
+  // TODO: Remove
+  CXString getUSRThatRequiresImplementationTU() {
+    llvm::SmallVector<char, 128> Buff;
+    if (!Operation.requiresImplementationTU() ||
+        index::generateUSRForDecl(Operation.declThatRequiresImplementationTU(),
+                                  Buff))
+      return cxstring::createNull();
+    return cxstring::createDup(StringRef(Buff.begin(), Buff.size()));
+  }
+
+  // TODO: Remove
+  RenamingResult *handlePrimaryTU(CXTranslationUnit TU, ASTUnit &Unit) {
+    // Perform the renaming.
+    if (NewNames.empty())
+      return nullptr;
+
+    const ASTContext &Context = Unit.getASTContext();
+    auto Occurrences = rename::findSymbolOccurrences(
+        Operation, Context.getTranslationUnitDecl());
+    auto *Result = new RenamingResult(NewNames, Operation.symbols());
+    Result->handleTUResults(TU, Occurrences);
+    return Result;
+  }
+
+  SymbolOccurrencesResult *findSymbolsInInitiationTU(CXTranslationUnit TU,
+                                                     ASTUnit &Unit) {
+    const ASTContext &Context = Unit.getASTContext();
+    auto Occurrences = rename::findSymbolOccurrences(
+        Operation, Context.getTranslationUnitDecl());
+    auto *Result = new SymbolOccurrencesResult(Operation.symbols());
+    Result->handleTUResults(TU, Occurrences);
+    return Result;
+  }
+};
+
+static bool isObjCSelectorKind(CXCursorKind Kind) {
+  return Kind == CXCursor_ObjCInstanceMethodDecl ||
+         Kind == CXCursor_ObjCClassMethodDecl ||
+         Kind == CXCursor_ObjCMessageExpr;
+}
+
+// TODO: Remove
+static bool isObjCSelector(const CXRenamedIndexedSymbol &Symbol) {
+  if (isObjCSelectorKind(Symbol.CursorKind))
+    return true;
+  for (const auto &Occurrence : llvm::makeArrayRef(
+           Symbol.IndexedLocations, Symbol.IndexedLocationCount)) {
+    if (isObjCSelectorKind(Occurrence.CursorKind))
+      return true;
+  }
+  return false;
+}
+
+static bool isObjCSelector(const CXIndexedSymbol &Symbol) {
+  if (isObjCSelectorKind(Symbol.CursorKind))
+    return true;
+  for (const auto &Occurrence : llvm::makeArrayRef(
+           Symbol.IndexedLocations, Symbol.IndexedLocationCount)) {
+    if (isObjCSelectorKind(Occurrence.CursorKind))
+      return true;
+  }
+  return false;
+}
+
+// New names are initialized and verified after the LangOptions are created.
+CXErrorCode computeNewNames(ArrayRef<CXRenamedIndexedSymbol> Symbols,
+                            ArrayRef<SymbolName> SymbolNames,
+                            const LangOptions &LangOpts,
+                            SmallVectorImpl<SymbolName> &NewNames) {
+  IdentifierTable IDs(LangOpts);
+  for (const auto &Symbol : Symbols) {
+    SymbolName NewSymbolName(Symbol.NewName, LangOpts);
+    if (NewSymbolName.size() != SymbolNames[0].size())
+      return CXError_RefactoringNameSizeMismatch;
+    if (!rename::isNewNameValid(NewSymbolName, isObjCSelector(Symbol), IDs,
+                                LangOpts))
+      return CXError_RefactoringNameInvalid;
+    NewNames.push_back(std::move(NewSymbolName));
+  }
+  return CXError_Success;
+}
+
+static rename::IndexedOccurrence::OccurrenceKind
+translateIndexedOccurrenceKind(CXCursorKind Kind) {
+  switch (Kind) {
+  case CXCursor_ObjCMessageExpr:
+    return rename::IndexedOccurrence::IndexedObjCMessageSend;
+  case CXCursor_InclusionDirective:
+    return rename::IndexedOccurrence::InclusionDirective;
+  default:
+    return rename::IndexedOccurrence::IndexedSymbol;
+  }
+}
+
+// TODO: Remove
+CXErrorCode performIndexedFileRename(
+    ArrayRef<CXRenamedIndexedSymbol> Symbols, StringRef Filename,
+    ArrayRef<const char *> Arguments, CXIndex CIdx,
+    MutableArrayRef<CXUnsavedFile> UnsavedFiles,
+    const RefactoringOptionSet *Options, CXRenamingResult &Result) {
+  Result = nullptr;
+
+  // Adjust the given command line arguments to ensure that any positional
+  // arguments in them are stripped.
+  std::vector<const char *> ClangToolArguments;
+  ClangToolArguments.push_back("--");
+  for (const auto &Arg : Arguments) {
+    // Remove the '-gmodules' option, as the -fmodules-format=obj isn't
+    // supported without the linked object reader.
+    if (StringRef(Arg) == "-gmodules")
+      continue;
+    ClangToolArguments.push_back(Arg);
+  }
+  int Argc = ClangToolArguments.size();
+  std::string ErrorMessage;
+  std::unique_ptr<CompilationDatabase> Compilations =
+      FixedCompilationDatabase::loadFromCommandLine(
+          Argc, ClangToolArguments.data(), ErrorMessage);
+  if (!Compilations) {
+    llvm::errs() << "CRefactor: Failed to load command line: " << ErrorMessage
+                 << "\n";
+    return CXError_Failure;
+  }
+
+  // Translate the symbols.
+  llvm::SmallVector<rename::IndexedSymbol, 4> IndexedSymbols;
+  for (const auto &Symbol : Symbols) {
+
+    // Parse the symbol name.
+    bool IsObjCSelector = false;
+    // Selectors have to be parsed.
+    if (isObjCSelector(Symbol))
+      IsObjCSelector = true;
+    // Ensure that we don't get selectors with incorrect symbol kind.
+    else if (StringRef(Symbol.Name).contains(':'))
+      return CXError_InvalidArguments;
+
+    std::vector<rename::IndexedOccurrence> IndexedOccurrences;
+    for (const auto &Loc : llvm::makeArrayRef(Symbol.IndexedLocations,
+                                              Symbol.IndexedLocationCount)) {
+      rename::IndexedOccurrence Result;
+      Result.Line = Loc.Location.Line;
+      Result.Column = Loc.Location.Column;
+      Result.Kind = translateIndexedOccurrenceKind(Loc.CursorKind);
+      IndexedOccurrences.push_back(Result);
+    }
+
+    IndexedSymbols.emplace_back(SymbolName(Symbol.Name, IsObjCSelector),
+                                IndexedOccurrences,
+                                /*IsObjCSelector=*/IsObjCSelector);
+  }
+
+  class ToolRunner final : public FrontendActionFactory,
+                           public rename::IndexedFileOccurrenceConsumer {
+    ArrayRef<CXRenamedIndexedSymbol> Symbols;
+    ArrayRef<rename::IndexedSymbol> IndexedSymbols;
+    const RefactoringOptionSet *Options;
+
+  public:
+    RenamingResult *Result;
+    CXErrorCode Err;
+
+    ToolRunner(ArrayRef<CXRenamedIndexedSymbol> Symbols,
+               ArrayRef<rename::IndexedSymbol> IndexedSymbols,
+               const RefactoringOptionSet *Options)
+        : Symbols(Symbols), IndexedSymbols(IndexedSymbols), Options(Options),
+          Result(nullptr), Err(CXError_Success) {}
+
+    clang::FrontendAction *create() override {
+      return new rename::IndexedFileOccurrenceProducer(IndexedSymbols, *this,
+                                                       Options);
+    }
+
+    void handleOccurrence(const rename::SymbolOccurrence &Occurrence,
+                          SourceManager &SM,
+                          const LangOptions &LangOpts) override {
+      if (Err != CXError_Success)
+        return;
+      if (!Result) {
+        SmallVector<SymbolName, 4> SymbolNames;
+        for (const auto &Symbol : IndexedSymbols)
+          SymbolNames.push_back(Symbol.Name);
+        SmallVector<SymbolName, 4> NewNames;
+        Err = computeNewNames(Symbols, SymbolNames, LangOpts, NewNames);
+        if (Err != CXError_Success)
+          return;
+        Result = new RenamingResult(NewNames, SymbolNames);
+      }
+      Result->handleIndexedFileOccurrence(Occurrence, SM, LangOpts);
+    }
+  };
+
+  auto Runner = llvm::make_unique<ToolRunner>(Symbols, IndexedSymbols, Options);
+
+  // Run a clang tool on the input file.
+  std::string Name = Filename.str();
+  ClangTool Tool(*Compilations, Name);
+  Tool.run(Runner.get());
+  if (Runner->Err != CXError_Success)
+    return Runner->Err;
+  Result = Runner->Result;
+  return CXError_Success;
+}
+
+CXErrorCode performIndexedSymbolSearch(
+    ArrayRef<CXIndexedSymbol> Symbols, StringRef Filename,
+    ArrayRef<const char *> Arguments, CXIndex CIdx,
+    MutableArrayRef<CXUnsavedFile> UnsavedFiles,
+    const RefactoringOptionSet *Options, CXSymbolOccurrencesResult &Result) {
+  Result = nullptr;
+
+  // Adjust the given command line arguments to ensure that any positional
+  // arguments in them are stripped.
+  std::vector<const char *> ClangToolArguments;
+  ClangToolArguments.push_back("--");
+  for (const auto &Arg : Arguments) {
+    // Remove the '-gmodules' option, as the -fmodules-format=obj isn't
+    // supported without the linked object reader.
+    if (StringRef(Arg) == "-gmodules")
+      continue;
+    ClangToolArguments.push_back(Arg);
+  }
+  int Argc = ClangToolArguments.size();
+  std::string ErrorMessage;
+  std::unique_ptr<CompilationDatabase> Compilations =
+      FixedCompilationDatabase::loadFromCommandLine(
+          Argc, ClangToolArguments.data(), ErrorMessage);
+  if (!Compilations) {
+    llvm::errs() << "CRefactor: Failed to load command line: " << ErrorMessage
+                 << "\n";
+    return CXError_Failure;
+  }
+
+  // Translate the symbols.
+  llvm::SmallVector<rename::IndexedSymbol, 4> IndexedSymbols;
+  for (const auto &Symbol : Symbols) {
+
+    // Parse the symbol name.
+    bool IsObjCSelector = false;
+    // Selectors have to be parsed.
+    if (isObjCSelector(Symbol))
+      IsObjCSelector = true;
+    // Ensure that we don't get selectors with incorrect symbol kind.
+    else if (StringRef(Symbol.Name).contains(':'))
+      return CXError_InvalidArguments;
+
+    std::vector<rename::IndexedOccurrence> IndexedOccurrences;
+    for (const auto &Loc : llvm::makeArrayRef(Symbol.IndexedLocations,
+                                              Symbol.IndexedLocationCount)) {
+      rename::IndexedOccurrence Result;
+      Result.Line = Loc.Location.Line;
+      Result.Column = Loc.Location.Column;
+      Result.Kind = translateIndexedOccurrenceKind(Loc.CursorKind);
+      IndexedOccurrences.push_back(Result);
+    }
+
+    IndexedSymbols.emplace_back(SymbolName(Symbol.Name, IsObjCSelector),
+                                IndexedOccurrences,
+                                /*IsObjCSelector=*/IsObjCSelector);
+  }
+
+  class ToolRunner final : public FrontendActionFactory,
+                           public rename::IndexedFileOccurrenceConsumer {
+    ArrayRef<rename::IndexedSymbol> IndexedSymbols;
+    const RefactoringOptionSet *Options;
+
+  public:
+    SymbolOccurrencesResult *Result;
+
+    ToolRunner(ArrayRef<rename::IndexedSymbol> IndexedSymbols,
+               const RefactoringOptionSet *Options)
+        : IndexedSymbols(IndexedSymbols), Options(Options), Result(nullptr) {}
+
+    clang::FrontendAction *create() override {
+      return new rename::IndexedFileOccurrenceProducer(IndexedSymbols, *this,
+                                                       Options);
+    }
+
+    void handleOccurrence(const rename::SymbolOccurrence &Occurrence,
+                          SourceManager &SM,
+                          const LangOptions &LangOpts) override {
+      if (!Result) {
+        SmallVector<SymbolName, 4> SymbolNames;
+        for (const auto &Symbol : IndexedSymbols)
+          SymbolNames.push_back(Symbol.Name);
+        Result = new SymbolOccurrencesResult(SymbolNames);
+      }
+      Result->handleIndexedFileOccurrence(Occurrence, SM, LangOpts);
+    }
+  };
+
+  auto Runner = llvm::make_unique<ToolRunner>(IndexedSymbols, Options);
+
+  // Run a clang tool on the input file.
+  std::string Name = Filename.str();
+  ClangTool Tool(*Compilations, Name);
+  for (const CXUnsavedFile &File : UnsavedFiles)
+    Tool.mapVirtualFile(File.Filename, StringRef(File.Contents, File.Length));
+  if (Tool.run(Runner.get()))
+    return CXError_Failure;
+  Result = Runner->Result;
+  return CXError_Success;
+}
+
+class RefactoringAction {
+  std::unique_ptr<RefactoringOperation> Operation;
+  std::unique_ptr<RenamingAction> Rename;
+
+  SmallVector<CXRefactoringCandidate, 2> RefactoringCandidates;
+  CXRefactoringCandidateSet CandidateSet = {nullptr, 0};
+  bool HasCandidateSet = false;
+
+public:
+  CXRefactoringActionType Type;
+  unsigned SelectedCandidate = 0;
+  CXTranslationUnit InitiationTU;
+  // TODO: Remove (no longer needed due to continuations).
+  CXTranslationUnit ImplementationTU;
+
+  RefactoringAction(std::unique_ptr<RefactoringOperation> Operation,
+                    CXRefactoringActionType Type,
+                    CXTranslationUnit InitiationTU)
+      : Operation(std::move(Operation)), Type(Type), InitiationTU(InitiationTU),
+        ImplementationTU(nullptr) {}
+
+  RefactoringAction(std::unique_ptr<RenamingAction> Rename,
+                    CXTranslationUnit InitiationTU)
+      : Rename(std::move(Rename)),
+        Type(this->Rename->Operation.isLocal() ? CXRefactor_Rename_Local
+                                               : CXRefactor_Rename),
+        InitiationTU(InitiationTU), ImplementationTU(nullptr) {}
+
+  ~RefactoringAction() {
+    for (const auto &Candidate : RefactoringCandidates)
+      clang_disposeString(Candidate.Description);
+  }
+
+  RefactoringOperation *getOperation() const { return Operation.get(); }
+
+  RenamingAction *getRenamingAction() const { return Rename.get(); }
+
+  CXRefactoringCandidateSet getRefactoringCandidates() {
+    if (HasCandidateSet)
+      return CandidateSet;
+    HasCandidateSet = true;
+    RefactoringOperation *Operation = getOperation();
+    if (!Operation)
+      return CandidateSet;
+    auto Candidates = Operation->getRefactoringCandidates();
+    if (Candidates.empty())
+      return CandidateSet;
+    for (const auto &Candidate : Candidates)
+      RefactoringCandidates.push_back({cxstring::createDup(Candidate)});
+    CandidateSet = {RefactoringCandidates.data(),
+                    (unsigned)RefactoringCandidates.size()};
+    return CandidateSet;
+  }
+
+  CXErrorCode selectCandidate(unsigned Index) {
+    RefactoringOperation *Operation = getOperation();
+    if (!Operation)
+      return CXError_InvalidArguments;
+    if (Index != 0 && Index >= getRefactoringCandidates().NumCandidates)
+      return CXError_InvalidArguments;
+    SelectedCandidate = Index;
+    return CXError_Success;
+  }
+};
+
+static bool operator==(const CXFileLocation &LHS, const CXFileLocation &RHS) {
+  return LHS.Line == RHS.Line && LHS.Column == RHS.Column;
+}
+
+static CXFileRange translateOffsetToRelativeRange(unsigned Offset,
+                                                  unsigned Size,
+                                                  StringRef Source) {
+  assert(Source.drop_front(Offset).take_front(Size).count('\n') == 0 &&
+         "Newlines in translated range?");
+  StringRef Prefix = Source.take_front(Offset);
+  unsigned StartLines = Prefix.count('\n') + 1;
+  if (StartLines > 1)
+    Offset -= Prefix.rfind('\n') + 1;
+  return CXFileRange{{StartLines, Offset + 1}, {StartLines, Offset + 1 + Size}};
+}
+
+class RefactoringResultWrapper {
+public:
+  CXRefactoringReplacements_Old Replacements; // TODO: Remove.
+  CXRefactoringReplacements SourceReplacements;
+  std::unique_ptr<RefactoringContinuation> Continuation;
+  llvm::BumpPtrAllocator Allocator;
+  CXTranslationUnit TU;
+
+  struct AssociatedReplacementInfo {
+    CXSymbolOccurrence *AssociatedSymbolOccurrences;
+    unsigned NumAssociatedSymbolOccurrences;
+  };
+
+  ~RefactoringResultWrapper() {
+    // TODO: Remove.
+    for (unsigned I = 0; I < Replacements.NumFileReplacementSets; ++I) {
+      const CXRefactoringFileReplacementSet_Old &FileSet =
+          Replacements.FileReplacementSets[I];
+      clang_disposeString(FileSet.Filename);
+      for (unsigned J = 0; J < FileSet.NumReplacements; ++J)
+        clang_disposeString(FileSet.Replacements[J].ReplacementString);
+      delete[] FileSet.Replacements;
+    }
+    delete[] Replacements.FileReplacementSets;
+
+    for (unsigned I = 0; I < SourceReplacements.NumFileReplacementSets; ++I) {
+      const CXRefactoringFileReplacementSet &FileSet =
+          SourceReplacements.FileReplacementSets[I];
+      clang_disposeString(FileSet.Filename);
+      for (unsigned J = 0; J < FileSet.NumReplacements; ++J)
+        clang_disposeString(FileSet.Replacements[J].ReplacementString);
+    }
+  }
+
+  RefactoringResultWrapper(
+      ArrayRef<RefactoringReplacement> Replacements,
+      ArrayRef<std::unique_ptr<RefactoringResultAssociatedSymbol>>
+          AssociatedSymbols,
+      std::unique_ptr<RefactoringContinuation> Continuation,
+      ASTContext &Context, CXTranslationUnit TU)
+      : Continuation(std::move(Continuation)), TU(TU) {
+    SourceManager &SM = Context.getSourceManager();
+
+    if (Replacements.empty()) {
+      assert(AssociatedSymbols.empty() && "Symbols without replacements??");
+      // TODO: Remove begin
+      this->Replacements.NumFileReplacementSets = 0;
+      this->Replacements.FileReplacementSets = nullptr;
+      // Remove end
+      this->SourceReplacements.NumFileReplacementSets = 0;
+      this->SourceReplacements.FileReplacementSets = nullptr;
+      return;
+    }
+    llvm::SmallDenseMap<const RefactoringResultAssociatedSymbol *, unsigned>
+        AssociatedSymbolToIndex;
+    for (const auto &Symbol : llvm::enumerate(AssociatedSymbols))
+      AssociatedSymbolToIndex[Symbol.value().get()] = Symbol.index();
+
+    // Find the set of files that have to be modified and gather the indices of
+    // the occurrences for each file.
+    llvm::DenseMap<const FileEntry *, std::vector<unsigned>>
+        FilesToReplacements;
+    for (const auto &Replacement : llvm::enumerate(Replacements)) {
+      SourceLocation Loc = Replacement.value().Range.getBegin();
+      const std::pair<FileID, unsigned> DecomposedLocation =
+          SM.getDecomposedLoc(Loc);
+      assert(DecomposedLocation.first.isValid() && "Invalid file!");
+      const FileEntry *Entry = SM.getFileEntryForID(DecomposedLocation.first);
+      FilesToReplacements.try_emplace(Entry, std::vector<unsigned>())
+          .first->second.push_back(Replacement.index());
+    }
+
+    // TODO: Remove
+    unsigned NumFiles = FilesToReplacements.size();
+    auto *FileReplacementSets =
+        new CXRefactoringFileReplacementSet_Old[NumFiles];
+
+    unsigned FileIndex = 0;
+    for (const auto &Entry : FilesToReplacements) {
+      CXRefactoringFileReplacementSet_Old &FileSet =
+          FileReplacementSets[FileIndex];
+      ++FileIndex;
+      ArrayRef<unsigned> ReplacementIndices = Entry.second;
+      FileSet.Filename = cxstring::createDup(Entry.first->getName());
+      FileSet.NumReplacements = ReplacementIndices.size();
+      auto *FileReplacements =
+          new CXRefactoringReplacement_Old[ReplacementIndices.size()];
+      FileSet.Replacements = FileReplacements;
+
+      unsigned NumRemoved = 0;
+      for (unsigned I = 0; I < FileSet.NumReplacements; ++I) {
+        const RefactoringReplacement &RefReplacement =
+            Replacements[ReplacementIndices[I]];
+        CXSourceRange Range = cxloc::translateSourceRange(
+            SM, Context.getLangOpts(),
+            CharSourceRange::getCharRange(RefReplacement.Range.getBegin(),
+                                          RefReplacement.Range.getEnd()));
+        CXFileLocation Begin, End;
+        clang_getFileLocation(clang_getRangeStart(Range), nullptr, &Begin.Line,
+                              &Begin.Column, nullptr);
+        clang_getFileLocation(clang_getRangeEnd(Range), nullptr, &End.Line,
+                              &End.Column, nullptr);
+
+        if (I && FileReplacements[I - NumRemoved - 1].Range.End == Begin) {
+          // Merge the previous and the current replacement.
+          FileReplacements[I - NumRemoved - 1].Range.End = End;
+          std::string Replacement =
+              std::string(clang_getCString(
+                  FileReplacements[I - NumRemoved - 1].ReplacementString)) +
+              RefReplacement.ReplacementString;
+          FileReplacements[I - NumRemoved - 1].ReplacementString =
+              cxstring::createDup(Replacement);
+          NumRemoved++;
+          continue;
+        }
+
+        CXRefactoringReplacement_Old &Replacement =
+            FileReplacements[I - NumRemoved];
+        Replacement.ReplacementString =
+            cxstring::createDup(RefReplacement.ReplacementString);
+        Replacement.Range.Begin = Begin;
+        Replacement.Range.End = End;
+      }
+      FileSet.NumReplacements -= NumRemoved;
+    }
+
+    this->Replacements.FileReplacementSets = FileReplacementSets;
+    this->Replacements.NumFileReplacementSets = NumFiles;
+
+    // TODO: Outdent.
+    {
+      unsigned NumFiles = FilesToReplacements.size();
+      auto *FileReplacementSets =
+          Allocator.Allocate<CXRefactoringFileReplacementSet>(NumFiles);
+      SourceReplacements.FileReplacementSets = FileReplacementSets;
+      SourceReplacements.NumFileReplacementSets = NumFiles;
+      unsigned FileIndex = 0;
+      for (const auto &Entry : FilesToReplacements) {
+        CXRefactoringFileReplacementSet &FileSet =
+            FileReplacementSets[FileIndex];
+        ++FileIndex;
+        ArrayRef<unsigned> ReplacementIndices = Entry.second;
+        FileSet.Filename = cxstring::createDup(Entry.first->getName());
+        FileSet.NumReplacements = ReplacementIndices.size();
+        auto *FileReplacements = Allocator.Allocate<CXRefactoringReplacement>(
+            ReplacementIndices.size());
+        FileSet.Replacements = FileReplacements;
+
+        unsigned NumRemoved = 0;
+        for (unsigned I = 0; I < FileSet.NumReplacements; ++I) {
+          const RefactoringReplacement &RefReplacement =
+              Replacements[ReplacementIndices[I]];
+          CXSourceRange Range = cxloc::translateSourceRange(
+              SM, Context.getLangOpts(),
+              CharSourceRange::getCharRange(RefReplacement.Range.getBegin(),
+                                            RefReplacement.Range.getEnd()));
+          CXFileLocation Begin, End;
+          clang_getFileLocation(clang_getRangeStart(Range), nullptr,
+                                &Begin.Line, &Begin.Column, nullptr);
+          clang_getFileLocation(clang_getRangeEnd(Range), nullptr, &End.Line,
+                                &End.Column, nullptr);
+
+          if (I && FileReplacements[I - NumRemoved - 1].Range.End == Begin) {
+            // Merge the previous and the current replacement.
+            FileReplacements[I - NumRemoved - 1].Range.End = End;
+            std::string Replacement =
+                std::string(clang_getCString(
+                    FileReplacements[I - NumRemoved - 1].ReplacementString)) +
+                RefReplacement.ReplacementString;
+            FileReplacements[I - NumRemoved - 1].ReplacementString =
+                cxstring::createDup(Replacement);
+            NumRemoved++;
+            continue;
+          }
+
+          CXRefactoringReplacement &Replacement =
+              FileReplacements[I - NumRemoved];
+          Replacement.ReplacementString =
+              cxstring::createDup(RefReplacement.ReplacementString);
+          Replacement.Range.Begin = Begin;
+          Replacement.Range.End = End;
+          unsigned NumAssociatedSymbols = RefReplacement.SymbolLocations.size();
+          if (!NumAssociatedSymbols) {
+            Replacement.AssociatedData = nullptr;
+            continue;
+          }
+          AssociatedReplacementInfo *AssociatedData =
+              Allocator.Allocate<AssociatedReplacementInfo>();
+          Replacement.AssociatedData = AssociatedData;
+          AssociatedData->AssociatedSymbolOccurrences =
+              Allocator.Allocate<CXSymbolOccurrence>(NumAssociatedSymbols);
+          AssociatedData->NumAssociatedSymbolOccurrences = NumAssociatedSymbols;
+          unsigned SymbolIndex = 0;
+          for (const auto &AssociatedSymbol : RefReplacement.SymbolLocations) {
+            unsigned Index = AssociatedSymbolToIndex[AssociatedSymbol.first];
+            const RefactoringReplacement::AssociatedSymbolLocation &Loc =
+                AssociatedSymbol.second;
+            CXFileRange *NamePieces =
+                Allocator.Allocate<CXFileRange>(Loc.Offsets.size());
+            assert(AssociatedSymbol.first->getName().size() ==
+                       Loc.Offsets.size() &&
+                   "mismatching symbol name and offsets");
+            for (const auto &Offset : llvm::enumerate(Loc.Offsets)) {
+              StringRef NamePiece =
+                  AssociatedSymbol.first->getName()[Offset.index()];
+              NamePieces[Offset.index()] = translateOffsetToRelativeRange(
+                  Offset.value(), NamePiece.size(),
+                  RefReplacement.ReplacementString);
+            }
+            AssociatedData->AssociatedSymbolOccurrences[SymbolIndex] =
+                CXSymbolOccurrence{
+                    NamePieces, (unsigned)Loc.Offsets.size(),
+                    Loc.IsDeclaration
+                        ? CXSymbolOccurrence_ExtractedDeclaration
+                        : CXSymbolOccurrence_ExtractedDeclaration_Reference,
+                    /*IsMacroExpansion=*/0, Index};
+            ++SymbolIndex;
+          }
+        }
+        FileSet.NumReplacements -= NumRemoved;
+      }
+    }
+  }
+};
+
+class RefactoringContinuationWrapper {
+public:
+  std::unique_ptr<RefactoringContinuation> Continuation;
+  struct QueryWrapper {
+    indexer::IndexerQuery *Query;
+    CXTranslationUnit TU;
+    std::vector<indexer::Indexed<PersistentDeclRef<Decl>>> DeclResults;
+    unsigned ConsumedResults = 0;
+
+    QueryWrapper(indexer::IndexerQuery *Query, CXTranslationUnit TU)
+        : Query(Query), TU(TU) {}
+  };
+  SmallVector<QueryWrapper, 4> Queries;
+  bool IsInitiationTUAbandoned = false;
+
+  RefactoringContinuationWrapper(
+      std::unique_ptr<RefactoringContinuation> Continuation,
+      CXTranslationUnit TU)
+      : Continuation(std::move(Continuation)) {
+    Queries.emplace_back(this->Continuation->getASTUnitIndexerQuery(), TU);
+    assert(Queries.back().Query && "Invalid ast query");
+    std::vector<indexer::IndexerQuery *> AdditionalQueries =
+        this->Continuation->getAdditionalIndexerQueries();
+    for (indexer::IndexerQuery *IQ : AdditionalQueries)
+      Queries.emplace_back(IQ, TU);
+  }
+};
+
+class RefactoringDiagnosticConsumer : public DiagnosticConsumer {
+  const ASTContext &Context;
+  DiagnosticConsumer *PreviousClient;
+  std::unique_ptr<DiagnosticConsumer> PreviousClientPtr;
+  llvm::SmallVector<StoredDiagnostic, 2> RenameDiagnostics;
+  llvm::SmallVector<StoredDiagnostic, 1> ContinuationDiagnostics;
+
+public:
+  RefactoringDiagnosticConsumer(ASTContext &Context) : Context(Context) {
+    PreviousClient = Context.getDiagnostics().getClient();
+    PreviousClientPtr = Context.getDiagnostics().takeClient();
+    Context.getDiagnostics().setClient(this, /*ShouldOwnClient=*/false);
+  }
+
+  ~RefactoringDiagnosticConsumer() {
+    if (PreviousClientPtr)
+      Context.getDiagnostics().setClient(PreviousClientPtr.release());
+    else
+      Context.getDiagnostics().setClient(PreviousClient,
+                                         /*ShouldOwnClient=*/false);
+  }
+
+  void HandleDiagnostic(DiagnosticsEngine::Level Level,
+                        const Diagnostic &Info) override {
+    unsigned Cat = DiagnosticIDs::getCategoryNumberForDiag(Info.getID());
+    if (Cat == diag::DiagCat_Rename_Issue)
+      RenameDiagnostics.push_back(StoredDiagnostic(Level, Info));
+    else if (Cat == diag::DiagCat_Refactoring_Continuation_Issue)
+      ContinuationDiagnostics.push_back(StoredDiagnostic(Level, Info));
+    else
+      assert(false && "Unhandled refactoring category");
+  }
+
+  CXDiagnosticSetImpl *createDiags() const {
+    if (RenameDiagnostics.empty() && ContinuationDiagnostics.empty())
+      return nullptr;
+    llvm::SmallVector<StoredDiagnostic, 2> AllDiagnostics;
+    for (const auto &D : RenameDiagnostics)
+      AllDiagnostics.push_back(D);
+    for (const auto &D : ContinuationDiagnostics)
+      AllDiagnostics.push_back(D);
+    return cxdiag::createStoredDiags(AllDiagnostics, Context.getLangOpts());
+  }
+
+  CXRefactoringActionSetWithDiagnostics createActionSet() const {
+    if (RenameDiagnostics.empty())
+      return {nullptr, 0};
+    CXRefactoringActionWithDiagnostics *Actions =
+        new CXRefactoringActionWithDiagnostics[1];
+    Actions[0].Action = CXRefactor_Rename;
+    Actions[0].Diagnostics =
+        cxdiag::createStoredDiags(RenameDiagnostics, Context.getLangOpts());
+    return {Actions, 1};
+  }
+};
+
+} // end anonymous namespace
+
+template <typename T>
+static T withRenamingAction(CXRefactoringAction Action, T DefaultValue,
+                            llvm::function_ref<T(RenamingAction &)> Callback) {
+  if (!Action)
+    return DefaultValue;
+  RenamingAction *Rename =
+      static_cast<RefactoringAction *>(Action)->getRenamingAction();
+  if (!Rename)
+    return DefaultValue;
+  return Callback(*Rename);
+}
+
+static enum CXIndexerQueryKind
+translateDeclPredicate(const indexer::DeclPredicate &Predicate) {
+  indexer::DeclEntity Entity;
+  if (Predicate == Entity.isDefined().Predicate)
+    return CXIndexerQuery_Decl_IsDefined;
+  return CXIndexerQuery_Unknown;
+}
+
+extern "C" {
+
+CXString
+clang_RefactoringActionType_getName(enum CXRefactoringActionType Action) {
+  return cxstring::createRef(
+      getRefactoringActionTypeName(translateRefactoringActionType(Action)));
+}
+
+void clang_RefactoringActionSet_dispose(CXRefactoringActionSet *Set) {
+  if (Set && Set->Actions)
+    delete[] Set->Actions;
+}
+
+void clang_RefactoringActionSetWithDiagnostics_dispose(
+    CXRefactoringActionSetWithDiagnostics *Set) {
+  if (Set && Set->Actions) {
+    for (auto &S : llvm::makeArrayRef(Set->Actions, Set->NumActions))
+      clang_disposeDiagnosticSet(S.Diagnostics);
+    delete[] Set->Actions;
+  }
+}
+
+CXRefactoringOptionSet clang_RefactoringOptionSet_create() {
+  return new RefactoringOptionSet;
+}
+
+CXRefactoringOptionSet
+clang_RefactoringOptionSet_createFromString(const char *String) {
+  RefactoringOptionSet *Result = new RefactoringOptionSet;
+  auto Options = RefactoringOptionSet::parse(String);
+  if (Options) {
+    *Result = std::move(*Options);
+    return Result;
+  }
+  llvm::handleAllErrors(Options.takeError(),
+                        [](const llvm::StringError &Error) {});
+  return clang_RefactoringOptionSet_create();
+}
+
+void clang_RefactoringOptionSet_add(CXRefactoringOptionSet Set,
+                                    enum CXRefactoringOption Option) {
+  if (!Set)
+    return;
+  switch (Option) {
+  case CXRefactorOption_AvoidTextualMatches:
+    static_cast<RefactoringOptionSet *>(Set)->add(
+        option::AvoidTextualMatches::getTrue());
+    break;
+  }
+}
+
+CXString clang_RefactoringOptionSet_toString(CXRefactoringOptionSet Set) {
+  if (!Set)
+    return cxstring::createNull();
+  std::string Result;
+  llvm::raw_string_ostream OS(Result);
+  static_cast<RefactoringOptionSet *>(Set)->print(OS);
+  return cxstring::createDup(OS.str());
+}
+
+void clang_RefactoringOptionSet_dispose(CXRefactoringOptionSet Set) {
+  if (Set)
+    delete static_cast<RefactoringOptionSet *>(Set);
+}
+
+enum CXErrorCode
+clang_Refactoring_findActionsAt(CXTranslationUnit TU, CXSourceLocation Location,
+                                CXSourceRange SelectionRange,
+                                CXRefactoringOptionSet Options,
+                                CXRefactoringActionSet *OutSet) {
+  return clang_Refactoring_findActionsWithInitiationFailureDiagnosicsAt(
+      TU, Location, SelectionRange, Options, OutSet, /*OutFailureSet=*/nullptr);
+}
+
+enum CXErrorCode clang_Refactoring_findActionsWithInitiationFailureDiagnosicsAt(
+    CXTranslationUnit TU, CXSourceLocation Location,
+    CXSourceRange SelectionRange, CXRefactoringOptionSet Options,
+    CXRefactoringActionSet *OutSet,
+    CXRefactoringActionSetWithDiagnostics *OutFailureSet) {
+  LOG_FUNC_SECTION { *Log << TU << ' '; }
+  if (OutFailureSet) {
+    OutFailureSet->Actions = nullptr;
+    OutFailureSet->NumActions = 0;
+  }
+
+  if (!OutSet)
+    return CXError_InvalidArguments;
+
+  OutSet->Actions = nullptr;
+  OutSet->NumActions = 0;
+
+  if (cxtu::isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return CXError_InvalidArguments;
+  }
+
+  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+  if (!CXXUnit)
+    return CXError_InvalidArguments;
+
+  SourceLocation Loc = cxloc::translateSourceLocation(Location);
+  if (Loc.isInvalid())
+    return CXError_InvalidArguments;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+  (void)Options; // FIXME: handle options
+  ASTContext &Context = CXXUnit->getASTContext();
+  RefactoringDiagnosticConsumer DiagConsumer(Context);
+  RefactoringActionSet ActionSet = findActionSetAt(
+      Loc, cxloc::translateCXSourceRange(SelectionRange), Context);
+  if (OutFailureSet)
+    *OutFailureSet = DiagConsumer.createActionSet();
+  if (ActionSet.Actions.empty())
+    return CXError_RefactoringActionUnavailable;
+
+  CXRefactoringActionType *Actions =
+      new CXRefactoringActionType[ActionSet.Actions.size()];
+  OutSet->Actions = Actions;
+  OutSet->NumActions = ActionSet.Actions.size();
+  for (const auto &Action : llvm::enumerate(ActionSet.Actions))
+    Actions[Action.index()] = translateRefactoringActionType(Action.value());
+  return CXError_Success;
+}
+
+void clang_RefactoringAction_dispose(CXRefactoringAction Action) {
+  if (Action)
+    delete static_cast<RefactoringAction *>(Action);
+}
+
+CXSourceRange
+clang_RefactoringAction_getSourceRangeOfInterest(CXRefactoringAction Action) {
+  if (Action) {
+    RefactoringOperation *Operation =
+        static_cast<RefactoringAction *>(Action)->getOperation();
+    if (Operation) {
+      ASTUnit *CXXUnit = cxtu::getASTUnit(
+          static_cast<RefactoringAction *>(Action)->InitiationTU);
+      if (const Stmt *S = Operation->getTransformedStmt()) {
+        SourceRange Range = S->getSourceRange();
+        if (const Stmt *Last = Operation->getLastTransformedStmt())
+          Range.setEnd(Last->getLocEnd());
+        return cxloc::translateSourceRange(CXXUnit->getASTContext(), Range);
+      } else if (const Decl *D = Operation->getTransformedDecl()) {
+        SourceRange Range = D->getSourceRange();
+        if (const Decl *Last = Operation->getLastTransformedDecl())
+          Range.setEnd(Last->getLocEnd());
+        return cxloc::translateSourceRange(CXXUnit->getASTContext(), Range);
+      }
+    }
+  }
+  return clang_getNullRange();
+}
+
+int clang_RefactoringAction_requiresImplementationTU(
+    CXRefactoringAction Action) {
+  return withRenamingAction<int>(Action, 0, [](RenamingAction &Action) {
+    return Action.Operation.requiresImplementationTU();
+  });
+}
+
+CXString clang_RefactoringAction_getUSRThatRequiresImplementationTU(
+    CXRefactoringAction Action) {
+  return withRenamingAction<CXString>(
+      Action, cxstring::createNull(), [](RenamingAction &Action) {
+        return Action.getUSRThatRequiresImplementationTU();
+      });
+}
+
+enum CXErrorCode
+clang_RefactoringAction_addImplementationTU(CXRefactoringAction Action,
+                                            CXTranslationUnit TU) {
+  if (!Action || !TU)
+    return CXError_InvalidArguments;
+  // Prohibit multiple additions of implementation TU.
+  if (static_cast<RefactoringAction *>(Action)->ImplementationTU)
+    return CXError_Failure;
+  static_cast<RefactoringAction *>(Action)->ImplementationTU = TU;
+  return CXError_Success;
+}
+
+enum CXErrorCode clang_RefactoringAction_getRefactoringCandidates(
+    CXRefactoringAction Action,
+    CXRefactoringCandidateSet *OutRefactoringCandidateSet) {
+  if (!Action || !OutRefactoringCandidateSet)
+    return CXError_InvalidArguments;
+  *OutRefactoringCandidateSet =
+      static_cast<RefactoringAction *>(Action)->getRefactoringCandidates();
+  return CXError_Success;
+}
+
+enum CXErrorCode
+clang_RefactoringAction_selectRefactoringCandidate(CXRefactoringAction Action,
+                                                   unsigned Index) {
+  if (!Action)
+    return CXError_InvalidArguments;
+  return static_cast<RefactoringAction *>(Action)->selectCandidate(Index);
+}
+
+// TODO: Remove.
+enum CXErrorCode clang_Refactoring_initiateActionAt(
+    CXTranslationUnit TU, CXSourceLocation Location,
+    CXSourceRange SelectionRange, enum CXRefactoringActionType ActionType,
+    CXRefactoringOptionSet Options, CXRefactoringAction *OutAction,
+    CXString *OutFailureReason) {
+  CXDiagnosticSet Diags;
+  CXErrorCode Result = clang_Refactoring_initiateAction(
+      TU, Location, SelectionRange, ActionType, Options, OutAction, &Diags);
+  if (OutFailureReason && Diags && clang_getNumDiagnosticsInSet(Diags) == 1) {
+    CXString Spelling =
+        clang_getDiagnosticSpelling(clang_getDiagnosticInSet(Diags, 0));
+    *OutFailureReason = cxstring::createDup(clang_getCString(Spelling));
+    clang_disposeString(Spelling);
+  } else if (OutFailureReason)
+    *OutFailureReason = cxstring::createEmpty();
+  clang_disposeDiagnosticSet(Diags);
+  return Result;
+}
+
+enum CXErrorCode clang_Refactoring_initiateAction(
+    CXTranslationUnit TU, CXSourceLocation Location,
+    CXSourceRange SelectionRange, enum CXRefactoringActionType ActionType,
+    CXRefactoringOptionSet Options, CXRefactoringAction *OutAction,
+    CXDiagnosticSet *OutDiagnostics) {
+  if (!OutAction)
+    return CXError_InvalidArguments;
+  *OutAction = nullptr;
+  if (OutDiagnostics)
+    *OutDiagnostics = nullptr;
+
+  if (cxtu::isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return CXError_InvalidArguments;
+  }
+
+  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+  if (!CXXUnit)
+    return CXError_InvalidArguments;
+
+  SourceLocation Loc = cxloc::translateSourceLocation(Location);
+  if (Loc.isInvalid())
+    return CXError_InvalidArguments;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+  (void)Options; // FIXME: handle options
+  ASTContext &Context = CXXUnit->getASTContext();
+  RefactoringDiagnosticConsumer DiagConsumer(Context);
+  auto Operation = initiateRefactoringOperationAt(
+      Loc, cxloc::translateCXSourceRange(SelectionRange), Context,
+      translateRefactoringActionType(ActionType));
+  if (!Operation.Initiated) {
+    if (OutDiagnostics) {
+      if (!Operation.FailureReason.empty()) {
+        // TODO: Remove when other actions migrate to diagnostics.
+        StoredDiagnostic Diag(DiagnosticsEngine::Error, /*ID=*/0,
+                              Operation.FailureReason);
+        *OutDiagnostics =
+            cxdiag::createStoredDiags(Diag, Context.getLangOpts());
+      } else
+        *OutDiagnostics = DiagConsumer.createDiags();
+    }
+    return CXError_RefactoringActionUnavailable;
+  }
+  if (Operation.RefactoringOp)
+    *OutAction = new RefactoringAction(std::move(Operation.RefactoringOp),
+                                       ActionType, TU);
+  else
+    *OutAction = new RefactoringAction(
+        llvm::make_unique<RenamingAction>(CXXUnit->getLangOpts(),
+                                          std::move(*Operation.SymbolOp)),
+        TU);
+  return CXError_Success;
+}
+
+enum CXErrorCode clang_Refactoring_initiateActionOnDecl(
+    CXTranslationUnit TU, const char *DeclUSR,
+    enum CXRefactoringActionType ActionType, CXRefactoringOptionSet Options,
+    CXRefactoringAction *OutAction, CXString *OutFailureReason) {
+  if (!OutAction)
+    return CXError_InvalidArguments;
+  *OutAction = nullptr;
+  if (OutFailureReason)
+    *OutFailureReason = cxstring::createNull();
+
+  if (cxtu::isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return CXError_InvalidArguments;
+  }
+
+  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+  if (!CXXUnit)
+    return CXError_InvalidArguments;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+  (void)Options; // FIXME: handle options
+  auto Operation = initiateRefactoringOperationOnDecl(
+      DeclUSR, CXXUnit->getASTContext(),
+      translateRefactoringActionType(ActionType));
+  if (!Operation.Initiated)
+    return CXError_RefactoringActionUnavailable;
+  // FIXME: Don't dupe with above
+  if (Operation.RefactoringOp)
+    *OutAction = new RefactoringAction(std::move(Operation.RefactoringOp),
+                                       ActionType, TU);
+  else
+    *OutAction = new RefactoringAction(
+        llvm::make_unique<RenamingAction>(CXXUnit->getLangOpts(),
+                                          std::move(*Operation.SymbolOp)),
+        TU);
+  return CXError_Success;
+}
+
+enum CXErrorCode
+clang_Refactoring_initiateRenamingOperation(CXRefactoringAction Action) {
+  if (!Action)
+    return CXError_InvalidArguments;
+  RefactoringAction *RefAction = static_cast<RefactoringAction *>(Action);
+  RenamingAction *Rename = RefAction->getRenamingAction();
+  if (!Rename)
+    return CXError_InvalidArguments;
+  // TODO
+  return CXError_Success;
+}
+
+CINDEX_LINKAGE
+enum CXErrorCode clang_Refactoring_findRenamedCursor(
+    CXTranslationUnit TU, CXSourceLocation Location,
+    CXSourceRange SelectionRange, CXCursor *OutCursor) {
+  if (!OutCursor)
+    return CXError_InvalidArguments;
+
+  if (cxtu::isNotUsableTU(TU)) {
+    LOG_BAD_TU(TU);
+    return CXError_InvalidArguments;
+  }
+
+  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+  if (!CXXUnit)
+    return CXError_InvalidArguments;
+  SourceLocation Loc = cxloc::translateSourceLocation(Location);
+  if (Loc.isInvalid())
+    return CXError_InvalidArguments;
+
+  const NamedDecl *ND = rename::getNamedDeclAt(CXXUnit->getASTContext(), Loc);
+  if (!ND) {
+    *OutCursor = cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound, TU);
+    return CXError_RefactoringActionUnavailable;
+  }
+
+  *OutCursor = cxcursor::MakeCXCursor(ND, TU);
+  return CXError_Success;
+}
+
+enum CXErrorCode clang_RenamingOperation_setNewName(CXRefactoringAction Action,
+                                                    const char *NewName) {
+  return withRenamingAction<CXErrorCode>(
+      Action, CXError_InvalidArguments,
+      [=](RenamingAction &Action) -> CXErrorCode {
+        if (!NewName)
+          return CXError_InvalidArguments;
+        StringRef Name = NewName;
+        if (Name.empty())
+          return CXError_InvalidArguments;
+        return Action.setNewName(Name);
+      });
+}
+
+enum CXRefactoringActionType
+clang_RefactoringAction_getInitiatedActionType(CXRefactoringAction Action) {
+  return static_cast<RefactoringAction *>(Action)->Type;
+}
+
+unsigned clang_RenamingOperation_getNumSymbols(CXRefactoringAction Action) {
+  return withRenamingAction<unsigned>(Action, 0, [](RenamingAction &Action) {
+    return Action.Operation.symbols().size();
+  });
+}
+
+CXString clang_RenamingOperation_getUSRForSymbol(CXRefactoringAction Action,
+                                                 unsigned Index) {
+  return withRenamingAction<CXString>(
+      Action, cxstring::createNull(),
+      [=](RenamingAction &Action) { return Action.usrForSymbolAt(Index); });
+}
+
+CXRenamingResult clang_Refactoring_findRenamedOccurrencesInPrimaryTUs(
+    CXRefactoringAction Action, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles) {
+  if (!Action)
+    return nullptr;
+  RefactoringAction *RefAction = static_cast<RefactoringAction *>(Action);
+  RenamingAction *Rename = RefAction->getRenamingAction();
+  if (!Rename)
+    return nullptr;
+
+  // TODO: Handle implementation TU
+  if (cxtu::isNotUsableTU(RefAction->InitiationTU)) {
+    LOG_BAD_TU(RefAction->InitiationTU);
+    return nullptr;
+  }
+
+  ASTUnit *CXXUnit = cxtu::getASTUnit(RefAction->InitiationTU);
+  if (!CXXUnit)
+    return nullptr;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+  return Rename->handlePrimaryTU(RefAction->InitiationTU, *CXXUnit);
+}
+
+CXSymbolOccurrencesResult clang_Refactoring_findSymbolOccurrencesInInitiationTU(
+    CXRefactoringAction Action, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, struct CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles) {
+  if (!Action)
+    return nullptr;
+  RefactoringAction *RefAction = static_cast<RefactoringAction *>(Action);
+  RenamingAction *Rename = RefAction->getRenamingAction();
+  if (!Rename)
+    return nullptr;
+
+  if (cxtu::isNotUsableTU(RefAction->InitiationTU)) {
+    LOG_BAD_TU(RefAction->InitiationTU);
+    return nullptr;
+  }
+
+  ASTUnit *CXXUnit = cxtu::getASTUnit(RefAction->InitiationTU);
+  if (!CXXUnit)
+    return nullptr;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+  return Rename->findSymbolsInInitiationTU(RefAction->InitiationTU, *CXXUnit);
+}
+
+CXErrorCode clang_Refactoring_findRenamedOccurrencesInIndexedFile(
+    const CXRenamedIndexedSymbol *Symbols, unsigned NumSymbols, CXIndex CIdx,
+    const char *Filename, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, struct CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles, CXRefactoringOptionSet Options,
+    CXRenamingResult *OutResult) {
+  if (!OutResult)
+    return CXError_InvalidArguments;
+  if (!Symbols || !NumSymbols || !Filename)
+    return CXError_InvalidArguments;
+  return performIndexedFileRename(
+      llvm::makeArrayRef(Symbols, NumSymbols), StringRef(Filename),
+      llvm::makeArrayRef(CommandLineArgs, NumCommandLineArgs), CIdx,
+      MutableArrayRef<CXUnsavedFile>(UnsavedFiles, NumUnsavedFiles),
+      Options ? static_cast<RefactoringOptionSet *>(Options) : nullptr,
+      *OutResult);
+}
+
+CXErrorCode clang_Refactoring_findSymbolOccurrencesInIndexedFile(
+    const CXIndexedSymbol *Symbols, unsigned NumSymbols, CXIndex CIdx,
+    const char *Filename, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, struct CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles, CXRefactoringOptionSet Options,
+    CXSymbolOccurrencesResult *OutResult) {
+  if (!OutResult)
+    return CXError_InvalidArguments;
+  if (!Symbols || !NumSymbols || !Filename)
+    return CXError_InvalidArguments;
+  return performIndexedSymbolSearch(
+      llvm::makeArrayRef(Symbols, NumSymbols), StringRef(Filename),
+      llvm::makeArrayRef(CommandLineArgs, NumCommandLineArgs), CIdx,
+      MutableArrayRef<CXUnsavedFile>(UnsavedFiles, NumUnsavedFiles),
+      Options ? static_cast<RefactoringOptionSet *>(Options) : nullptr,
+      *OutResult);
+}
+
+unsigned clang_RenamingResult_getNumModifiedFiles(CXRenamingResult Result) {
+  if (Result)
+    return static_cast<RenamingResult *>(Result)->getFilenames().size();
+  return 0;
+}
+
+void clang_RenamingResult_getResultForFile(CXRenamingResult Result,
+                                           unsigned FileIndex,
+                                           CXFileRenamingResult *OutResult) {
+  if (!Result ||
+      FileIndex >=
+          static_cast<RenamingResult *>(Result)->getFilenames().size()) {
+    OutResult->Filename = cxstring::createNull();
+    OutResult->NumOccurrences = 0;
+    OutResult->Occurrences = nullptr;
+    return;
+  }
+  auto &RenameResult = *static_cast<RenamingResult *>(Result);
+  OutResult->Filename = RenameResult.getFilenames()[FileIndex];
+  OutResult->NumOccurrences = RenameResult.getOccurrences(FileIndex).size();
+  OutResult->Occurrences = RenameResult.getOccurrences(FileIndex).data();
+}
+
+void clang_RenamingResult_dispose(CXRenamingResult Result) {
+  if (Result)
+    delete static_cast<RenamingResult *>(Result);
+}
+
+unsigned clang_SymbolOccurrences_getNumFiles(CXSymbolOccurrencesResult Result) {
+  if (Result)
+    return static_cast<SymbolOccurrencesResult *>(Result)
+        ->getFilenames()
+        .size();
+  return 0;
+}
+
+void clang_SymbolOccurrences_getOccurrencesForFile(
+    CXSymbolOccurrencesResult Result, unsigned FileIndex,
+    CXSymbolOccurrencesInFile *OutResult) {
+  if (!Result ||
+      FileIndex >= static_cast<SymbolOccurrencesResult *>(Result)
+                       ->getFilenames()
+                       .size()) {
+    OutResult->Filename = cxstring::createNull();
+    OutResult->NumOccurrences = 0;
+    OutResult->Occurrences = nullptr;
+    return;
+  }
+  auto &RenameResult = *static_cast<SymbolOccurrencesResult *>(Result);
+  OutResult->Filename = RenameResult.getFilenames()[FileIndex];
+  OutResult->NumOccurrences = RenameResult.getOccurrences(FileIndex).size();
+  OutResult->Occurrences = RenameResult.getOccurrences(FileIndex).data();
+}
+
+void clang_SymbolOccurrences_dispose(CXSymbolOccurrencesResult Result) {
+  if (Result)
+    delete static_cast<SymbolOccurrencesResult *>(Result);
+}
+
+CXRefactoringResult clang_Refactoring_performOperation(
+    CXRefactoringAction Action, const char *const *CommandLineArgs,
+    int NumCommandLineArgs, struct CXUnsavedFile *UnsavedFiles,
+    unsigned NumUnsavedFiles, CXRefactoringOptionSet Options,
+    CXString *OutFailureReason) {
+  if (OutFailureReason)
+    *OutFailureReason = cxstring::createNull();
+  if (!Action)
+    return nullptr;
+  RefactoringAction *RefAction = static_cast<RefactoringAction *>(Action);
+  if (!RefAction->getOperation())
+    return nullptr;
+
+  ASTUnit *CXXUnit = cxtu::getASTUnit(RefAction->InitiationTU);
+  if (!CXXUnit)
+    return nullptr;
+
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+
+  RefactoringOptionSet EmptyOptionSet;
+  const RefactoringOptionSet &OptionSet =
+      Options ? *static_cast<RefactoringOptionSet *>(Options) : EmptyOptionSet;
+  llvm::Expected<RefactoringResult> Result = RefAction->getOperation()->perform(
+      CXXUnit->getASTContext(), CXXUnit->getPreprocessor(), OptionSet,
+      RefAction->SelectedCandidate);
+  if (!Result) {
+    if (OutFailureReason) {
+      (void)!llvm::handleErrors(
+          Result.takeError(), [&](const RefactoringOperationError &Error) {
+            *OutFailureReason = cxstring::createDup(Error.FailureReason);
+          });
+    }
+    return nullptr;
+  }
+  return new RefactoringResultWrapper(
+      Result.get().Replacements, Result.get().AssociatedSymbols,
+      std::move(Result.get().Continuation), CXXUnit->getASTContext(),
+      RefAction->InitiationTU);
+}
+
+void clang_RefactoringResult_getReplacements(
+    CXRefactoringResult Result,
+    CXRefactoringReplacements_Old *OutReplacements) {
+  if (!OutReplacements)
+    return;
+  if (!Result) {
+    OutReplacements->FileReplacementSets = nullptr;
+    OutReplacements->NumFileReplacementSets = 0;
+    return;
+  }
+  *OutReplacements = static_cast<RefactoringResultWrapper *>(Result)->Replacements;
+}
+
+CXRefactoringReplacements
+clang_RefactoringResult_getSourceReplacements(CXRefactoringResult Result) {
+  if (!Result)
+    return CXRefactoringReplacements{nullptr, 0};
+  return static_cast<RefactoringResultWrapper *>(Result)->SourceReplacements;
+}
+
+CXRefactoringReplacementAssociatedSymbolOccurrences
+clang_RefactoringReplacement_getAssociatedSymbolOccurrences(
+    CXRefactoringReplacement Replacement) {
+  if (!Replacement.AssociatedData)
+    return CXRefactoringReplacementAssociatedSymbolOccurrences{nullptr, 0};
+  auto *Data =
+      static_cast<RefactoringResultWrapper::AssociatedReplacementInfo *>(
+          Replacement.AssociatedData);
+  return CXRefactoringReplacementAssociatedSymbolOccurrences{
+      Data->AssociatedSymbolOccurrences, Data->NumAssociatedSymbolOccurrences};
+}
+
+void clang_RefactoringResult_dispose(CXRefactoringResult Result) {
+  if (Result)
+    delete static_cast<RefactoringResultWrapper *>(Result);
+}
+
+CXRefactoringContinuation
+clang_RefactoringResult_getContinuation(CXRefactoringResult Result) {
+  if (!Result)
+    return nullptr;
+  auto *Wrapper = static_cast<RefactoringResultWrapper *>(Result);
+  if (!Wrapper->Continuation)
+    return nullptr;
+  return new RefactoringContinuationWrapper(std::move(Wrapper->Continuation),
+                                            Wrapper->TU);
+}
+
+enum CXErrorCode
+clang_RefactoringContinuation_loadSerializedIndexerQueryResults(
+    CXRefactoringContinuation Continuation, const char *Source) {
+  if (!Continuation)
+    return CXError_InvalidArguments;
+  auto *Wrapper = static_cast<RefactoringContinuationWrapper *>(Continuation);
+  llvm::SmallVector<indexer::IndexerQuery *, 4> Queries;
+  for (const auto &Query : Wrapper->Queries)
+    Queries.push_back(Query.Query);
+  auto Err = indexer::IndexerQuery::loadResultsFromYAML(Source, Queries);
+  if (Err) {
+    consumeError(std::move(Err));
+    return CXError_Failure;
+  }
+  return CXError_Success;
+}
+
+unsigned clang_RefactoringContinuation_getNumIndexerQueries(
+    CXRefactoringContinuation Continuation) {
+  if (Continuation)
+    return static_cast<RefactoringContinuationWrapper *>(Continuation)
+        ->Queries.size();
+  return 0;
+}
+
+CXIndexerQuery clang_RefactoringContinuation_getIndexerQuery(
+    CXRefactoringContinuation Continuation, unsigned Index) {
+  if (!Continuation)
+    return nullptr;
+  auto *Wrapper = static_cast<RefactoringContinuationWrapper *>(Continuation);
+  if (Index >= Wrapper->Queries.size())
+    return nullptr;
+  return &Wrapper->Queries[Index];
+}
+
+CXDiagnosticSet clang_RefactoringContinuation_verifyBeforeFinalizing(
+    CXRefactoringContinuation Continuation) {
+  if (!Continuation)
+    return nullptr;
+  auto *Wrapper = static_cast<RefactoringContinuationWrapper *>(Continuation);
+  CXTranslationUnit TU = Wrapper->Queries[0].TU;
+  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+  if (!CXXUnit)
+    return nullptr;
+  ASTContext &Context = CXXUnit->getASTContext();
+  RefactoringDiagnosticConsumer DiagConsumer(Context);
+  for (const auto &Query : Wrapper->Queries) {
+    if (Query.Query->verify(Context))
+      break;
+  }
+  return DiagConsumer.createDiags();
+}
+
+void clang_RefactoringContinuation_finalizeEvaluationInInitationTU(
+    CXRefactoringContinuation Continuation) {
+  if (!Continuation)
+    return;
+  auto *Wrapper = static_cast<RefactoringContinuationWrapper *>(Continuation);
+  Wrapper->Queries.clear();
+  Wrapper->Continuation->persistTUSpecificState();
+  Wrapper->IsInitiationTUAbandoned = true;
+}
+
+CXRefactoringResult clang_RefactoringContinuation_continueOperationInTU(
+    CXRefactoringContinuation Continuation, CXTranslationUnit TU,
+    CXString *OutFailureReason) {
+  if (!Continuation || !TU)
+    return nullptr;
+  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
+  if (!CXXUnit)
+    return nullptr;
+  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
+  const auto *Wrapper =
+      static_cast<RefactoringContinuationWrapper *>(Continuation);
+  if (!Wrapper->IsInitiationTUAbandoned) {
+    // FIXME: We can avoid conversions of TU-specific state if the given TU is
+    // the same as the initiation TU.
+    clang_RefactoringContinuation_finalizeEvaluationInInitationTU(Continuation);
+  }
+  auto Result =
+      Wrapper->Continuation->runInExternalASTUnit(CXXUnit->getASTContext());
+  if (!Result) {
+    if (OutFailureReason) {
+      (void)!llvm::handleErrors(
+          Result.takeError(), [&](const RefactoringOperationError &Error) {
+            *OutFailureReason = cxstring::createDup(Error.FailureReason);
+          });
+    }
+    return nullptr;
+  }
+  return new RefactoringResultWrapper(
+      Result.get().Replacements, Result.get().AssociatedSymbols,
+      std::move(Result.get().Continuation), CXXUnit->getASTContext(), TU);
+}
+
+void clang_RefactoringContinuation_dispose(
+    CXRefactoringContinuation Continuation) {
+  if (Continuation)
+    delete static_cast<RefactoringContinuationWrapper *>(Continuation);
+}
+
+enum CXIndexerQueryKind clang_IndexerQuery_getKind(CXIndexerQuery Query) {
+  if (!Query)
+    return CXIndexerQuery_Unknown;
+  const auto *IQ =
+      static_cast<RefactoringContinuationWrapper::QueryWrapper *>(Query)->Query;
+  if (const auto *DQ = dyn_cast<indexer::DeclarationsQuery>(IQ)) {
+    const indexer::detail::DeclPredicateNode &Node = DQ->getPredicateNode();
+    if (const auto *NP =
+            dyn_cast<indexer::detail::DeclPredicateNotPredicate>(&Node))
+      return translateDeclPredicate(
+          cast<indexer::detail::DeclPredicateNodePredicate>(NP->getChild())
+              .getPredicate());
+    return translateDeclPredicate(
+        cast<indexer::detail::DeclPredicateNodePredicate>(Node).getPredicate());
+  } else if (isa<indexer::ASTUnitForImplementationOfDeclarationQuery>(IQ))
+    return CXIndexerQuery_Decl_FileThatShouldImplement;
+  return CXIndexerQuery_Unknown;
+}
+
+unsigned clang_IndexerQuery_getNumCursors(CXIndexerQuery Query) {
+  if (!Query)
+    return 0;
+  const auto *IQ =
+      static_cast<RefactoringContinuationWrapper::QueryWrapper *>(Query)->Query;
+  if (const auto *DQ = dyn_cast<indexer::DeclarationsQuery>(IQ))
+    return DQ->getInputs().size();
+  else if (isa<indexer::ASTUnitForImplementationOfDeclarationQuery>(IQ))
+    return 1;
+  return 0;
+}
+
+CXCursor clang_IndexerQuery_getCursor(CXIndexerQuery Query,
+                                      unsigned CursorIndex) {
+  if (Query) {
+    const auto *Wrapper =
+        static_cast<RefactoringContinuationWrapper::QueryWrapper *>(Query);
+    const indexer::IndexerQuery *IQ = Wrapper->Query;
+    CXTranslationUnit TU = Wrapper->TU;
+    if (const auto *DQ = dyn_cast<indexer::DeclarationsQuery>(IQ)) {
+      if (CursorIndex < DQ->getInputs().size())
+        return cxcursor::MakeCXCursor(DQ->getInputs()[CursorIndex], TU);
+    } else if (const auto *ASTQuery = dyn_cast<
+                   indexer::ASTUnitForImplementationOfDeclarationQuery>(IQ)) {
+      if (CursorIndex == 0)
+        return cxcursor::MakeCXCursor(ASTQuery->getDecl(), TU);
+    }
+  }
+  return cxcursor::MakeCXCursorInvalid(CXCursor_InvalidCode);
+}
+
+enum CXIndexerQueryAction
+clang_IndexerQuery_consumeIntResult(CXIndexerQuery Query, unsigned CursorIndex,
+                                    int Value) {
+  if (!Query)
+    return CXIndexerQueryAction_None;
+  auto *Wrapper =
+      static_cast<RefactoringContinuationWrapper::QueryWrapper *>(Query);
+  auto *DQ = dyn_cast<indexer::DeclarationsQuery>(Wrapper->Query);
+  if (!DQ)
+    return CXIndexerQueryAction_None;
+  if (CursorIndex >= DQ->getInputs().size() ||
+      Wrapper->ConsumedResults == DQ->getInputs().size())
+    return CXIndexerQueryAction_None;
+  if (Wrapper->DeclResults.empty())
+    Wrapper->DeclResults.resize(DQ->getInputs().size(),
+                                indexer::Indexed<PersistentDeclRef<Decl>>(
+                                    PersistentDeclRef<Decl>::create(nullptr)));
+  // Filter the declarations!
+  bool IsNot = false;
+  if (isa<indexer::detail::DeclPredicateNotPredicate>(DQ->getPredicateNode()))
+    IsNot = true;
+  bool Result = IsNot ? !Value : !!Value;
+  Wrapper->DeclResults[CursorIndex] = indexer::Indexed<PersistentDeclRef<Decl>>(
+      PersistentDeclRef<Decl>::create(Result ? DQ->getInputs()[CursorIndex]
+                                             : nullptr),
+      Result ? indexer::QueryBoolResult::Yes : indexer::QueryBoolResult::No);
+  Wrapper->ConsumedResults++;
+  if (Wrapper->ConsumedResults == Wrapper->DeclResults.size()) {
+    // We've received all the results, pass them back to the query.
+    DQ->setOutput(std::move(Wrapper->DeclResults));
+  }
+  return CXIndexerQueryAction_None;
+}
+
+enum CXIndexerQueryAction
+clang_IndexerQuery_consumeFileResult(CXIndexerQuery Query, unsigned CursorIndex,
+                                     const char *Filename) {
+  if (!Query || !Filename)
+    return CXIndexerQueryAction_None;
+  auto *IQ =
+      static_cast<RefactoringContinuationWrapper::QueryWrapper *>(Query)->Query;
+  if (auto *ASTQuery =
+          dyn_cast<indexer::ASTUnitForImplementationOfDeclarationQuery>(IQ)) {
+    if (CursorIndex != 0)
+      return CXIndexerQueryAction_None;
+    ASTQuery->setResult(PersistentFileID(Filename));
+    return CXIndexerQueryAction_RunContinuationInTUThatHasThisFile;
+  }
+  return CXIndexerQueryAction_None;
+}
+}
diff --git a/tools/libclang/CXIndexDataConsumer.cpp b/tools/libclang/CXIndexDataConsumer.cpp
index a2ef68b..2cfecf7 100644
--- a/tools/libclang/CXIndexDataConsumer.cpp
+++ b/tools/libclang/CXIndexDataConsumer.cpp
@@ -1258,6 +1258,8 @@
   case SymbolKind::Module:
   case SymbolKind::Macro:
   case SymbolKind::ClassProperty:
+  case SymbolKind::Using:
+  case SymbolKind::CommentTag:
     return CXIdxEntity_Unexposed;
 
   case SymbolKind::Enum: return CXIdxEntity_Enum;
diff --git a/tools/libclang/Indexing.cpp b/tools/libclang/Indexing.cpp
index 5312b7c..2a13624 100644
--- a/tools/libclang/Indexing.cpp
+++ b/tools/libclang/Indexing.cpp
@@ -272,7 +272,8 @@
   /// SourceRangeSkipped - This hook is called when a source range is skipped.
   /// \param Range The SourceRange that was skipped. The range begins at the
   /// #if/#else directive and ends after the #endif/#else directive.
-  void SourceRangeSkipped(SourceRange Range) override {}
+  void SourceRangeSkipped(SourceRange Range, SourceLocation EndifLoc) override {
+  }
 };
 
 //===----------------------------------------------------------------------===//
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index e0d178a..e9a9b58 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -353,3 +353,57 @@
 clang_EvalResult_getAsDouble
 clang_EvalResult_getAsStr
 clang_EvalResult_dispose
+clang_RefactoringActionType_getName
+clang_RefactoringActionSet_dispose
+clang_RefactoringActionSetWithDiagnostics_dispose
+clang_RefactoringOptionSet_create
+clang_RefactoringOptionSet_createFromString
+clang_RefactoringOptionSet_add
+clang_RefactoringOptionSet_toString
+clang_RefactoringOptionSet_dispose
+clang_Refactoring_findActionsAt
+clang_Refactoring_findActionsWithInitiationFailureDiagnosicsAt
+clang_RefactoringAction_dispose
+clang_RefactoringAction_getSourceRangeOfInterest
+clang_RefactoringAction_getInitiatedActionType
+clang_RefactoringAction_requiresImplementationTU
+clang_RefactoringAction_getUSRThatRequiresImplementationTU
+clang_RefactoringAction_addImplementationTU
+clang_RefactoringAction_getRefactoringCandidates
+clang_RefactoringAction_selectRefactoringCandidate
+clang_Refactoring_initiateActionAt
+clang_Refactoring_initiateAction
+clang_Refactoring_initiateActionOnDecl
+clang_Refactoring_initiateRenamingOperation
+clang_RenamingOperation_setNewName
+clang_RenamingOperation_getNumSymbols
+clang_RenamingOperation_getUSRForSymbol
+clang_Refactoring_findRenamedCursor
+clang_Refactoring_findRenamedOccurrencesInPrimaryTUs
+clang_Refactoring_findSymbolOccurrencesInInitiationTU
+clang_Refactoring_findRenamedOccurrencesInIndexedFile
+clang_Refactoring_findSymbolOccurrencesInIndexedFile
+clang_RenamingResult_getNumModifiedFiles
+clang_RenamingResult_getResultForFile
+clang_RenamingResult_dispose
+clang_SymbolOccurrences_getNumFiles
+clang_SymbolOccurrences_getOccurrencesForFile
+clang_SymbolOccurrences_dispose
+clang_Refactoring_performOperation
+clang_RefactoringResult_getReplacements
+clang_RefactoringResult_getSourceReplacements
+clang_RefactoringReplacement_getAssociatedSymbolOccurrences
+clang_RefactoringResult_getContinuation
+clang_RefactoringResult_dispose
+clang_RefactoringContinuation_loadSerializedIndexerQueryResults
+clang_RefactoringContinuation_getNumIndexerQueries
+clang_RefactoringContinuation_getIndexerQuery
+clang_RefactoringContinuation_verifyBeforeFinalizing
+clang_RefactoringContinuation_finalizeEvaluationInInitationTU
+clang_RefactoringContinuation_continueOperationInTU
+clang_RefactoringContinuation_dispose
+clang_IndexerQuery_getKind
+clang_IndexerQuery_getNumCursors
+clang_IndexerQuery_getCursor
+clang_IndexerQuery_consumeIntResult
+clang_IndexerQuery_consumeFileResult
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/ASTMatchers/ASTMatchersNarrowingTest.cpp b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 7bc8421..6037127 100644
--- a/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1108,35 +1108,26 @@
 }
 
 TEST(ConstructorDeclaration, Kinds) {
-  EXPECT_TRUE(matches(
-      "struct S { S(); };",
-      cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
-  EXPECT_TRUE(notMatches(
-      "struct S { S(); };",
-      cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
-  EXPECT_TRUE(notMatches(
-      "struct S { S(); };",
-      cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
+  EXPECT_TRUE(matches("struct S { S(); };",
+                      cxxConstructorDecl(isDefaultConstructor())));
+  EXPECT_TRUE(notMatches("struct S { S(); };",
+                         cxxConstructorDecl(isCopyConstructor())));
+  EXPECT_TRUE(notMatches("struct S { S(); };",
+                         cxxConstructorDecl(isMoveConstructor())));
 
-  EXPECT_TRUE(notMatches(
-      "struct S { S(const S&); };",
-      cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
-  EXPECT_TRUE(matches(
-      "struct S { S(const S&); };",
-      cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
-  EXPECT_TRUE(notMatches(
-      "struct S { S(const S&); };",
-      cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
+  EXPECT_TRUE(notMatches("struct S { S(const S&); };",
+                         cxxConstructorDecl(isDefaultConstructor())));
+  EXPECT_TRUE(matches("struct S { S(const S&); };",
+                      cxxConstructorDecl(isCopyConstructor())));
+  EXPECT_TRUE(notMatches("struct S { S(const S&); };",
+                         cxxConstructorDecl(isMoveConstructor())));
 
-  EXPECT_TRUE(notMatches(
-      "struct S { S(S&&); };",
-      cxxConstructorDecl(isDefaultConstructor(), unless(isImplicit()))));
-  EXPECT_TRUE(notMatches(
-      "struct S { S(S&&); };",
-      cxxConstructorDecl(isCopyConstructor(), unless(isImplicit()))));
-  EXPECT_TRUE(matches(
-      "struct S { S(S&&); };",
-      cxxConstructorDecl(isMoveConstructor(), unless(isImplicit()))));
+  EXPECT_TRUE(notMatches("struct S { S(S&&); };",
+                         cxxConstructorDecl(isDefaultConstructor())));
+  EXPECT_TRUE(notMatches("struct S { S(S&&); };",
+                         cxxConstructorDecl(isCopyConstructor())));
+  EXPECT_TRUE(matches("struct S { S(S&&); };",
+                      cxxConstructorDecl(isMoveConstructor())));
 }
 
 TEST(ConstructorDeclaration, IsUserProvided) {
diff --git a/unittests/Frontend/ASTUnitTest.cpp b/unittests/Frontend/ASTUnitTest.cpp
new file mode 100644
index 0000000..a7d08a9
--- /dev/null
+++ b/unittests/Frontend/ASTUnitTest.cpp
@@ -0,0 +1,87 @@
+//===- unittests/Frontend/ASTUnitTest.cpp - ASTUnit tests -----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <fstream>
+
+#include "clang/Frontend/ASTUnit.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/CompilerInvocation.h"
+#include "clang/Frontend/PCHContainerOperations.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang;
+
+namespace {
+
+TEST(ASTUnit, SaveLoadPreservesLangOptionsInPrintingPolicy) {
+  // Check that the printing policy is restored with the correct language
+  // options when loading an ASTUnit from a file.  To this end, an ASTUnit
+  // for a C++ translation unit is set up and written to a temporary file.
+
+  // By default `UseVoidForZeroParams` is true for non-C++ language options,
+  // thus we can check this field after loading the ASTUnit to deduce whether
+  // the correct (C++) language options were used when setting up the printing
+  // policy.
+
+  {
+    PrintingPolicy PolicyWithDefaultLangOpt(LangOptions{});
+    EXPECT_TRUE(PolicyWithDefaultLangOpt.UseVoidForZeroParams);
+  }
+
+  int FD;
+  llvm::SmallString<256> InputFileName;
+  ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "cpp", FD, InputFileName));
+  tool_output_file input_file(InputFileName, FD);
+  input_file.os() << "";
+
+  const char* Args[] = {"clang", "-xc++", InputFileName.c_str()};
+
+  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
+      CompilerInstance::createDiagnostics(new DiagnosticOptions());
+
+  std::shared_ptr<CompilerInvocation> CInvok =
+      createInvocationFromCommandLine(Args, Diags);
+
+  if (!CInvok)
+    FAIL() << "could not create compiler invocation";
+
+  FileManager *FileMgr =
+      new FileManager(FileSystemOptions(), vfs::getRealFileSystem());
+  auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
+
+  std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
+      CInvok, PCHContainerOps, Diags, FileMgr);
+
+  if (!AST)
+    FAIL() << "failed to create ASTUnit";
+
+  EXPECT_FALSE(AST->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
+
+  llvm::SmallString<256> ASTFileName;
+  ASSERT_FALSE(llvm::sys::fs::createTemporaryFile("ast-unit", "ast", FD, ASTFileName));
+  tool_output_file ast_file(ASTFileName, FD);
+  AST->Save(ASTFileName.str());
+
+  EXPECT_TRUE(llvm::sys::fs::exists(ASTFileName));
+
+  std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
+      ASTFileName.str(), PCHContainerOps->getRawReader(), ASTUnit::LoadEverything, Diags,
+      FileSystemOptions(), /*UseDebugInfo=*/false);
+
+  if (!AU)
+    FAIL() << "failed to load ASTUnit";
+
+  EXPECT_FALSE(AU->getASTContext().getPrintingPolicy().UseVoidForZeroParams);
+}
+
+} // anonymous namespace
diff --git a/unittests/Frontend/CMakeLists.txt b/unittests/Frontend/CMakeLists.txt
index 674f77b..4312151 100644
--- a/unittests/Frontend/CMakeLists.txt
+++ b/unittests/Frontend/CMakeLists.txt
@@ -3,6 +3,7 @@
   )
 
 add_clang_unittest(FrontendTests
+  ASTUnitTest.cpp
   FrontendActionTest.cpp
   CodeGenActionTest.cpp
   )
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/Tooling/RefactoringTest.cpp b/unittests/Tooling/RefactoringTest.cpp
index 1590094..07aef25 100644
--- a/unittests/Tooling/RefactoringTest.cpp
+++ b/unittests/Tooling/RefactoringTest.cpp
@@ -25,6 +25,9 @@
 #include "clang/Frontend/FrontendAction.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Rewrite/Core/Rewriter.h"
+#include "clang/Tooling/Refactor/IndexerQuery.h"
+#include "clang/Tooling/Refactor/RefactoringOperation.h"
+#include "clang/Tooling/Refactor/RefactoringOptions.h"
 #include "clang/Tooling/Refactoring.h"
 #include "clang/Tooling/Refactoring/AtomicChange.h"
 #include "clang/Tooling/Tooling.h"
@@ -1090,6 +1093,51 @@
   EXPECT_TRUE(FileToReplaces.empty());
 }
 
+namespace {
+struct TestRefactoringValueOption final : RefactoringOption {
+  int Value;
+  TestRefactoringValueOption(int Value) : Value(Value) {}
+
+  static constexpr const char *Name = "test value option";
+};
+} // end anonymous namespace
+
+TEST(RefactoringOptionSet, AddGet) {
+  RefactoringOptionSet Options;
+  const TestRefactoringValueOption Kind(21);
+  const TestRefactoringValueOption DefaultKind(42);
+
+  EXPECT_EQ(Options.get<TestRefactoringValueOption>(), nullptr);
+  EXPECT_EQ(Options.get(DefaultKind).Value, DefaultKind.Value);
+
+  Options.add(Kind);
+
+  auto *Ptr = Options.get<TestRefactoringValueOption>();
+  ASSERT_TRUE(Ptr);
+  EXPECT_EQ(Ptr->Value, Kind.Value);
+  EXPECT_EQ(Options.get(DefaultKind).Value, Kind.Value);
+}
+
+namespace {
+struct TestRefactoringOption final : RefactoringOption {
+  int &Counter;
+  TestRefactoringOption(int &Counter) : Counter(Counter) {}
+  ~TestRefactoringOption() { ++Counter; }
+
+  static constexpr const char *Name = "test option";
+};
+} // end anonymous namespace
+
+TEST(RefactoringOptionSet, OptionDestroyed) {
+  int Counter = 0;
+  {
+    RefactoringOptionSet Options;
+    Options.add(TestRefactoringOption(Counter));
+    Options.add(TestRefactoringOption(Counter));
+  }
+  EXPECT_EQ(Counter, 3);
+}
+
 class AtomicChangeTest : public ::testing::Test {
   protected:
     void SetUp() override {
@@ -1295,5 +1343,127 @@
       Replacement(Context.Sources, SourceLocation(), 0, "b")));
 }
 
+namespace {
+
+class RefactoringOperationTest {
+  RefactoringActionType Type;
+  unsigned Line, Column;
+  bool Success = true;
+  std::function<void(const RefactoringResult &Result)> ResultHandler;
+
+public:
+  RefactoringOperationTest(
+      RefactoringActionType Type, unsigned Line, unsigned Column,
+      std::function<void(const RefactoringResult &Result)> ResultHandler)
+      : Type(Type), Line(Line), Column(Column),
+        ResultHandler(std::move(ResultHandler)) {}
+
+  bool runOver(StringRef Code) {
+    return runToolOnCode(new TestAction(this), Code);
+  }
+
+  bool succeeded() const { return Success; }
+
+  void run() {
+    assert(PP && Context && "Invalid state");
+    SourceLocation Loc = Context->getSourceManager().translateLineCol(
+        Context->getSourceManager().getMainFileID(), Line, Column);
+    if (Loc.isInvalid()) {
+      Success = false;
+      return;
+    }
+    RefactoringOperationResult Op =
+        initiateRefactoringOperationAt(Loc, SourceRange(), *Context, Type);
+    if (!Op.Initiated) {
+      Success = false;
+      return;
+    }
+    RefactoringOptionSet Options;
+    llvm::Expected<RefactoringResult> Result =
+        Op.RefactoringOp->perform(*Context, *PP, Options);
+    if (!Result) {
+      (void)!llvm::handleErrors(
+          Result.takeError(),
+          [&](const RefactoringOperationError &Error) { Success = false; });
+      return;
+    }
+    ResultHandler(Result.get());
+  }
+
+protected:
+  clang::Preprocessor *PP;
+  clang::ASTContext *Context;
+
+private:
+  class TestConsumer : public clang::ASTConsumer {
+  public:
+    TestConsumer(RefactoringOperationTest *Test) : Test(Test) {}
+
+    void HandleTranslationUnit(clang::ASTContext &Context) override {
+      Test->run();
+    }
+
+  private:
+    RefactoringOperationTest *Test;
+  };
+
+  class TestAction : public clang::ASTFrontendAction {
+  public:
+    TestAction(RefactoringOperationTest *Test) : Test(Test) {}
+
+    std::unique_ptr<clang::ASTConsumer>
+    CreateASTConsumer(clang::CompilerInstance &Compiler,
+                      llvm::StringRef) override {
+      Test->PP = &Compiler.getPreprocessor();
+      Test->Context = &Compiler.getASTContext();
+      return llvm::make_unique<TestConsumer>(Test);
+    }
+
+  private:
+    RefactoringOperationTest *Test;
+  };
+};
+
+} // end anonymous namespace
+
+TEST(RefactoringContinuation, ContinuationAndQueriesExist) {
+  using namespace clang::tooling::indexer;
+  using namespace clang::tooling::indexer::detail;
+  RefactoringOperationTest Test(
+      RefactoringActionType::ImplementDeclaredMethods, 2, 1,
+      [](const RefactoringResult &Result) {
+        EXPECT_TRUE(Result.Replacements.empty());
+        ASSERT_NE(Result.Continuation, nullptr);
+        RefactoringContinuation &Continuation = *Result.Continuation;
+
+        ASTProducerQuery *ASTQuery = Continuation.getASTUnitIndexerQuery();
+        ASSERT_NE(ASTQuery, nullptr);
+        EXPECT_TRUE(isa<ASTProducerQuery>(ASTQuery));
+        EXPECT_TRUE(isa<ASTUnitForImplementationOfDeclarationQuery>(ASTQuery));
+        EXPECT_FALSE(isa<DeclarationsQuery>(ASTQuery));
+
+        auto AdditionalQueries = Continuation.getAdditionalIndexerQueries();
+        ASSERT_EQ(AdditionalQueries.size(), (size_t)1);
+        EXPECT_FALSE(isa<ASTProducerQuery>(AdditionalQueries[0]));
+        EXPECT_FALSE(isa<ASTUnitForImplementationOfDeclarationQuery>(
+            AdditionalQueries[0]));
+        ASSERT_TRUE(isa<DeclarationsQuery>(AdditionalQueries[0]));
+
+        const DeclPredicateNode &Predicate =
+            cast<DeclarationsQuery>(AdditionalQueries[0])->getPredicateNode();
+        ASSERT_TRUE(isa<DeclPredicateNotPredicate>(Predicate));
+        const DeclPredicateNode &SubPredicate =
+            cast<DeclPredicateNotPredicate>(Predicate).getChild();
+        ASSERT_TRUE(isa<DeclPredicateNodePredicate>(SubPredicate));
+        EXPECT_EQ(cast<DeclPredicateNodePredicate>(SubPredicate).getPredicate(),
+                  DeclEntity().isDefined().Predicate);
+
+        ASTQuery->invalidateTUSpecificState();
+        AdditionalQueries[0]->invalidateTUSpecificState();
+      });
+  Test.runOver("class Foo {\nvoid method();\n};\n");
+  EXPECT_TRUE(Test.succeeded());
+}
+
 } // end namespace tooling
 } // end namespace clang
diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp
index f2a96d6..d5a9cbf 100644
--- a/unittests/libclang/LibclangTest.cpp
+++ b/unittests/libclang/LibclangTest.cpp
@@ -8,6 +8,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang-c/Index.h"
+#include "clang-c/Refactor.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -572,3 +573,71 @@
   EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
   DisplayDiagnostics();
 }
+
+TEST(libclang, RefactoringAction) {
+  std::string Name =
+      clang_getCString(clang_RefactoringActionType_getName(CXRefactor_Rename));
+  EXPECT_EQ(Name, "Rename");
+}
+
+TEST_F(LibclangParseTest, RefactoringFindRenamedCursor) {
+  std::string Filename = "test.cpp";
+  WriteFile(Filename, "int renamable = 0;\n");
+
+  ClangTU = clang_parseTranslationUnit(Index, Filename.c_str(), nullptr, 0,
+                                       nullptr, 0, TUFlags);
+  CXSourceLocation Loc = clang_getLocation(
+      ClangTU, clang_getFile(ClangTU, Filename.c_str()), 1, 5);
+  CXSourceRange Range = clang_getRange(Loc, Loc);
+  CXCursor Cursor;
+  EXPECT_EQ(CXError_Success,
+            clang_Refactoring_findRenamedCursor(ClangTU, Loc, Range, &Cursor));
+  EXPECT_EQ(Cursor.kind, CXCursor_VarDecl);
+}
+
+TEST_F(LibclangParseTest, RefactoringRenameIndexedUnsavedFiles) {
+  std::string Filename = "test.cpp";
+  std::string PartialSource = "class Test { };\n";
+  WriteFile(Filename, PartialSource);
+  std::string FullSource = PartialSource + "Test t;\n";
+
+  CXIndexedSymbolLocation IndexedLocations[2] = {
+      {{1, 7}, CXCursor_DeclRefExpr}, {{2, 1}, CXCursor_DeclRefExpr}};
+  CXIndexedSymbol Symbols[1] = {
+      {IndexedLocations, 2, CXCursor_DeclRefExpr, /*Name=*/"Test"}};
+
+  CXIndex Idx = clang_createIndex(0, 0);
+
+  auto test = [&](CXUnsavedFile *File = nullptr) -> CXSymbolOccurrencesInFile {
+    CXSymbolOccurrencesResult Result;
+    CXErrorCode Err = clang_Refactoring_findSymbolOccurrencesInIndexedFile(
+        Symbols, 1, Idx, Filename.c_str(), nullptr, 0, File, File ? 1 : 0,
+        /*Options=*/nullptr, &Result);
+    EXPECT_EQ(CXError_Success, Err);
+    unsigned NumFiles = clang_SymbolOccurrences_getNumFiles(Result);
+    EXPECT_EQ(NumFiles, 1u);
+    CXSymbolOccurrencesInFile Occurrences;
+    clang_SymbolOccurrences_getOccurrencesForFile(Result, 0, &Occurrences);
+    return Occurrences;
+  };
+  CXSymbolOccurrencesInFile FileOccurrences = test();
+  EXPECT_EQ(FileOccurrences.NumOccurrences, 1u);
+  EXPECT_EQ(clang_getCString(FileOccurrences.Filename), Filename);
+  EXPECT_EQ(FileOccurrences.Occurrences[0].NumNamePieces, 1u);
+  EXPECT_EQ(FileOccurrences.Occurrences[0].NamePieces[0].Begin.Line, 1u);
+  EXPECT_EQ(FileOccurrences.Occurrences[0].NamePieces[0].Begin.Column, 7u);
+
+  CXUnsavedFile UnsavedFile = {Filename.c_str(), FullSource.c_str(),
+                               FullSource.size()};
+  CXSymbolOccurrencesInFile UnsavedFileOccurrences = test(&UnsavedFile);
+  EXPECT_EQ(UnsavedFileOccurrences.NumOccurrences, 2u);
+  EXPECT_EQ(clang_getCString(UnsavedFileOccurrences.Filename), Filename);
+  EXPECT_EQ(UnsavedFileOccurrences.Occurrences[0].NumNamePieces, 1u);
+  EXPECT_EQ(UnsavedFileOccurrences.Occurrences[0].NamePieces[0].Begin.Line, 1u);
+  EXPECT_EQ(UnsavedFileOccurrences.Occurrences[0].NamePieces[0].Begin.Column,
+            7u);
+  EXPECT_EQ(UnsavedFileOccurrences.Occurrences[1].NumNamePieces, 1u);
+  EXPECT_EQ(UnsavedFileOccurrences.Occurrences[1].NamePieces[0].Begin.Line, 2u);
+  EXPECT_EQ(UnsavedFileOccurrences.Occurrences[1].NamePieces[0].Begin.Column,
+            1u);
+}
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index b6d2988..333bd13 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -1163,6 +1163,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(Record, vec);\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>
@@ -1212,6 +1238,8 @@
     Ptr = llvm::make_unique<VariadicExprArgument>(Arg, Attr);
   else if (ArgName == "VersionArgument")
     Ptr = llvm::make_unique<VersionArgument>(Arg, Attr);
+  else if (ArgName == "AttrArgument")
+    Ptr = llvm::make_unique<AttrArgument>(Arg, Attr);
 
   if (!Ptr) {
     // Search in reverse order so that the most-derived type is handled first.
diff --git a/utils/perf-training/lit.cfg b/utils/perf-training/lit.cfg
index 671d44f..1deb080 100644
--- a/utils/perf-training/lit.cfg
+++ b/utils/perf-training/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 = subprocess.check_output(['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 93904ec..2e7acc7 100644
--- a/utils/perf-training/order-files.lit.cfg
+++ b/utils/perf-training/order-files.lit.cfg
@@ -9,7 +9,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 = subprocess.check_output(['xcrun', '--show-sdk-path']).strip()
             res = 0