Propagating prior merge from 'llvm.org/release_50'.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2667b1d..04ab7b7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -186,8 +186,6 @@
   set(CLANG_HAVE_LIBXML 1)
 endif()
 
-find_package(Z3 4.5)
-
 include(CheckIncludeFile)
 check_include_file(sys/resource.h CLANG_HAVE_RLIMITS)
 
@@ -381,6 +379,7 @@
 endif()
 
 if(CLANG_ANALYZER_BUILD_Z3)
+  find_package(Z3 4.5)
   if(Z3_FOUND)
     set(CLANG_ANALYZER_WITH_Z3 1)
   else()
@@ -411,7 +410,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/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake
index 1b7b636..52c5794 100644
--- a/cmake/caches/Fuchsia-stage2.cmake
+++ b/cmake/caches/Fuchsia-stage2.cmake
@@ -31,6 +31,7 @@
   set(BUILTINS_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "")
   set(BUILTINS_${target}-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
 endforeach()
+
 if(NOT APPLE)
   list(APPEND LLVM_BUILTIN_TARGETS "default")
 endif()
@@ -45,7 +46,11 @@
   set(RUNTIMES_${target}-fuchsia_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "")
   set(RUNTIMES_${target}-fuchsia_LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
   set(RUNTIMES_${target}-fuchsia_LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
+  set(RUNTIMES_${target}-fuchsia_LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "")
   set(RUNTIMES_${target}-fuchsia_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
+  set(RUNTIMES_${target}-fuchsia_LIBCXX_ABI_VERSION 2 CACHE STRING "")
+  set(RUNTIMES_${target}-fuchsia_LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
+  set(RUNTIMES_${target}-fuchsia_SANITIZER_USE_COMPILER_RT ON CACHE BOOL "")
 endforeach()
 
 # Setup toolchain.
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/ControlFlowIntegrity.rst b/docs/ControlFlowIntegrity.rst
index eed5ac5..04fb43a 100644
--- a/docs/ControlFlowIntegrity.rst
+++ b/docs/ControlFlowIntegrity.rst
@@ -243,17 +243,25 @@
 
 A :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain
 source files, functions and types using the ``src``, ``fun`` and ``type``
-entity types.
+entity types. Specific CFI modes can be be specified using ``[section]``
+headers.
 
 .. code-block:: bash
 
-    # Suppress checking for code in a file.
+    # Suppress all CFI checking for code in a file.
     src:bad_file.cpp
     src:bad_header.h
     # Ignore all functions with names containing MyFooBar.
     fun:*MyFooBar*
     # Ignore all types in the standard library.
     type:std::*
+    # Disable only unrelated cast checks for this function
+    [cfi-unrelated-cast]
+    fun:*UnrelatedCast*
+    # Disable CFI call checks for this function without affecting cast checks
+    [cfi-vcall|cfi-nvcall|cfi-icall]
+    fun:*BadCall*
+
 
 .. _cfi-cross-dso:
 
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..faf7f40 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -65,6 +65,9 @@
    default. It warns about unguarded uses of APIs only when they were introduced
    in or after macOS 10.13, iOS 11, tvOS 11 or watchOS 4.
 
+- ``-Wzero-as-null-pointer-constant`` was adjusted not to warn on null pointer
+  constants that originate from system macros, except ``NULL`` macro.
+
 -  The ``-Wdocumentation`` warning now allows the use of ``\param`` and
    ``\returns`` documentation directives in the documentation comments for
    declarations with a function or a block pointer type.
@@ -316,28 +319,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/SanitizerSpecialCaseList.rst b/docs/SanitizerSpecialCaseList.rst
index a4165b2..a636a02 100644
--- a/docs/SanitizerSpecialCaseList.rst
+++ b/docs/SanitizerSpecialCaseList.rst
@@ -51,14 +51,23 @@
 Format
 ======
 
-Each line contains an entity type, followed by a colon and a regular
-expression, specifying the names of the entities, optionally followed by
-an equals sign and a tool-specific category. Empty lines and lines starting
-with "#" are ignored. The meanining of ``*`` in regular expression for entity
-names is different - it is treated as in shell wildcarding. Two generic
-entity types are ``src`` and ``fun``, which allow user to add, respectively,
-source files and functions to special case list. Some sanitizer tools may
-introduce custom entity types - refer to tool-specific docs.
+Blacklists consist of entries, optionally grouped into sections. Empty lines and
+lines starting with "#" are ignored.
+
+Section names are regular expressions written in square brackets that denote
+which sanitizer the following entries apply to. For example, ``[address]``
+specifies AddressSanitizer while ``[cfi-vcall|cfi-icall]`` specifies Control
+Flow Integrity virtual and indirect call checking. Entries without a section
+will be placed under the ``[*]`` section applying to all enabled sanitizers.
+
+Entries contain an entity type, followed by a colon and a regular expression,
+specifying the names of the entities, optionally followed by an equals sign and
+a tool-specific category, e.g. ``fun:*ExampleFunc=example_category``.  The
+meaning of ``*`` in regular expression for entity names is different - it is
+treated as in shell wildcarding. Two generic entity types are ``src`` and
+``fun``, which allow users to specify source files and functions, respectively.
+Some sanitizer tools may introduce custom entity types and categories - refer to
+tool-specific docs.
 
 .. code-block:: bash
 
@@ -77,3 +86,10 @@
     fun:*BadFunction*
     # Specific sanitizer tools may introduce categories.
     src:/special/path/*=special_sources
+    # Sections can be used to limit blacklist entries to specific sanitizers
+    [address]
+    fun:*BadASanFunc*
+    # Section names are regular expressions
+    [cfi-vcall|cfi-icall]
+    fun:*BadCfiCall
+    # Entries without sections are placed into [*] and apply to all sanitizers
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/docs/analyzer/DebugChecks.rst b/docs/analyzer/DebugChecks.rst
index 880dcfc..e2a8e05 100644
--- a/docs/analyzer/DebugChecks.rst
+++ b/docs/analyzer/DebugChecks.rst
@@ -74,7 +74,7 @@
 ExprInspection checks
 ---------------------
 
-- void clang_analyzer_eval(bool);
+- ``void clang_analyzer_eval(bool);``
 
   Prints TRUE if the argument is known to have a non-zero value, FALSE if the
   argument is known to have a zero or null value, and UNKNOWN if the argument
@@ -93,7 +93,7 @@
     clang_analyzer_eval(x); // expected-warning{{TRUE}}
 
 
-- void clang_analyzer_checkInlined(bool);
+- ``void clang_analyzer_checkInlined(bool);``
 
   If a call occurs within an inlined function, prints TRUE or FALSE according to
   the value of its argument. If a call occurs outside an inlined function,
@@ -125,7 +125,7 @@
       clang_analyzer_eval(value == 42); // expected-warning{{TRUE}}
     }
 
-- void clang_analyzer_warnIfReached();
+- ``void clang_analyzer_warnIfReached();``
 
   Generate a warning if this line of code gets reached by the analyzer.
 
@@ -138,7 +138,7 @@
       clang_analyzer_warnIfReached();  // no-warning
     }
 
-- void clang_analyzer_numTimesReached();
+- ``void clang_analyzer_numTimesReached();``
 
   Same as above, but include the number of times this call expression
   gets reached by the analyzer during the current analysis.
@@ -149,7 +149,7 @@
       clang_analyzer_numTimesReached(); // expected-warning{{3}}
     }
 
-- void clang_analyzer_warnOnDeadSymbol(int);
+- ``void clang_analyzer_warnOnDeadSymbol(int);``
 
   Subscribe for a delayed warning when the symbol that represents the value of
   the argument is garbage-collected by the analyzer.
@@ -173,7 +173,7 @@
     } while(0);  // expected-warning{{SYMBOL DEAD}}
 
 
-- void clang_analyzer_explain(a single argument of any type);
+- ``void clang_analyzer_explain(a single argument of any type);``
 
   This function explains the value of its argument in a human-readable manner
   in the warning message. You can make as many overrides of its prototype
@@ -197,7 +197,7 @@
         clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}
     }
 
-- void clang_analyzer_dump(a single argument of any type);
+- ``void clang_analyzer_dump( /* a single argument of any type */);``
 
   Similar to clang_analyzer_explain, but produces a raw dump of the value,
   same as SVal::dump().
@@ -209,7 +209,7 @@
       clang_analyzer_dump(x); // expected-warning{{reg_$0<x>}}
     }
 
-- size_t clang_analyzer_getExtent(void *);
+- ``size_t clang_analyzer_getExtent(void *);``
 
   This function returns the value that represents the extent of a memory region
   pointed to by the argument. This value is often difficult to obtain otherwise,
@@ -226,7 +226,7 @@
       clang_analyzer_explain(ys); // expected-warning{{'8'}}
     }
 
-- void clang_analyzer_printState();
+- ``void clang_analyzer_printState();``
 
   Dumps the current ProgramState to the stderr. Quickly lookup the program state
   at any execution point without ViewExplodedGraph or re-compiling the program.
diff --git a/docs/analyzer/DesignDiscussions/InitializerLists.rst b/docs/analyzer/DesignDiscussions/InitializerLists.rst
new file mode 100644
index 0000000..b826547
--- /dev/null
+++ b/docs/analyzer/DesignDiscussions/InitializerLists.rst
@@ -0,0 +1,321 @@
+This discussion took place in https://reviews.llvm.org/D35216
+"Escape symbols when creating std::initializer_list".
+
+It touches problems of modelling C++ standard library constructs in general,
+including modelling implementation-defined fields within C++ standard library
+objects, in particular constructing objects into pointers held by such fields,
+and separation of responsibilities between analyzer's core and checkers.
+
+**Artem:**
+
+I've seen a few false positives that appear because we construct
+C++11 std::initializer_list objects with brace initializers, and such
+construction is not properly modeled. For instance, if a new object is
+constructed on the heap only to be put into a brace-initialized STL container,
+the object is reported to be leaked.
+
+Approach (0): This can be trivially fixed by this patch, which causes pointers
+passed into initializer list expressions to immediately escape.
+
+This fix is overly conservative though. So i did a bit of investigation as to
+how model std::initializer_list better.
+
+According to the standard, std::initializer_list<T> is an object that has
+methods begin(), end(), and size(), where begin() returns a pointer to continous
+array of size() objects of type T, and end() is equal to begin() plus size().
+The standard does hint that it should be possible to implement
+std::initializer_list<T> as a pair of pointers, or as a pointer and a size
+integer, however specific fields that the object would contain are an
+implementation detail.
+
+Ideally, we should be able to model the initializer list's methods precisely.
+Or, at least, it should be possible to explain to the analyzer that the list
+somehow "takes hold" of the values put into it. Initializer lists can also be
+copied, which is a separate story that i'm not trying to address here.
+
+The obvious approach to modeling std::initializer_list in a checker would be to
+construct a SymbolMetadata for the memory region of the initializer list object,
+which would be of type T* and represent begin(), so we'd trivially model begin()
+as a function that returns this symbol. The array pointed to by that symbol
+would be bindLoc()ed to contain the list's contents (probably as a CompoundVal
+to produce less bindings in the store). Extent of this array would represent
+size() and would be equal to the length of the list as written.
+
+So this sounds good, however apparently it does nothing to address our false
+positives: when the list escapes, our RegionStoreManager is not magically
+guessing that the metadata symbol attached to it, together with its contents,
+should also escape. In fact, it's impossible to trigger a pointer escape from
+within the checker.
+
+Approach (1): If only we enabled ProgramState::bindLoc(..., notifyChanges=true)
+to cause pointer escapes (not only region changes) (which sounds like the right
+thing to do anyway) such checker would be able to solve the false positives by
+triggering escapes when binding list elements to the list. However, it'd be as
+conservative as the current patch's solution. Ideally, we do not want escapes to
+happen so early. Instead, we'd prefer them to be delayed until the list itself
+escapes.
+
+So i believe that escaping metadata symbols whenever their base regions escape
+would be the right thing to do. Currently we didn't think about that because we
+had neither pointer-type metadatas nor non-pointer escapes.
+
+Approach (2): We could teach the Store to scan itself for bindings to
+metadata-symbolic-based regions during scanReachableSymbols() whenever a region
+turns out to be reachable. This requires no work on checker side, but it sounds
+performance-heavy.
+
+Approach (3): We could let checkers maintain the set of active metadata symbols
+in the program state (ideally somewhere in the Store, which sounds weird but
+causes the smallest amount of layering violations), so that the core knew what
+to escape. This puts a stress on the checkers, but with a smart data map it
+wouldn't be a problem.
+
+Approach (4): We could allow checkers to trigger pointer escapes in arbitrary
+moments. If we allow doing this within checkPointerEscape callback itself, we
+would be able to express facts like "when this region escapes, that metadata
+symbol attached to it should also escape". This sounds like an ultimate freedom,
+with maximum stress on the checkers - still not too much stress when we have
+smart data maps.
+
+I'm personally liking the approach (2) - it should be possible to avoid
+performance overhead, and clarity seems nice.
+
+**Gabor:**
+
+At this point, I am a bit wondering about two questions.
+
+- When should something belong to a checker and when should something belong
+to the engine? Sometimes we model library aspects in the engine and model
+language constructs in checkers.
+- What is the checker programming model that we are aiming for? Maximum
+freedom or more easy checker development?
+
+I think if we aim for maximum freedom, we do not need to worry about the
+potential stress on checkers, and we can introduce abstractions to mitigate that
+later on.
+If we want to simplify the API, then maybe it makes more sense to move language
+construct modeling to the engine when the checker API is not sufficient instead
+of complicating the API.
+
+Right now I have no preference or objections between the alternatives but there
+are some random thoughts:
+
+- Maybe it would be great to have a guideline how to evolve the analyzer and
+follow it, so it can help us to decide in similar situations
+- I do care about performance in this case. The reason is that we have a
+limited performance budget. And I think we should not expect most of the checker
+writers to add modeling of language constructs. So, in my opinion, it is ok to
+have less nice/more verbose API for language modeling if we can have better
+performance this way, since it only needs to be done once, and is done by the
+framework developers.
+
+**Artem:** These are some great questions, i guess it'd be better to discuss
+them more openly. As a quick dump of my current mood:
+
+- To me it seems obvious that we need to aim for a checker API that is both
+simple and powerful. This can probably by keeping the API as powerful as
+necessary while providing a layer of simple ready-made solutions on top of it.
+Probably a few reusable components for assembling checkers. And this layer
+should ideally be pleasant enough to work with, so that people would prefer to
+extend it when something is lacking, instead of falling back to the complex
+omnipotent API. I'm thinking of AST matchers vs. AST visitors as a roughly
+similar situation: matchers are not omnipotent, but they're so nice.
+
+- Separation between core and checkers is usually quite strange. Once we have
+shared state traits, i generally wouldn't mind having region store or range
+constraint manager as checkers (though it's probably not worth it to transform
+them - just a mood). The main thing to avoid here would be the situation when
+the checker overwrites stuff written by the core because it thinks it has a
+better idea what's going on, so the core should provide a good default behavior.
+
+- Yeah, i totally care about performance as well, and if i try to implement
+approach, i'd make sure it's good.
+
+**Artem:**
+
+> Approach (2): We could teach the Store to scan itself for bindings to
+> metadata-symbolic-based regions during scanReachableSymbols() whenever
+> a region turns out to be reachable. This requires no work on checker side,
+> but it sounds performance-heavy.
+
+Nope, this approach is wrong. Metadata symbols may become out-of-date: when the
+object changes, metadata symbols attached to it aren't changing (because symbols
+simply don't change). The same metadata may have different symbols to denote its
+value in different moments of time, but at most one of them represents the
+actual metadata value. So we'd be escaping more stuff than necessary.
+
+If only we had "ghost fields"
+(http://lists.llvm.org/pipermail/cfe-dev/2016-May/049000.html), it would have
+been much easier, because the ghost field would only contain the actual
+metadata, and the Store would always know about it. This example adds to my
+belief that ghost fields are exactly what we need for most C++ checkers.
+
+**Devin:**
+
+In this case, I would be fine with some sort of
+AbstractStorageMemoryRegion that meant "here is a memory region and somewhere
+reachable from here exists another region of type T". Or even multiple regions
+with different identifiers. This wouldn't specify how the memory is reachable,
+but it would allow for transfer functions to get at those regions and it would
+allow for invalidation.
+
+For std::initializer_list this reachable region would the region for the backing
+array and the transfer functions for begin() and end() yield the beginning and
+end element regions for it.
+
+In my view this differs from ghost variables in that (1) this storage does
+actually exist (it is just a library implementation detail where that storage
+lives) and (2) it is perfectly valid for a pointer into that storage to be
+returned and for another part of the program to read or write from that storage.
+(Well, in this case just read since it is allowed to be read-only memory).
+
+What I'm not OK with is modeling abstract analysis state (for example, the count
+of a NSMutableArray or the typestate of a file handle) as a value stored in some
+ginned up region in the store. This takes an easy problem that the analyzer does
+well at (modeling typestate) and turns it into a hard one that the analyzer is
+bad at (reasoning about the contents of the heap).
+
+I think the key criterion here is: "is the region accessible from outside the
+library". That is, does the library expose the region as a pointer that can be
+read to or written from in the client program? If so, then it makes sense for
+this to be in the store: we are modeling reachable storage as storage. But if
+we're just modeling arbitrary analysis facts that need to be invalidated when a
+pointer escapes then we shouldn't try to gin up storage for them just to get
+invalidation for free.
+
+**Artem:**
+
+> In this case, I would be fine with some sort of AbstractStorageMemoryRegion
+> that meant "here is a memory region and somewhere reachable from here exists
+> another region of type T". Or even multiple regions with different
+> identifiers. This wouldn't specify how the memory is reachable, but it would
+> allow for transfer functions to get at those regions and it would allow for
+> invalidation.
+
+Yeah, this is what we can easily implement now as a
+symbolic-region-based-on-a-metadata-symbol (though we can make a new region
+class for that if we eg. want it typed). The problem is that the relation
+between such storage region and its parent object region is essentially
+immaterial, similarly to the relation between SymbolRegionValue and its parent
+region. Region contents are mutable: today the abstract storage is reachable
+from its parent object, tomorrow it's not, and maybe something else becomes
+reachable, something that isn't even abstract. So the parent region for the
+abstract storage is most of the time at best a "nice to know" thing - we cannot
+rely on it to do any actual work. We'd anyway need to rely on the checker to do
+the job.
+
+> For std::initializer_list this reachable region would the region for the
+> backing array and the transfer functions for begin() and end() yield the
+> beginning and end element regions for it.
+
+So maybe in fact for std::initializer_list it may work fine because you cannot
+change the data after the object is constructed - so this region's contents are
+essentially immutable. For the future, i feel as if it is a dead end.
+
+I'd like to consider another funny example. Suppose we're trying to model
+std::unique_ptr. Consider::
+
+  void bar(const std::unique_ptr<int> &x);
+
+  void foo(std::unique_ptr<int> &x) {
+    int *a = x.get();   // (a, 0, direct): &AbstractStorageRegion
+    *a = 1;             // (AbstractStorageRegion, 0, direct): 1 S32b
+    int *b = new int;
+    *b = 2;             // (SymRegion{conj_$0<int *>}, 0 ,direct): 2 S32b
+    x.reset(b);         // Checker map: x -> SymRegion{conj_$0<int *>}
+    bar(x);             // 'a' doesn't escape (the pointer was unique), 'b' does.
+    clang_analyzer_eval(*a == 1); // Making this true is up to the checker.
+    clang_analyzer_eval(*b == 2); // Making this unknown is up to the checker.
+  }
+
+The checker doesn't totally need to ensure that *a == 1 passes - even though the
+pointer was unique, it could theoretically have .get()-ed above and the code
+could of course break the uniqueness invariant (though we'd probably want it).
+The checker can say that "even if *a did escape, it was not because it was
+stuffed directly into bar()".
+
+The checker's direct responsibility, however, is to solve the *b == 2 thing
+(which is in fact the problem we're dealing with in this patch - escaping the
+storage region of the object).
+
+So we're talking about one more operation over the program state (scanning
+reachable symbols and regions) that cannot work without checker support.
+
+We can probably add a new callback "checkReachableSymbols" to solve this. This
+is in fact also related to the dead symbols problem (we're scanning for live
+symbols in the store and in the checkers separately, but we need to do so
+simultaneously with a single worklist). Hmm, in fact this sounds like a good
+idea; we can replace checkLiveSymbols with checkReachableSymbols.
+
+Or we could just have ghost member variables, and no checker support required at
+all. For ghost member variables, the relation with their parent region (which
+would be their superregion) is actually useful, the mutability of their contents
+is expressed naturally, and the store automagically sees reachable symbols, live
+symbols, escapes, invalidations, whatever.
+
+> In my view this differs from ghost variables in that (1) this storage does
+> actually exist (it is just a library implementation detail where that storage
+> lives) and (2) it is perfectly valid for a pointer into that storage to be
+> returned and for another part of the program to read or write from that
+> storage. (Well, in this case just read since it is allowed to be read-only
+> memory).
+
+> What I'm not OK with is modeling abstract analysis state (for example, the
+> count of a NSMutableArray or the typestate of a file handle) as a value stored
+> in some ginned up region in the store.This takes an easy problem that the
+> analyzer does well at (modeling typestate) and turns it into a hard one that
+> the analyzer is bad at (reasoning about the contents of the heap).
+
+Yeah, i tend to agree on that. For simple typestates, this is probably an
+overkill, so let's definitely put aside the idea of "ghost symbolic regions"
+that i had earlier.
+
+But, to summarize a bit, in our current case, however, the typestate we're
+looking for is the contents of the heap. And when we try to model such
+typestates (complex in this specific manner, i.e. heap-like) in any checker, we
+have a choice between re-doing this modeling in every such checker (which is
+something analyzer is indeed good at, but at a price of making checkers heavy)
+or instead relying on the Store to do exactly what it's designed to do.
+
+> I think the key criterion here is: "is the region accessible from outside
+> the library". That is, does the library expose the region as a pointer that
+> can be read to or written from in the client program? If so, then it makes
+> sense for this to be in the store: we are modeling reachable storage as
+> storage. But if we're just modeling arbitrary analysis facts that need to be
+> invalidated when a pointer escapes then we shouldn't try to gin up storage
+> for them just to get invalidation for free.
+
+As a metaphor, i'd probably compare it to body farms - the difference between
+ghost member variables and metadata symbols seems to me like the difference
+between body farms and evalCall. Both are nice to have, and body farms are very
+pleasant to work with, even if not omnipotent. I think it's fine for a
+FunctionDecl's body in a body farm to have a local variable, even if such
+variable doesn't actually exist, even if it cannot be seen from outside the
+function call. I'm not seeing immediate practical difference between "it does
+actually exist" and "it doesn't actually exist, just a handy abstraction".
+Similarly, i think it's fine if we have a CXXRecordDecl with
+implementation-defined contents, and try to farm up a member variable as a handy
+abstraction (we don't even need to know its name or offset, only that it's there
+somewhere).
+
+**Artem:**
+
+We've discussed it in person with Devin, and he provided more points to think
+about:
+
+- If the initializer list consists of non-POD data, constructors of list's
+objects need to take the sub-region of the list's region as this-region In the
+current (v2) version of this patch, these objects are constructed elsewhere and
+then trivial-copied into the list's metadata pointer region, which may be
+incorrect. This is our overall problem with C++ constructors, which manifests in
+this case as well. Additionally, objects would need to be constructed in the
+analyzer's core, which would not be able to predict that it needs to take a
+checker-specific region as this-region, which makes it harder, though it might
+be mitigated by sharing the checker state traits.
+
+- Because "ghost variables" are not material to the user, we need to somehow
+make super sure that they don't make it into the diagnostic messages.
+
+So, because this needs further digging into overall C++ support and rises too
+many questions, i'm delaying a better approach to this problem and will fall
+back to the original trivial patch.
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..0438ab6
--- /dev/null
+++ b/include/clang/APINotes/Types.h
@@ -0,0 +1,794 @@
+//===--- 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) { }
+};
+
+enum class RetainCountConventionKind {
+  None,
+  CFReturnsRetained,
+  CFReturnsNotRetained,
+  NSReturnsRetained,
+  NSReturnsNotRetained,
+};
+
+
+/// 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;
+
+  /// A biased RetainCountConventionKind, where 0 means "unspecified".
+  ///
+  /// Only relevant for out-parameters.
+  unsigned RawRetainCountConvention : 3;
+
+public:
+  ParamInfo() : VariableInfo(), NoEscapeSpecified(false), NoEscape(false),
+      RawRetainCountConvention() { }
+
+  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;
+    }
+  }
+
+  Optional<RetainCountConventionKind> getRetainCountConvention() const {
+    if (!RawRetainCountConvention)
+      return None;
+    return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
+  }
+  void setRetainCountConvention(Optional<RetainCountConventionKind> convention){
+    if (convention)
+      RawRetainCountConvention = static_cast<unsigned>(convention.getValue())+1;
+    else
+      RawRetainCountConvention = 0;
+    assert(getRetainCountConvention() == convention && "bitfield too small");
+  }
+
+  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;
+    }
+    if (!lhs.RawRetainCountConvention)
+      lhs.RawRetainCountConvention = rhs.RawRetainCountConvention;
+    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 &&
+           lhs.RawRetainCountConvention == rhs.RawRetainCountConvention;
+  }
+
+  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;
+
+  /// A biased RetainCountConventionKind, where 0 means "unspecified".
+  unsigned RawRetainCountConvention : 3;
+
+  /// 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),
+      RawRetainCountConvention() { }
+
+  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);
+  }
+
+  Optional<RetainCountConventionKind> getRetainCountConvention() const {
+    if (!RawRetainCountConvention)
+      return None;
+    return static_cast<RetainCountConventionKind>(RawRetainCountConvention - 1);
+  }
+  void setRetainCountConvention(Optional<RetainCountConventionKind> convention){
+    if (convention)
+      RawRetainCountConvention = static_cast<unsigned>(convention.getValue())+1;
+    else
+      RawRetainCountConvention = 0;
+    assert(getRetainCountConvention() == convention && "bitfield too small");
+  }
+
+  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 &&
+           lhs.RawRetainCountConvention == rhs.RawRetainCountConvention;
+  }
+
+  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/DataCollection.h b/include/clang/AST/DataCollection.h
new file mode 100644
index 0000000..229ac2b
--- /dev/null
+++ b/include/clang/AST/DataCollection.h
@@ -0,0 +1,65 @@
+//===--- DatatCollection.h --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file declares helper methods for collecting data from AST nodes.
+///
+/// To collect data from Stmt nodes, subclass ConstStmtVisitor and include
+/// StmtDataCollectors.inc after defining the macros that you need. This
+/// provides data collection implementations for most Stmt kinds. Note
+/// that that code requires some conditions to be met:
+///
+///   - There must be a method addData(const T &Data) that accepts strings,
+///     integral types as well as QualType. All data is forwarded using
+///     to this method.
+///   - The ASTContext of the Stmt must be accessible by the name Context.
+///
+/// It is also possible to override individual visit methods. Have a look at
+/// the DataCollector in lib/Analysis/CloneDetection.cpp for a usage example.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DATACOLLECTION_H
+#define LLVM_CLANG_AST_DATACOLLECTION_H
+
+#include "clang/AST/ASTContext.h"
+
+namespace clang {
+namespace data_collection {
+
+/// Returns a string that represents all macro expansions that expanded into the
+/// given SourceLocation.
+///
+/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
+/// A and B are expanded from the same macros in the same order.
+std::string getMacroStack(SourceLocation Loc, ASTContext &Context);
+
+/// Utility functions for implementing addData() for a consumer that has a
+/// method update(StringRef)
+template <class T>
+void addDataToConsumer(T &DataConsumer, llvm::StringRef Str) {
+  DataConsumer.update(Str);
+}
+
+template <class T> void addDataToConsumer(T &DataConsumer, const QualType &QT) {
+  addDataToConsumer(DataConsumer, QT.getAsString());
+}
+
+template <class T, class Type>
+typename std::enable_if<
+    std::is_integral<Type>::value || std::is_enum<Type>::value ||
+    std::is_convertible<Type, size_t>::value // for llvm::hash_code
+    >::type
+addDataToConsumer(T &DataConsumer, Type Data) {
+  DataConsumer.update(StringRef(reinterpret_cast<char *>(&Data), sizeof(Data)));
+}
+
+} // end namespace data_collection
+} // end namespace clang
+
+#endif // LLVM_CLANG_AST_DATACOLLECTION_H
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..9792678 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -2345,6 +2345,12 @@
   SourceLocation getLocStart() const LLVM_READONLY;
   SourceLocation getLocEnd() const LLVM_READONLY;
 
+  bool isCallToStdMove() const {
+    const FunctionDecl* FD = getDirectCallee();
+    return getNumArgs() == 1 && FD && FD->isInStdNamespace() &&
+           FD->getIdentifier() && FD->getIdentifier()->isStr("move");
+  }
+
   static bool classof(const Stmt *T) {
     return T->getStmtClass() >= firstCallExprConstant &&
            T->getStmtClass() <= lastCallExprConstant;
@@ -2771,6 +2777,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..798de28 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,9 @@
       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), SuppressImplicitBase(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 +83,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 +206,30 @@
   /// 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 : 1;
+
+  /// \brief When true, don't print the implicit 'self' or 'this' expressions.
+  bool SuppressImplicitBase : 1;
+
+  /// \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/Analysis/Analyses/Consumed.h b/include/clang/Analysis/Analyses/Consumed.h
index c0fc027..5ba42b4 100644
--- a/include/clang/Analysis/Analyses/Consumed.h
+++ b/include/clang/Analysis/Analyses/Consumed.h
@@ -19,7 +19,7 @@
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/SourceLocation.h"
 
 namespace clang {
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 38010e1..6cb161a 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -14,7 +14,7 @@
 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
 #define LLVM_CLANG_ANALYSIS_ANALYSES_DOMINATORS_H
 
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "llvm/ADT/GraphTraits.h"
 #include "llvm/Support/GenericDomTree.h"
diff --git a/include/clang/Analysis/Analyses/LiveVariables.h b/include/clang/Analysis/Analyses/LiveVariables.h
index 8db4b0a..6a12223 100644
--- a/include/clang/Analysis/Analyses/LiveVariables.h
+++ b/include/clang/Analysis/Analyses/LiveVariables.h
@@ -15,7 +15,7 @@
 #define LLVM_CLANG_ANALYSIS_ANALYSES_LIVEVARIABLES_H
 
 #include "clang/AST/Decl.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "llvm/ADT/ImmutableSet.h"
 
 namespace clang {
diff --git a/include/clang/Analysis/Analyses/PostOrderCFGView.h b/include/clang/Analysis/Analyses/PostOrderCFGView.h
index a1c6504..c0a9352 100644
--- a/include/clang/Analysis/Analyses/PostOrderCFGView.h
+++ b/include/clang/Analysis/Analyses/PostOrderCFGView.h
@@ -21,7 +21,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/BitVector.h"
 
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 
 namespace clang {
diff --git a/include/clang/Analysis/Analyses/ThreadSafety.h b/include/clang/Analysis/Analyses/ThreadSafety.h
index 22694a7..7e403b1 100644
--- a/include/clang/Analysis/Analyses/ThreadSafety.h
+++ b/include/clang/Analysis/Analyses/ThreadSafety.h
@@ -19,7 +19,7 @@
 #ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
 #define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETY_H
 
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/StringRef.h"
 
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
index 8c1d1da..414645b 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyCommon.h
@@ -25,7 +25,7 @@
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
 #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/OperatorKinds.h"
 #include <memory>
 #include <ostream>
diff --git a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
index be8a710..1735162 100644
--- a/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
+++ b/include/clang/Analysis/Analyses/ThreadSafetyTIL.h
@@ -909,15 +909,10 @@
 public:
   static bool classof(const SExpr *E) { return E->opcode() == COP_Project; }
 
-  Project(SExpr *R, StringRef SName)
-      : SExpr(COP_Project), Rec(R), SlotName(SName), Cvdecl(nullptr)
-  { }
   Project(SExpr *R, const clang::ValueDecl *Cvd)
-      : SExpr(COP_Project), Rec(R), SlotName(Cvd->getName()), Cvdecl(Cvd)
-  { }
-  Project(const Project &P, SExpr *R)
-      : SExpr(P), Rec(R), SlotName(P.SlotName), Cvdecl(P.Cvdecl)
-  { }
+      : SExpr(COP_Project), Rec(R), Cvdecl(Cvd) {
+    assert(Cvd && "ValueDecl must not be null");
+  }
 
   SExpr *record() { return Rec; }
   const SExpr *record() const { return Rec; }
@@ -931,10 +926,14 @@
   }
 
   StringRef slotName() const {
-    if (Cvdecl)
+    if (Cvdecl->getDeclName().isIdentifier())
       return Cvdecl->getName();
-    else
-      return SlotName;
+    if (!SlotName) {
+      SlotName = "";
+      llvm::raw_string_ostream OS(*SlotName);
+      Cvdecl->printName(OS);
+    }
+    return *SlotName;
   }
 
   template <class V>
@@ -953,7 +952,7 @@
 
 private:
   SExpr* Rec;
-  StringRef SlotName;
+  mutable llvm::Optional<std::string> SlotName;
   const clang::ValueDecl *Cvdecl;
 };
 
diff --git a/include/clang/Analysis/AnalysisContext.h b/include/clang/Analysis/AnalysisContext.h
deleted file mode 100644
index ec7549d..0000000
--- a/include/clang/Analysis/AnalysisContext.h
+++ /dev/null
@@ -1,486 +0,0 @@
-//=== AnalysisContext.h - Analysis context for Path Sens analysis --*- 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 AnalysisDeclContext, a class that manages the analysis
-// context data for path sensitive analysis.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
-#define LLVM_CLANG_ANALYSIS_ANALYSISCONTEXT_H
-
-#include "clang/AST/Decl.h"
-#include "clang/Analysis/CFG.h"
-#include "clang/Analysis/CodeInjector.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/Support/Allocator.h"
-#include <memory>
-
-namespace clang {
-
-class Stmt;
-class CFGReverseBlockReachabilityAnalysis;
-class CFGStmtMap;
-class LiveVariables;
-class ManagedAnalysis;
-class ParentMap;
-class PseudoConstantAnalysis;
-class LocationContextManager;
-class StackFrameContext;
-class BlockInvocationContext;
-class AnalysisDeclContextManager;
-class LocationContext;
-
-namespace idx { class TranslationUnit; }
-
-/// The base class of a hierarchy of objects representing analyses tied
-/// to AnalysisDeclContext.
-class ManagedAnalysis {
-protected:
-  ManagedAnalysis() {}
-public:
-  virtual ~ManagedAnalysis();
-
-  // Subclasses need to implement:
-  //
-  //  static const void *getTag();
-  //
-  // Which returns a fixed pointer address to distinguish classes of
-  // analysis objects.  They also need to implement:
-  //
-  //  static [Derived*] create(AnalysisDeclContext &Ctx);
-  //
-  // which creates the analysis object given an AnalysisDeclContext.
-};
-
-
-/// AnalysisDeclContext contains the context data for the function or method
-/// under analysis.
-class AnalysisDeclContext {
-  /// Backpoint to the AnalysisManager object that created this
-  /// AnalysisDeclContext. This may be null.
-  AnalysisDeclContextManager *Manager;
-
-  const Decl * const D;
-
-  std::unique_ptr<CFG> cfg, completeCFG;
-  std::unique_ptr<CFGStmtMap> cfgStmtMap;
-
-  CFG::BuildOptions cfgBuildOptions;
-  CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
-
-  bool builtCFG, builtCompleteCFG;
-  std::unique_ptr<ParentMap> PM;
-  std::unique_ptr<PseudoConstantAnalysis> PCA;
-  std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
-
-  llvm::BumpPtrAllocator A;
-
-  llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
-
-  void *ManagedAnalyses;
-
-public:
-  AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
-                  const Decl *D);
-
-  AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
-                  const Decl *D,
-                  const CFG::BuildOptions &BuildOptions);
-
-  ~AnalysisDeclContext();
-
-  ASTContext &getASTContext() const { return D->getASTContext(); }
-  const Decl *getDecl() const { return D; }
-
-  /// Return the AnalysisDeclContextManager (if any) that created
-  /// this AnalysisDeclContext.
-  AnalysisDeclContextManager *getManager() const {
-    return Manager;
-  }
-  
-  /// Return the build options used to construct the CFG.
-  CFG::BuildOptions &getCFGBuildOptions() {
-    return cfgBuildOptions;
-  }
-
-  const CFG::BuildOptions &getCFGBuildOptions() const {
-    return cfgBuildOptions;
-  }
-
-  /// getAddEHEdges - Return true iff we are adding exceptional edges from
-  /// callExprs.  If this is false, then try/catch statements and blocks
-  /// reachable from them can appear to be dead in the CFG, analysis passes must
-  /// cope with that.
-  bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
-  bool getUseUnoptimizedCFG() const {
-      return !cfgBuildOptions.PruneTriviallyFalseEdges;
-  }
-  bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
-  bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
-
-  void registerForcedBlockExpression(const Stmt *stmt);
-  const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
-
-  /// \brief Get the body of the Declaration.
-  Stmt *getBody() const;
-
-  /// \brief Get the body of the Declaration.
-  /// \param[out] IsAutosynthesized Specifies if the body is auto-generated
-  ///             by the BodyFarm.
-  Stmt *getBody(bool &IsAutosynthesized) const;
-
-  /// \brief Checks if the body of the Decl is generated by the BodyFarm.
-  ///
-  /// Note, the lookup is not free. We are going to call getBody behind
-  /// the scenes.
-  /// \sa getBody
-  bool isBodyAutosynthesized() const;
-
-  /// \brief Checks if the body of the Decl is generated by the BodyFarm from a
-  /// model file.
-  ///
-  /// Note, the lookup is not free. We are going to call getBody behind
-  /// the scenes.
-  /// \sa getBody
-  bool isBodyAutosynthesizedFromModelFile() const;
-
-  CFG *getCFG();
-
-  CFGStmtMap *getCFGStmtMap();
-
-  CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();
-
-  /// Return a version of the CFG without any edges pruned.
-  CFG *getUnoptimizedCFG();
-
-  void dumpCFG(bool ShowColors);
-
-  /// \brief Returns true if we have built a CFG for this analysis context.
-  /// Note that this doesn't correspond to whether or not a valid CFG exists, it
-  /// corresponds to whether we *attempted* to build one.
-  bool isCFGBuilt() const { return builtCFG; }
-
-  ParentMap &getParentMap();
-  PseudoConstantAnalysis *getPseudoConstantAnalysis();
-
-  typedef const VarDecl * const * referenced_decls_iterator;
-
-  llvm::iterator_range<referenced_decls_iterator>
-  getReferencedBlockVars(const BlockDecl *BD);
-
-  /// Return the ImplicitParamDecl* associated with 'self' if this
-  /// AnalysisDeclContext wraps an ObjCMethodDecl.  Returns NULL otherwise.
-  const ImplicitParamDecl *getSelfDecl() const;
-
-  const StackFrameContext *getStackFrame(LocationContext const *Parent,
-                                         const Stmt *S,
-                                         const CFGBlock *Blk,
-                                         unsigned Idx);
-  
-  const BlockInvocationContext *
-  getBlockInvocationContext(const LocationContext *parent,
-                            const BlockDecl *BD,
-                            const void *ContextData);
-
-  /// Return the specified analysis object, lazily running the analysis if
-  /// necessary.  Return NULL if the analysis could not run.
-  template <typename T>
-  T *getAnalysis() {
-    const void *tag = T::getTag();
-    ManagedAnalysis *&data = getAnalysisImpl(tag);
-    if (!data) {
-      data = T::create(*this);
-    }
-    return static_cast<T*>(data);
-  }
-
-  /// Returns true if the root namespace of the given declaration is the 'std'
-  /// C++ namespace.
-  static bool isInStdNamespace(const Decl *D);
-private:
-  ManagedAnalysis *&getAnalysisImpl(const void* tag);
-
-  LocationContextManager &getLocationContextManager();
-};
-
-class LocationContext : public llvm::FoldingSetNode {
-public:
-  enum ContextKind { StackFrame, Scope, Block };
-
-private:
-  ContextKind Kind;
-
-  // AnalysisDeclContext can't be const since some methods may modify its
-  // member.
-  AnalysisDeclContext *Ctx;
-
-  const LocationContext *Parent;
-
-protected:
-  LocationContext(ContextKind k, AnalysisDeclContext *ctx,
-                  const LocationContext *parent)
-    : Kind(k), Ctx(ctx), Parent(parent) {}
-
-public:
-  virtual ~LocationContext();
-
-  ContextKind getKind() const { return Kind; }
-
-  AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
-
-  const LocationContext *getParent() const { return Parent; }
-
-  bool isParentOf(const LocationContext *LC) const;
-
-  const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); }
-
-  CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); }
-
-  template <typename T>
-  T *getAnalysis() const {
-    return getAnalysisDeclContext()->getAnalysis<T>();
-  }
-
-  ParentMap &getParentMap() const {
-    return getAnalysisDeclContext()->getParentMap();
-  }
-
-  const ImplicitParamDecl *getSelfDecl() const {
-    return Ctx->getSelfDecl();
-  }
-
-  const StackFrameContext *getCurrentStackFrame() const;
-
-  /// Return true if the current LocationContext has no caller context.
-  virtual bool inTopFrame() const;
-
-  virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
-
-  void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
-  void dumpStack() const;
-
-public:
-  static void ProfileCommon(llvm::FoldingSetNodeID &ID,
-                            ContextKind ck,
-                            AnalysisDeclContext *ctx,
-                            const LocationContext *parent,
-                            const void *data);
-};
-
-class StackFrameContext : public LocationContext {
-  // The callsite where this stack frame is established.
-  const Stmt *CallSite;
-
-  // The parent block of the callsite.
-  const CFGBlock *Block;
-
-  // The index of the callsite in the CFGBlock.
-  unsigned Index;
-
-  friend class LocationContextManager;
-  StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
-                    const Stmt *s, const CFGBlock *blk,
-                    unsigned idx)
-    : LocationContext(StackFrame, ctx, parent), CallSite(s),
-      Block(blk), Index(idx) {}
-
-public:
-  ~StackFrameContext() override {}
-
-  const Stmt *getCallSite() const { return CallSite; }
-
-  const CFGBlock *getCallSiteBlock() const { return Block; }
-
-  /// Return true if the current LocationContext has no caller context.
-  bool inTopFrame() const override { return getParent() == nullptr;  }
-
-  unsigned getIndex() const { return Index; }
-
-  void Profile(llvm::FoldingSetNodeID &ID) override;
-
-  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
-                      const LocationContext *parent, const Stmt *s,
-                      const CFGBlock *blk, unsigned idx) {
-    ProfileCommon(ID, StackFrame, ctx, parent, s);
-    ID.AddPointer(blk);
-    ID.AddInteger(idx);
-  }
-
-  static bool classof(const LocationContext *Ctx) {
-    return Ctx->getKind() == StackFrame;
-  }
-};
-
-class ScopeContext : public LocationContext {
-  const Stmt *Enter;
-
-  friend class LocationContextManager;
-  ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
-               const Stmt *s)
-    : LocationContext(Scope, ctx, parent), Enter(s) {}
-
-public:
-  ~ScopeContext() override {}
-
-  void Profile(llvm::FoldingSetNodeID &ID) override;
-
-  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
-                      const LocationContext *parent, const Stmt *s) {
-    ProfileCommon(ID, Scope, ctx, parent, s);
-  }
-
-  static bool classof(const LocationContext *Ctx) {
-    return Ctx->getKind() == Scope;
-  }
-};
-
-class BlockInvocationContext : public LocationContext {
-  const BlockDecl *BD;
-  
-  // FIXME: Come up with a more type-safe way to model context-sensitivity.
-  const void *ContextData;
-
-  friend class LocationContextManager;
-
-  BlockInvocationContext(AnalysisDeclContext *ctx,
-                         const LocationContext *parent,
-                         const BlockDecl *bd, const void *contextData)
-    : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
-
-public:
-  ~BlockInvocationContext() override {}
-
-  const BlockDecl *getBlockDecl() const { return BD; }
-  
-  const void *getContextData() const { return ContextData; }
-
-  void Profile(llvm::FoldingSetNodeID &ID) override;
-
-  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
-                      const LocationContext *parent, const BlockDecl *bd,
-                      const void *contextData) {
-    ProfileCommon(ID, Block, ctx, parent, bd);
-    ID.AddPointer(contextData);
-  }
-
-  static bool classof(const LocationContext *Ctx) {
-    return Ctx->getKind() == Block;
-  }
-};
-
-class LocationContextManager {
-  llvm::FoldingSet<LocationContext> Contexts;
-public:
-  ~LocationContextManager();
-
-  const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx,
-                                         const LocationContext *parent,
-                                         const Stmt *s,
-                                         const CFGBlock *blk, unsigned idx);
-
-  const ScopeContext *getScope(AnalysisDeclContext *ctx,
-                               const LocationContext *parent,
-                               const Stmt *s);
-  
-  const BlockInvocationContext *
-  getBlockInvocationContext(AnalysisDeclContext *ctx,
-                            const LocationContext *parent,
-                            const BlockDecl *BD,
-                            const void *ContextData);
-
-  /// Discard all previously created LocationContext objects.
-  void clear();
-private:
-  template <typename LOC, typename DATA>
-  const LOC *getLocationContext(AnalysisDeclContext *ctx,
-                                const LocationContext *parent,
-                                const DATA *d);
-};
-
-class AnalysisDeclContextManager {
-  typedef llvm::DenseMap<const Decl *, std::unique_ptr<AnalysisDeclContext>>
-      ContextMap;
-
-  ContextMap Contexts;
-  LocationContextManager LocContexts;
-  CFG::BuildOptions cfgBuildOptions;
-
-  /// Pointer to an interface that can provide function bodies for
-  /// declarations from external source.
-  std::unique_ptr<CodeInjector> Injector;
-  
-  /// Flag to indicate whether or not bodies should be synthesized
-  /// for well-known functions.
-  bool SynthesizeBodies;
-
-public:
-  AnalysisDeclContextManager(bool useUnoptimizedCFG = false,
-                             bool addImplicitDtors = false,
-                             bool addInitializers = false,
-                             bool addTemporaryDtors = false,
-                             bool addLifetime = false,
-                             bool synthesizeBodies = false,
-                             bool addStaticInitBranches = false,
-                             bool addCXXNewAllocator = true,
-                             CodeInjector* injector = nullptr);
-
-  ~AnalysisDeclContextManager();
-
-  AnalysisDeclContext *getContext(const Decl *D);
-
-  bool getUseUnoptimizedCFG() const {
-    return !cfgBuildOptions.PruneTriviallyFalseEdges;
-  }
-
-  CFG::BuildOptions &getCFGBuildOptions() {
-    return cfgBuildOptions;
-  }
-  
-  /// Return true if faux bodies should be synthesized for well-known
-  /// functions.
-  bool synthesizeBodies() const { return SynthesizeBodies; }
-
-  const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx,
-                                         LocationContext const *Parent,
-                                         const Stmt *S,
-                                         const CFGBlock *Blk,
-                                         unsigned Idx) {
-    return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx);
-  }
-
-  // Get the top level stack frame.
-  const StackFrameContext *getStackFrame(const Decl *D) {
-    return LocContexts.getStackFrame(getContext(D), nullptr, nullptr, nullptr,
-                                     0);
-  }
-
-  // Get a stack frame with parent.
-  StackFrameContext const *getStackFrame(const Decl *D,
-                                         LocationContext const *Parent,
-                                         const Stmt *S,
-                                         const CFGBlock *Blk,
-                                         unsigned Idx) {
-    return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
-  }
-
-  /// Discard all previously created AnalysisDeclContexts.
-  void clear();
-
-private:
-  friend class AnalysisDeclContext;
-
-  LocationContextManager &getLocationContextManager() {
-    return LocContexts;
-  }
-};
-
-} // end clang namespace
-#endif
diff --git a/include/clang/Analysis/AnalysisDeclContext.h b/include/clang/Analysis/AnalysisDeclContext.h
new file mode 100644
index 0000000..03ff4a9
--- /dev/null
+++ b/include/clang/Analysis/AnalysisDeclContext.h
@@ -0,0 +1,492 @@
+//=== AnalysisDeclContext.h - Analysis context for Path Sens analysis --*- 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 AnalysisDeclContext, a class that manages the analysis
+// context data for path sensitive analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
+#define LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H
+
+#include "clang/AST/Decl.h"
+#include "clang/Analysis/BodyFarm.h"
+#include "clang/Analysis/CFG.h"
+#include "clang/Analysis/CodeInjector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Allocator.h"
+#include <memory>
+
+namespace clang {
+
+class Stmt;
+class CFGReverseBlockReachabilityAnalysis;
+class CFGStmtMap;
+class LiveVariables;
+class ManagedAnalysis;
+class ParentMap;
+class PseudoConstantAnalysis;
+class LocationContextManager;
+class StackFrameContext;
+class BlockInvocationContext;
+class AnalysisDeclContextManager;
+class LocationContext;
+
+namespace idx { class TranslationUnit; }
+
+/// The base class of a hierarchy of objects representing analyses tied
+/// to AnalysisDeclContext.
+class ManagedAnalysis {
+protected:
+  ManagedAnalysis() {}
+public:
+  virtual ~ManagedAnalysis();
+
+  // Subclasses need to implement:
+  //
+  //  static const void *getTag();
+  //
+  // Which returns a fixed pointer address to distinguish classes of
+  // analysis objects.  They also need to implement:
+  //
+  //  static [Derived*] create(AnalysisDeclContext &Ctx);
+  //
+  // which creates the analysis object given an AnalysisDeclContext.
+};
+
+
+/// AnalysisDeclContext contains the context data for the function or method
+/// under analysis.
+class AnalysisDeclContext {
+  /// Backpoint to the AnalysisManager object that created this
+  /// AnalysisDeclContext. This may be null.
+  AnalysisDeclContextManager *Manager;
+
+  const Decl * const D;
+
+  std::unique_ptr<CFG> cfg, completeCFG;
+  std::unique_ptr<CFGStmtMap> cfgStmtMap;
+
+  CFG::BuildOptions cfgBuildOptions;
+  CFG::BuildOptions::ForcedBlkExprs *forcedBlkExprs;
+
+  bool builtCFG, builtCompleteCFG;
+  std::unique_ptr<ParentMap> PM;
+  std::unique_ptr<PseudoConstantAnalysis> PCA;
+  std::unique_ptr<CFGReverseBlockReachabilityAnalysis> CFA;
+
+  llvm::BumpPtrAllocator A;
+
+  llvm::DenseMap<const BlockDecl*,void*> *ReferencedBlockVars;
+
+  void *ManagedAnalyses;
+
+public:
+  AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
+                  const Decl *D);
+
+  AnalysisDeclContext(AnalysisDeclContextManager *Mgr,
+                  const Decl *D,
+                  const CFG::BuildOptions &BuildOptions);
+
+  ~AnalysisDeclContext();
+
+  ASTContext &getASTContext() const { return D->getASTContext(); }
+  const Decl *getDecl() const { return D; }
+
+  /// Return the AnalysisDeclContextManager (if any) that created
+  /// this AnalysisDeclContext.
+  AnalysisDeclContextManager *getManager() const {
+    return Manager;
+  }
+  
+  /// Return the build options used to construct the CFG.
+  CFG::BuildOptions &getCFGBuildOptions() {
+    return cfgBuildOptions;
+  }
+
+  const CFG::BuildOptions &getCFGBuildOptions() const {
+    return cfgBuildOptions;
+  }
+
+  /// getAddEHEdges - Return true iff we are adding exceptional edges from
+  /// callExprs.  If this is false, then try/catch statements and blocks
+  /// reachable from them can appear to be dead in the CFG, analysis passes must
+  /// cope with that.
+  bool getAddEHEdges() const { return cfgBuildOptions.AddEHEdges; }
+  bool getUseUnoptimizedCFG() const {
+      return !cfgBuildOptions.PruneTriviallyFalseEdges;
+  }
+  bool getAddImplicitDtors() const { return cfgBuildOptions.AddImplicitDtors; }
+  bool getAddInitializers() const { return cfgBuildOptions.AddInitializers; }
+
+  void registerForcedBlockExpression(const Stmt *stmt);
+  const CFGBlock *getBlockForRegisteredExpression(const Stmt *stmt);
+
+  /// \brief Get the body of the Declaration.
+  Stmt *getBody() const;
+
+  /// \brief Get the body of the Declaration.
+  /// \param[out] IsAutosynthesized Specifies if the body is auto-generated
+  ///             by the BodyFarm.
+  Stmt *getBody(bool &IsAutosynthesized) const;
+
+  /// \brief Checks if the body of the Decl is generated by the BodyFarm.
+  ///
+  /// Note, the lookup is not free. We are going to call getBody behind
+  /// the scenes.
+  /// \sa getBody
+  bool isBodyAutosynthesized() const;
+
+  /// \brief Checks if the body of the Decl is generated by the BodyFarm from a
+  /// model file.
+  ///
+  /// Note, the lookup is not free. We are going to call getBody behind
+  /// the scenes.
+  /// \sa getBody
+  bool isBodyAutosynthesizedFromModelFile() const;
+
+  CFG *getCFG();
+
+  CFGStmtMap *getCFGStmtMap();
+
+  CFGReverseBlockReachabilityAnalysis *getCFGReachablityAnalysis();
+
+  /// Return a version of the CFG without any edges pruned.
+  CFG *getUnoptimizedCFG();
+
+  void dumpCFG(bool ShowColors);
+
+  /// \brief Returns true if we have built a CFG for this analysis context.
+  /// Note that this doesn't correspond to whether or not a valid CFG exists, it
+  /// corresponds to whether we *attempted* to build one.
+  bool isCFGBuilt() const { return builtCFG; }
+
+  ParentMap &getParentMap();
+  PseudoConstantAnalysis *getPseudoConstantAnalysis();
+
+  typedef const VarDecl * const * referenced_decls_iterator;
+
+  llvm::iterator_range<referenced_decls_iterator>
+  getReferencedBlockVars(const BlockDecl *BD);
+
+  /// Return the ImplicitParamDecl* associated with 'self' if this
+  /// AnalysisDeclContext wraps an ObjCMethodDecl.  Returns NULL otherwise.
+  const ImplicitParamDecl *getSelfDecl() const;
+
+  const StackFrameContext *getStackFrame(LocationContext const *Parent,
+                                         const Stmt *S,
+                                         const CFGBlock *Blk,
+                                         unsigned Idx);
+  
+  const BlockInvocationContext *
+  getBlockInvocationContext(const LocationContext *parent,
+                            const BlockDecl *BD,
+                            const void *ContextData);
+
+  /// Return the specified analysis object, lazily running the analysis if
+  /// necessary.  Return NULL if the analysis could not run.
+  template <typename T>
+  T *getAnalysis() {
+    const void *tag = T::getTag();
+    ManagedAnalysis *&data = getAnalysisImpl(tag);
+    if (!data) {
+      data = T::create(*this);
+    }
+    return static_cast<T*>(data);
+  }
+
+  /// Returns true if the root namespace of the given declaration is the 'std'
+  /// C++ namespace.
+  static bool isInStdNamespace(const Decl *D);
+private:
+  ManagedAnalysis *&getAnalysisImpl(const void* tag);
+
+  LocationContextManager &getLocationContextManager();
+};
+
+class LocationContext : public llvm::FoldingSetNode {
+public:
+  enum ContextKind { StackFrame, Scope, Block };
+
+private:
+  ContextKind Kind;
+
+  // AnalysisDeclContext can't be const since some methods may modify its
+  // member.
+  AnalysisDeclContext *Ctx;
+
+  const LocationContext *Parent;
+
+protected:
+  LocationContext(ContextKind k, AnalysisDeclContext *ctx,
+                  const LocationContext *parent)
+    : Kind(k), Ctx(ctx), Parent(parent) {}
+
+public:
+  virtual ~LocationContext();
+
+  ContextKind getKind() const { return Kind; }
+
+  AnalysisDeclContext *getAnalysisDeclContext() const { return Ctx; }
+
+  const LocationContext *getParent() const { return Parent; }
+
+  bool isParentOf(const LocationContext *LC) const;
+
+  const Decl *getDecl() const { return getAnalysisDeclContext()->getDecl(); }
+
+  CFG *getCFG() const { return getAnalysisDeclContext()->getCFG(); }
+
+  template <typename T>
+  T *getAnalysis() const {
+    return getAnalysisDeclContext()->getAnalysis<T>();
+  }
+
+  ParentMap &getParentMap() const {
+    return getAnalysisDeclContext()->getParentMap();
+  }
+
+  const ImplicitParamDecl *getSelfDecl() const {
+    return Ctx->getSelfDecl();
+  }
+
+  const StackFrameContext *getCurrentStackFrame() const;
+
+  /// Return true if the current LocationContext has no caller context.
+  virtual bool inTopFrame() const;
+
+  virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
+
+  void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
+  void dumpStack() const;
+
+public:
+  static void ProfileCommon(llvm::FoldingSetNodeID &ID,
+                            ContextKind ck,
+                            AnalysisDeclContext *ctx,
+                            const LocationContext *parent,
+                            const void *data);
+};
+
+class StackFrameContext : public LocationContext {
+  // The callsite where this stack frame is established.
+  const Stmt *CallSite;
+
+  // The parent block of the callsite.
+  const CFGBlock *Block;
+
+  // The index of the callsite in the CFGBlock.
+  unsigned Index;
+
+  friend class LocationContextManager;
+  StackFrameContext(AnalysisDeclContext *ctx, const LocationContext *parent,
+                    const Stmt *s, const CFGBlock *blk,
+                    unsigned idx)
+    : LocationContext(StackFrame, ctx, parent), CallSite(s),
+      Block(blk), Index(idx) {}
+
+public:
+  ~StackFrameContext() override {}
+
+  const Stmt *getCallSite() const { return CallSite; }
+
+  const CFGBlock *getCallSiteBlock() const { return Block; }
+
+  /// Return true if the current LocationContext has no caller context.
+  bool inTopFrame() const override { return getParent() == nullptr;  }
+
+  unsigned getIndex() const { return Index; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) override;
+
+  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
+                      const LocationContext *parent, const Stmt *s,
+                      const CFGBlock *blk, unsigned idx) {
+    ProfileCommon(ID, StackFrame, ctx, parent, s);
+    ID.AddPointer(blk);
+    ID.AddInteger(idx);
+  }
+
+  static bool classof(const LocationContext *Ctx) {
+    return Ctx->getKind() == StackFrame;
+  }
+};
+
+class ScopeContext : public LocationContext {
+  const Stmt *Enter;
+
+  friend class LocationContextManager;
+  ScopeContext(AnalysisDeclContext *ctx, const LocationContext *parent,
+               const Stmt *s)
+    : LocationContext(Scope, ctx, parent), Enter(s) {}
+
+public:
+  ~ScopeContext() override {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) override;
+
+  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
+                      const LocationContext *parent, const Stmt *s) {
+    ProfileCommon(ID, Scope, ctx, parent, s);
+  }
+
+  static bool classof(const LocationContext *Ctx) {
+    return Ctx->getKind() == Scope;
+  }
+};
+
+class BlockInvocationContext : public LocationContext {
+  const BlockDecl *BD;
+  
+  // FIXME: Come up with a more type-safe way to model context-sensitivity.
+  const void *ContextData;
+
+  friend class LocationContextManager;
+
+  BlockInvocationContext(AnalysisDeclContext *ctx,
+                         const LocationContext *parent,
+                         const BlockDecl *bd, const void *contextData)
+    : LocationContext(Block, ctx, parent), BD(bd), ContextData(contextData) {}
+
+public:
+  ~BlockInvocationContext() override {}
+
+  const BlockDecl *getBlockDecl() const { return BD; }
+  
+  const void *getContextData() const { return ContextData; }
+
+  void Profile(llvm::FoldingSetNodeID &ID) override;
+
+  static void Profile(llvm::FoldingSetNodeID &ID, AnalysisDeclContext *ctx,
+                      const LocationContext *parent, const BlockDecl *bd,
+                      const void *contextData) {
+    ProfileCommon(ID, Block, ctx, parent, bd);
+    ID.AddPointer(contextData);
+  }
+
+  static bool classof(const LocationContext *Ctx) {
+    return Ctx->getKind() == Block;
+  }
+};
+
+class LocationContextManager {
+  llvm::FoldingSet<LocationContext> Contexts;
+public:
+  ~LocationContextManager();
+
+  const StackFrameContext *getStackFrame(AnalysisDeclContext *ctx,
+                                         const LocationContext *parent,
+                                         const Stmt *s,
+                                         const CFGBlock *blk, unsigned idx);
+
+  const ScopeContext *getScope(AnalysisDeclContext *ctx,
+                               const LocationContext *parent,
+                               const Stmt *s);
+  
+  const BlockInvocationContext *
+  getBlockInvocationContext(AnalysisDeclContext *ctx,
+                            const LocationContext *parent,
+                            const BlockDecl *BD,
+                            const void *ContextData);
+
+  /// Discard all previously created LocationContext objects.
+  void clear();
+private:
+  template <typename LOC, typename DATA>
+  const LOC *getLocationContext(AnalysisDeclContext *ctx,
+                                const LocationContext *parent,
+                                const DATA *d);
+};
+
+class AnalysisDeclContextManager {
+  typedef llvm::DenseMap<const Decl *, std::unique_ptr<AnalysisDeclContext>>
+      ContextMap;
+
+  ContextMap Contexts;
+  LocationContextManager LocContexts;
+  CFG::BuildOptions cfgBuildOptions;
+
+  /// Pointer to an interface that can provide function bodies for
+  /// declarations from external source.
+  std::unique_ptr<CodeInjector> Injector;
+
+  /// A factory for creating and caching implementations for common
+  /// methods during the analysis.
+  BodyFarm FunctionBodyFarm;
+
+  /// Flag to indicate whether or not bodies should be synthesized
+  /// for well-known functions.
+  bool SynthesizeBodies;
+
+public:
+  AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG = false,
+                             bool addImplicitDtors = false,
+                             bool addInitializers = false,
+                             bool addTemporaryDtors = false,
+                             bool addLifetime = false, bool addLoopExit = false,
+                             bool synthesizeBodies = false,
+                             bool addStaticInitBranches = false,
+                             bool addCXXNewAllocator = true,
+                             CodeInjector *injector = nullptr);
+
+  AnalysisDeclContext *getContext(const Decl *D);
+
+  bool getUseUnoptimizedCFG() const {
+    return !cfgBuildOptions.PruneTriviallyFalseEdges;
+  }
+
+  CFG::BuildOptions &getCFGBuildOptions() {
+    return cfgBuildOptions;
+  }
+  
+  /// Return true if faux bodies should be synthesized for well-known
+  /// functions.
+  bool synthesizeBodies() const { return SynthesizeBodies; }
+
+  const StackFrameContext *getStackFrame(AnalysisDeclContext *Ctx,
+                                         LocationContext const *Parent,
+                                         const Stmt *S,
+                                         const CFGBlock *Blk,
+                                         unsigned Idx) {
+    return LocContexts.getStackFrame(Ctx, Parent, S, Blk, Idx);
+  }
+
+  // Get the top level stack frame.
+  const StackFrameContext *getStackFrame(const Decl *D) {
+    return LocContexts.getStackFrame(getContext(D), nullptr, nullptr, nullptr,
+                                     0);
+  }
+
+  // Get a stack frame with parent.
+  StackFrameContext const *getStackFrame(const Decl *D,
+                                         LocationContext const *Parent,
+                                         const Stmt *S,
+                                         const CFGBlock *Blk,
+                                         unsigned Idx) {
+    return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx);
+  }
+
+  /// Get a reference to {@code BodyFarm} instance.
+  BodyFarm &getBodyFarm();
+
+  /// Discard all previously created AnalysisDeclContexts.
+  void clear();
+
+private:
+  friend class AnalysisDeclContext;
+
+  LocationContextManager &getLocationContextManager() {
+    return LocContexts;
+  }
+};
+
+} // end clang namespace
+#endif
diff --git a/include/clang/Analysis/BodyFarm.h b/include/clang/Analysis/BodyFarm.h
new file mode 100644
index 0000000..ff0859b
--- /dev/null
+++ b/include/clang/Analysis/BodyFarm.h
@@ -0,0 +1,54 @@
+//== BodyFarm.h - Factory for conjuring up fake bodies -------------*- C++ -*-//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// BodyFarm is a factory for creating faux implementations for functions/methods
+// for analysis purposes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
+#define LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
+
+#include "clang/AST/DeclBase.h"
+#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+
+namespace clang {
+
+class ASTContext;
+class FunctionDecl;
+class ObjCMethodDecl;
+class ObjCPropertyDecl;
+class Stmt;
+class CodeInjector;
+
+class BodyFarm {
+public:
+  BodyFarm(ASTContext &C, CodeInjector *injector) : C(C), Injector(injector) {}
+
+  /// Factory method for creating bodies for ordinary functions.
+  Stmt *getBody(const FunctionDecl *D);
+
+  /// Factory method for creating bodies for Objective-C properties.
+  Stmt *getBody(const ObjCMethodDecl *D);
+
+  /// Remove copy constructor to avoid accidental copying.
+  BodyFarm(const BodyFarm &other) = delete;
+
+private:
+  typedef llvm::DenseMap<const Decl *, Optional<Stmt *>> BodyMap;
+
+  ASTContext &C;
+  BodyMap Bodies;
+  CodeInjector *Injector;
+};
+} // namespace clang
+
+#endif
diff --git a/include/clang/Analysis/CFG.h b/include/clang/Analysis/CFG.h
index 97639bb..8cdd782 100644
--- a/include/clang/Analysis/CFG.h
+++ b/include/clang/Analysis/CFG.h
@@ -59,6 +59,7 @@
     Initializer,
     NewAllocator,
     LifetimeEnds,
+    LoopExit,
     // dtor kind
     AutomaticObjectDtor,
     DeleteDtor,
@@ -168,6 +169,29 @@
   }
 };
 
+/// Represents the point where a loop ends.
+/// This element is is only produced when building the CFG for the static
+/// analyzer and hidden behind the 'cfg-loopexit' analyzer config flag.
+///
+/// Note: a loop exit element can be reached even when the loop body was never
+/// entered.
+class CFGLoopExit : public CFGElement {
+public:
+    explicit CFGLoopExit(const Stmt *stmt)
+            : CFGElement(LoopExit, stmt) {}
+
+    const Stmt *getLoopStmt() const {
+      return static_cast<Stmt *>(Data1.getPointer());
+    }
+
+private:
+    friend class CFGElement;
+    CFGLoopExit() {}
+    static bool isKind(const CFGElement &elem) {
+      return elem.getKind() == LoopExit;
+    }
+};
+
 /// Represents the point where the lifetime of an automatic object ends
 class CFGLifetimeEnds : public CFGElement {
 public:
@@ -728,6 +752,10 @@
     Elements.push_back(CFGLifetimeEnds(VD, S), C);
   }
 
+  void appendLoopExit(const Stmt *LoopStmt, BumpVectorContext &C) {
+    Elements.push_back(CFGLoopExit(LoopStmt), C);
+  }
+
   void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, BumpVectorContext &C) {
     Elements.push_back(CFGDeleteDtor(RD, DE), C);
   }
@@ -794,6 +822,7 @@
     bool AddInitializers;
     bool AddImplicitDtors;
     bool AddLifetime;
+    bool AddLoopExit;
     bool AddTemporaryDtors;
     bool AddStaticInitBranches;
     bool AddCXXNewAllocator;
@@ -818,7 +847,7 @@
         PruneTriviallyFalseEdges(true),
         AddEHEdges(false),
         AddInitializers(false), AddImplicitDtors(false),
-        AddLifetime(false),
+        AddLifetime(false), AddLoopExit(false),
         AddTemporaryDtors(false), AddStaticInitBranches(false),
         AddCXXNewAllocator(false), AddCXXDefaultInitExprInCtors(false) {}
   };
diff --git a/include/clang/Analysis/CloneDetection.h b/include/clang/Analysis/CloneDetection.h
index 6339dee..234e23c 100644
--- a/include/clang/Analysis/CloneDetection.h
+++ b/include/clang/Analysis/CloneDetection.h
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 ///
-/// /file
+/// \file
 /// This file defines classes for searching and anlyzing source code clones.
 ///
 //===----------------------------------------------------------------------===//
@@ -15,11 +15,7 @@
 #ifndef LLVM_CLANG_AST_CLONEDETECTION_H
 #define LLVM_CLANG_AST_CLONEDETECTION_H
 
-#include "clang/AST/DeclTemplate.h"
 #include "clang/AST/StmtVisitor.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Regex.h"
 #include <vector>
 
@@ -31,192 +27,6 @@
 class ASTContext;
 class CompoundStmt;
 
-namespace clone_detection {
-
-/// Returns a string that represents all macro expansions that expanded into the
-/// given SourceLocation.
-///
-/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
-/// A and B are expanded from the same macros in the same order.
-std::string getMacroStack(SourceLocation Loc, ASTContext &Context);
-
-/// Collects the data of a single Stmt.
-///
-/// This class defines what a code clone is: If it collects for two statements
-/// the same data, then those two statements are considered to be clones of each
-/// other.
-///
-/// All collected data is forwarded to the given data consumer of the type T.
-/// The data consumer class needs to provide a member method with the signature:
-///   update(StringRef Str)
-template <typename T>
-class StmtDataCollector : public ConstStmtVisitor<StmtDataCollector<T>> {
-
-  ASTContext &Context;
-  /// The data sink to which all data is forwarded.
-  T &DataConsumer;
-
-public:
-  /// Collects data of the given Stmt.
-  /// \param S The given statement.
-  /// \param Context The ASTContext of S.
-  /// \param DataConsumer The data sink to which all data is forwarded.
-  StmtDataCollector(const Stmt *S, ASTContext &Context, T &DataConsumer)
-      : Context(Context), DataConsumer(DataConsumer) {
-    this->Visit(S);
-  }
-
-  typedef unsigned DataPiece;
-
-  // Below are utility methods for appending different data to the vector.
-
-  void addData(DataPiece Integer) {
-    DataConsumer.update(
-        StringRef(reinterpret_cast<char *>(&Integer), sizeof(Integer)));
-  }
-
-  void addData(llvm::StringRef Str) { DataConsumer.update(Str); }
-
-  void addData(const QualType &QT) { addData(QT.getAsString()); }
-
-// The functions below collect the class specific data of each Stmt subclass.
-
-// Utility macro for defining a visit method for a given class. This method
-// calls back to the ConstStmtVisitor to visit all parent classes.
-#define DEF_ADD_DATA(CLASS, CODE)                                              \
-  void Visit##CLASS(const CLASS *S) {                                          \
-    CODE;                                                                      \
-    ConstStmtVisitor<StmtDataCollector>::Visit##CLASS(S);                      \
-  }
-
-  DEF_ADD_DATA(Stmt, {
-    addData(S->getStmtClass());
-    // This ensures that macro generated code isn't identical to macro-generated
-    // code.
-    addData(getMacroStack(S->getLocStart(), Context));
-    addData(getMacroStack(S->getLocEnd(), Context));
-  })
-  DEF_ADD_DATA(Expr, { addData(S->getType()); })
-
-  //--- Builtin functionality ----------------------------------------------//
-  DEF_ADD_DATA(ArrayTypeTraitExpr, { addData(S->getTrait()); })
-  DEF_ADD_DATA(ExpressionTraitExpr, { addData(S->getTrait()); })
-  DEF_ADD_DATA(PredefinedExpr, { addData(S->getIdentType()); })
-  DEF_ADD_DATA(TypeTraitExpr, {
-    addData(S->getTrait());
-    for (unsigned i = 0; i < S->getNumArgs(); ++i)
-      addData(S->getArg(i)->getType());
-  })
-
-  //--- Calls --------------------------------------------------------------//
-  DEF_ADD_DATA(CallExpr, {
-    // Function pointers don't have a callee and we just skip hashing it.
-    if (const FunctionDecl *D = S->getDirectCallee()) {
-      // If the function is a template specialization, we also need to handle
-      // the template arguments as they are not included in the qualified name.
-      if (auto Args = D->getTemplateSpecializationArgs()) {
-        std::string ArgString;
-
-        // Print all template arguments into ArgString
-        llvm::raw_string_ostream OS(ArgString);
-        for (unsigned i = 0; i < Args->size(); ++i) {
-          Args->get(i).print(Context.getLangOpts(), OS);
-          // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
-          OS << '\n';
-        }
-        OS.flush();
-
-        addData(ArgString);
-      }
-      addData(D->getQualifiedNameAsString());
-    }
-  })
-
-  //--- Exceptions ---------------------------------------------------------//
-  DEF_ADD_DATA(CXXCatchStmt, { addData(S->getCaughtType()); })
-
-  //--- C++ OOP Stmts ------------------------------------------------------//
-  DEF_ADD_DATA(CXXDeleteExpr, {
-    addData(S->isArrayFormAsWritten());
-    addData(S->isGlobalDelete());
-  })
-
-  //--- Casts --------------------------------------------------------------//
-  DEF_ADD_DATA(ObjCBridgedCastExpr, { addData(S->getBridgeKind()); })
-
-  //--- Miscellaneous Exprs ------------------------------------------------//
-  DEF_ADD_DATA(BinaryOperator, { addData(S->getOpcode()); })
-  DEF_ADD_DATA(UnaryOperator, { addData(S->getOpcode()); })
-
-  //--- Control flow -------------------------------------------------------//
-  DEF_ADD_DATA(GotoStmt, { addData(S->getLabel()->getName()); })
-  DEF_ADD_DATA(IndirectGotoStmt, {
-    if (S->getConstantTarget())
-      addData(S->getConstantTarget()->getName());
-  })
-  DEF_ADD_DATA(LabelStmt, { addData(S->getDecl()->getName()); })
-  DEF_ADD_DATA(MSDependentExistsStmt, { addData(S->isIfExists()); })
-  DEF_ADD_DATA(AddrLabelExpr, { addData(S->getLabel()->getName()); })
-
-  //--- Objective-C --------------------------------------------------------//
-  DEF_ADD_DATA(ObjCIndirectCopyRestoreExpr, { addData(S->shouldCopy()); })
-  DEF_ADD_DATA(ObjCPropertyRefExpr, {
-    addData(S->isSuperReceiver());
-    addData(S->isImplicitProperty());
-  })
-  DEF_ADD_DATA(ObjCAtCatchStmt, { addData(S->hasEllipsis()); })
-
-  //--- Miscellaneous Stmts ------------------------------------------------//
-  DEF_ADD_DATA(CXXFoldExpr, {
-    addData(S->isRightFold());
-    addData(S->getOperator());
-  })
-  DEF_ADD_DATA(GenericSelectionExpr, {
-    for (unsigned i = 0; i < S->getNumAssocs(); ++i) {
-      addData(S->getAssocType(i));
-    }
-  })
-  DEF_ADD_DATA(LambdaExpr, {
-    for (const LambdaCapture &C : S->captures()) {
-      addData(C.isPackExpansion());
-      addData(C.getCaptureKind());
-      if (C.capturesVariable())
-        addData(C.getCapturedVar()->getType());
-    }
-    addData(S->isGenericLambda());
-    addData(S->isMutable());
-  })
-  DEF_ADD_DATA(DeclStmt, {
-    auto numDecls = std::distance(S->decl_begin(), S->decl_end());
-    addData(static_cast<DataPiece>(numDecls));
-    for (const Decl *D : S->decls()) {
-      if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
-        addData(VD->getType());
-      }
-    }
-  })
-  DEF_ADD_DATA(AsmStmt, {
-    addData(S->isSimple());
-    addData(S->isVolatile());
-    addData(S->generateAsmString(Context));
-    for (unsigned i = 0; i < S->getNumInputs(); ++i) {
-      addData(S->getInputConstraint(i));
-    }
-    for (unsigned i = 0; i < S->getNumOutputs(); ++i) {
-      addData(S->getOutputConstraint(i));
-    }
-    for (unsigned i = 0; i < S->getNumClobbers(); ++i) {
-      addData(S->getClobber(i));
-    }
-  })
-  DEF_ADD_DATA(AttributedStmt, {
-    for (const Attr *A : S->getAttrs()) {
-      addData(std::string(A->getSpelling()));
-    }
-  })
-};
-} // namespace clone_detection
-
 /// Identifies a list of statements.
 ///
 /// Can either identify a single arbitrary Stmt object, a continuous sequence of
@@ -423,9 +233,9 @@
   ///                    filtered.
   /// \param Filter The filter function that should return true for all groups
   ///               that should be removed from the list.
-  static void
-  filterGroups(std::vector<CloneDetector::CloneGroup> &CloneGroups,
-               std::function<bool(const CloneDetector::CloneGroup &)> Filter) {
+  static void filterGroups(
+      std::vector<CloneDetector::CloneGroup> &CloneGroups,
+      llvm::function_ref<bool(const CloneDetector::CloneGroup &)> Filter) {
     CloneGroups.erase(
         std::remove_if(CloneGroups.begin(), CloneGroups.end(), Filter),
         CloneGroups.end());
@@ -439,25 +249,29 @@
   ///                to the same CloneGroup.
   static void splitCloneGroups(
       std::vector<CloneDetector::CloneGroup> &CloneGroups,
-      std::function<bool(const StmtSequence &, const StmtSequence &)> Compare);
+      llvm::function_ref<bool(const StmtSequence &, const StmtSequence &)>
+          Compare);
 };
 
-/// Searches all children of the given clones for type II clones (i.e. they are
-/// identical in every aspect beside the used variable names).
-class RecursiveCloneTypeIIConstraint {
+/// This constraint moves clones into clone groups of type II via hashing.
+///
+/// Clones with different hash values are moved into separate clone groups.
+/// Collisions are possible, and this constraint does nothing to address this
+/// them. Add the slower RecursiveCloneTypeIIVerifyConstraint later in the
+/// constraint chain, not necessarily immediately, to eliminate hash collisions
+/// through a more detailed analysis.
+class RecursiveCloneTypeIIHashConstraint {
+public:
+  void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
+};
 
-  /// Generates and saves a hash code for the given Stmt.
-  /// \param S The given Stmt.
-  /// \param D The Decl containing S.
-  /// \param StmtsByHash Output parameter that will contain the hash codes for
-  ///                    each StmtSequence in the given Stmt.
-  /// \return The hash code of the given Stmt.
-  ///
-  /// If the given Stmt is a CompoundStmt, this method will also generate
-  /// hashes for all possible StmtSequences in the children of this Stmt.
-  size_t saveHash(const Stmt *S, const Decl *D,
-                  std::vector<std::pair<size_t, StmtSequence>> &StmtsByHash);
-
+/// This constraint moves clones into clone groups of type II by comparing them.
+///
+/// Clones that aren't type II clones are moved into separate clone groups.
+/// In contrast to the RecursiveCloneTypeIIHashConstraint, all clones in a clone
+/// group are guaranteed to be be type II clones of each other, but it is too
+/// slow to efficiently handle large amounts of clones.
+class RecursiveCloneTypeIIVerifyConstraint {
 public:
   void constrain(std::vector<CloneDetector::CloneGroup> &Sequences);
 };
@@ -474,14 +288,19 @@
   MinComplexityConstraint(unsigned MinComplexity)
       : MinComplexity(MinComplexity) {}
 
-  size_t calculateStmtComplexity(const StmtSequence &Seq,
+  /// Calculates the complexity of the given StmtSequence.
+  /// \param Limit The limit of complexity we probe for. After reaching
+  ///              this limit during calculation, this method is exiting
+  ///              early to improve performance and returns this limit.
+  size_t calculateStmtComplexity(const StmtSequence &Seq, std::size_t Limit,
                                  const std::string &ParentMacroStack = "");
 
   void constrain(std::vector<CloneDetector::CloneGroup> &CloneGroups) {
     CloneConstraint::filterGroups(
         CloneGroups, [this](const CloneDetector::CloneGroup &A) {
           if (!A.empty())
-            return calculateStmtComplexity(A.front()) < MinComplexity;
+            return calculateStmtComplexity(A.front(), MinComplexity) <
+                   MinComplexity;
           else
             return false;
         });
diff --git a/include/clang/Analysis/ProgramPoint.h b/include/clang/Analysis/ProgramPoint.h
index be5adfb..2d59dec 100644
--- a/include/clang/Analysis/ProgramPoint.h
+++ b/include/clang/Analysis/ProgramPoint.h
@@ -15,7 +15,7 @@
 #ifndef LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
 #define LLVM_CLANG_ANALYSIS_PROGRAMPOINT_H
 
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -83,6 +83,7 @@
               PostImplicitCallKind,
               MinImplicitCallKind = PreImplicitCallKind,
               MaxImplicitCallKind = PostImplicitCallKind,
+              LoopExitKind,
               EpsilonKind};
 
 private:
@@ -654,6 +655,29 @@
   }
 };
 
+/// Represents a point when we exit a loop.
+/// When this ProgramPoint is encountered we can be sure that the symbolic
+/// execution of the corresponding LoopStmt is finished on the given path.
+/// Note: It is possible to encounter a LoopExit element when we haven't even
+/// encountered the loop itself. At the current state not all loop exits will
+/// result in a LoopExit program point.
+class LoopExit : public ProgramPoint {
+public:
+    LoopExit(const Stmt *LoopStmt, const LocationContext *LC)
+            : ProgramPoint(LoopStmt, nullptr, LoopExitKind, LC) {}
+
+    const Stmt *getLoopStmt() const {
+      return static_cast<const Stmt *>(getData1());
+    }
+
+private:
+    friend class ProgramPoint;
+    LoopExit() {}
+    static bool isKind(const ProgramPoint &Location) {
+      return Location.getKind() == LoopExitKind;
+    }
+};
+
 /// This is a meta program point, which should be skipped by all the diagnostic
 /// reasoning etc.
 class EpsilonPoint : public ProgramPoint {
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 5c69635..9f8e5c5 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">,
@@ -2126,7 +2239,7 @@
   let TemplateDependent = 1;
   let ParseArgumentsAsUnevaluated = 1;
   let DuplicatesAllowedWhileMerging = 1;
-  let Args = [ExprArgument<"Expr">];
+  let Args = [VariadicExprArgument<"Args">];
   let Accessors = [Accessor<"isShared",
                     [GNU<"assert_shared_capability">,
                      CXX11<"clang", "assert_shared_capability">]>];
@@ -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 567c7a3..7c460f7 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 8dc6e7b..63047d5 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">;
@@ -2729,7 +2737,7 @@
 def err_attribute_weakref_without_alias : Error<
   "weakref declaration of %0 must also have an alias attribute">;
 def err_alias_not_supported_on_darwin : Error <
-  "only weak aliases are supported on darwin">;
+  "aliases are not supported on darwin">;
 def err_alias_to_undefined : Error<
   "%select{alias|ifunc}0 must point to a defined %select{variable or |}1function">;
 def warn_alias_to_weak_alias : Warning<
@@ -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/SanitizerBlacklist.h b/include/clang/Basic/SanitizerBlacklist.h
index e651e18..1ae5c36 100644
--- a/include/clang/Basic/SanitizerBlacklist.h
+++ b/include/clang/Basic/SanitizerBlacklist.h
@@ -15,29 +15,30 @@
 #define LLVM_CLANG_BASIC_SANITIZERBLACKLIST_H
 
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/SanitizerSpecialCaseList.h"
+#include "clang/Basic/Sanitizers.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/Support/SpecialCaseList.h"
 #include <memory>
 
 namespace clang {
 
 class SanitizerBlacklist {
-  std::unique_ptr<llvm::SpecialCaseList> SCL;
+  std::unique_ptr<SanitizerSpecialCaseList> SSCL;
   SourceManager &SM;
 
 public:
   SanitizerBlacklist(const std::vector<std::string> &BlacklistPaths,
                      SourceManager &SM);
-  bool isBlacklistedGlobal(StringRef GlobalName,
+  bool isBlacklistedGlobal(SanitizerMask Mask, StringRef GlobalName,
                            StringRef Category = StringRef()) const;
-  bool isBlacklistedType(StringRef MangledTypeName,
+  bool isBlacklistedType(SanitizerMask Mask, StringRef MangledTypeName,
                          StringRef Category = StringRef()) const;
-  bool isBlacklistedFunction(StringRef FunctionName) const;
-  bool isBlacklistedFile(StringRef FileName,
+  bool isBlacklistedFunction(SanitizerMask Mask, StringRef FunctionName) const;
+  bool isBlacklistedFile(SanitizerMask Mask, StringRef FileName,
                          StringRef Category = StringRef()) const;
-  bool isBlacklistedLocation(SourceLocation Loc,
+  bool isBlacklistedLocation(SanitizerMask Mask, SourceLocation Loc,
                              StringRef Category = StringRef()) const;
 };
 
diff --git a/include/clang/Basic/SanitizerSpecialCaseList.h b/include/clang/Basic/SanitizerSpecialCaseList.h
new file mode 100644
index 0000000..e325202
--- /dev/null
+++ b/include/clang/Basic/SanitizerSpecialCaseList.h
@@ -0,0 +1,54 @@
+//===--- SanitizerSpecialCaseList.h - SCL for sanitizers --------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An extension of SpecialCaseList to allowing querying sections by
+// SanitizerMask.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H
+#define LLVM_CLANG_BASIC_SANITIZERSPECIALCASELIST_H
+
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/Sanitizers.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/SpecialCaseList.h"
+#include <memory>
+
+namespace clang {
+
+class SanitizerSpecialCaseList : public llvm::SpecialCaseList {
+public:
+  static std::unique_ptr<SanitizerSpecialCaseList>
+  create(const std::vector<std::string> &Paths, std::string &Error);
+
+  static std::unique_ptr<SanitizerSpecialCaseList>
+  createOrDie(const std::vector<std::string> &Paths);
+
+  // Query blacklisted entries if any bit in Mask matches the entry's section.
+  bool inSection(SanitizerMask Mask, StringRef Prefix, StringRef Query,
+                 StringRef Category = StringRef()) const;
+
+protected:
+  // Initialize SanitizerSections.
+  void createSanitizerSections();
+
+  struct SanitizerSection {
+    SanitizerSection(SanitizerMask SM, SectionEntries &E)
+        : Mask(SM), Entries(E){};
+
+    SanitizerMask Mask;
+    SectionEntries &Entries;
+  };
+
+  std::vector<SanitizerSection> SanitizerSections;
+};
+
+} // end namespace clang
+
+#endif
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..4e1ea84 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -70,7 +70,7 @@
 def analyzer_display_progress : Flag<["-"], "analyzer-display-progress">,
   HelpText<"Emit verbose output about the analyzer's progress">;
 def analyze_function : Separate<["-"], "analyze-function">,
-  HelpText<"Run analysis on specific function">;
+  HelpText<"Run analysis on specific function (for C++ include parameters in name)">;
 def analyze_function_EQ : Joined<["-"], "analyze-function=">, Alias<analyze_function>;
 def analyzer_eagerly_assume : Flag<["-"], "analyzer-eagerly-assume">,
   HelpText<"Eagerly assume the truth/falseness of some symbolic constraints">;
@@ -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..e811296 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]>;
 
@@ -588,7 +595,9 @@
   HelpText<"Use Apple's kernel extensions ABI">;
 def fapple_pragma_pack : Flag<["-"], "fapple-pragma-pack">, Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Enable Apple gcc-compatible #pragma pack handling">;
-def shared_libasan : Flag<["-"], "shared-libasan">;
+def shared_libsan : Flag<["-"], "shared-libsan">;
+def static_libsan : Flag<["-"], "static-libsan">;
+def : Flag<["-"], "shared-libasan">, Alias<shared_libsan>;
 def fasm : Flag<["-"], "fasm">, Group<f_Group>;
 
 def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>, Flags<[CC1Option]>;
@@ -685,6 +694,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 +718,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 +889,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 +1610,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 +2158,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..6de39d9 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -33,7 +33,7 @@
   bool MsanUseAfterDtor = false;
   bool CfiCrossDso = false;
   int AsanFieldPadding = 0;
-  bool AsanSharedRuntime = false;
+  bool SharedRuntime = false;
   bool AsanUseAfterScope = true;
   bool AsanGlobalsDeadStripping = false;
   bool LinkCXXRuntimes = false;
@@ -42,13 +42,15 @@
   bool TsanMemoryAccess = true;
   bool TsanFuncEntryExit = true;
   bool TsanAtomics = true;
+  bool MinimalRuntime = false;
 
  public:
   /// Parses the sanitizer arguments from an argument list.
   SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
 
+  bool needsSharedRt() const { return SharedRuntime; }
+
   bool needsAsanRt() const { return Sanitizers.has(SanitizerKind::Address); }
-  bool needsSharedAsanRt() const { return AsanSharedRuntime; }
   bool needsTsanRt() const { return Sanitizers.has(SanitizerKind::Thread); }
   bool needsMsanRt() const { return Sanitizers.has(SanitizerKind::Memory); }
   bool needsFuzzer() const { return Sanitizers.has(SanitizerKind::Fuzzer); }
@@ -57,6 +59,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..d157d54 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -235,6 +235,14 @@
   virtual void PragmaWarningPop(SourceLocation Loc) {
   }
 
+  /// \brief Callback invoked when a \#pragma clang assume_nonnull begin directive
+  /// is read.
+  virtual void PragmaAssumeNonNullBegin(SourceLocation Loc) {}
+
+  /// \brief Callback invoked when a \#pragma clang assume_nonnull end directive
+  /// is read.
+  virtual void PragmaAssumeNonNullEnd(SourceLocation Loc) {}
+
   /// \brief Called by Preprocessor::HandleMacroExpandedIdentifier when a
   /// macro invocation is found.
   virtual void MacroExpands(const Token &MacroNameTok,
@@ -266,7 +274,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 {
@@ -437,6 +448,16 @@
     Second->PragmaWarningPop(Loc);
   }
 
+  void PragmaAssumeNonNullBegin(SourceLocation Loc) override {
+    First->PragmaAssumeNonNullBegin(Loc);
+    Second->PragmaAssumeNonNullBegin(Loc);
+  }
+
+  void PragmaAssumeNonNullEnd(SourceLocation Loc) override {
+    First->PragmaAssumeNonNullEnd(Loc);
+    Second->PragmaAssumeNonNullEnd(Loc);
+  }
+
   void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
                     SourceRange Range, const MacroArgs *Args) override {
     First->MacroExpands(MacroNameTok, MD, Range, Args);
@@ -462,9 +483,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..6b92e96 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -1517,9 +1517,10 @@
   typedef SmallVector<SourceLocation, 20> CommaLocsTy;
 
   /// ParseExpressionList - Used for C/C++ (argument-)expression-list.
-  bool ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
-                           SmallVectorImpl<SourceLocation> &CommaLocs,
-                           std::function<void()> Completer = nullptr);
+  bool ParseExpressionList(
+      SmallVectorImpl<Expr *> &Exprs,
+      SmallVectorImpl<SourceLocation> &CommaLocs,
+      llvm::function_ref<void()> Completer = llvm::function_ref<void()>());
 
   /// ParseSimpleExpressionList - A simple comma-separated list of expressions,
   /// used for misc language extensions.
@@ -2362,6 +2363,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 +2793,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..210dabe 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.
@@ -10126,8 +10178,7 @@
   void CodeCompleteObjCPropertyDefinition(Scope *S);
   void CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
                                               IdentifierInfo *PropertyName);
-  void CodeCompleteObjCMethodDecl(Scope *S,
-                                  bool IsInstanceMethod,
+  void CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod,
                                   ParsedType ReturnType);
   void CodeCompleteObjCMethodDeclSelector(Scope *S,
                                           bool IsInstanceMethod,
@@ -10396,6 +10447,7 @@
 
   /// The struct behind the CFErrorRef pointer.
   RecordDecl *CFError = nullptr;
+  bool isCFError(RecordDecl *D);
 
   /// Retrieve the identifier "NSError".
   IdentifierInfo *getNSErrorIdent();
@@ -10446,6 +10498,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/StaticAnalyzer/Checkers/Checkers.td b/include/clang/StaticAnalyzer/Checkers/Checkers.td
index 82ab720..be8b149 100644
--- a/include/clang/StaticAnalyzer/Checkers/Checkers.td
+++ b/include/clang/StaticAnalyzer/Checkers/Checkers.td
@@ -132,6 +132,10 @@
   HelpText<"Generate dynamic type information">,
   DescFile<"DynamicTypePropagation.cpp">;
 
+def NonnullGlobalConstantsChecker: Checker<"NonnilStringConstants">,
+  HelpText<"Assume that const string-like globals are non-null">,
+  DescFile<"NonilStringConstantsChecker.cpp">;
+
 } // end "core"
 
 let ParentPackage = CoreAlpha in {
@@ -284,6 +288,11 @@
 
 let ParentPackage = CplusplusAlpha in {
 
+def DeleteWithNonVirtualDtorChecker : Checker<"DeleteWithNonVirtualDtor">,
+  HelpText<"Reports destructions of polymorphic objects with a non-virtual "
+           "destructor in their base class">,
+  DescFile<"DeleteWithNonVirtualDtorChecker.cpp">;
+
 def IteratorRangeChecker : Checker<"IteratorRange">,
   HelpText<"Check for iterators used outside their valid ranges">,
   DescFile<"IteratorChecker.cpp">;
@@ -740,10 +749,6 @@
   HelpText<"View Exploded Graphs using GraphViz">,
   DescFile<"DebugCheckers.cpp">;
 
-def BugHashDumper : Checker<"DumpBugHash">,
-  HelpText<"Dump the bug hash for all statements.">,
-  DescFile<"DebugCheckers.cpp">;
-
 } // end "debug"
 
 
diff --git a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
index 2588654..e5e857e 100644
--- a/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
+++ b/include/clang/StaticAnalyzer/Checkers/ObjCRetainCount.h
@@ -145,9 +145,11 @@
     /// Indicates that the tracked object is an Objective-C object.
     ObjC,
     /// Indicates that the tracked object could be a CF or Objective-C object.
-    AnyObj
+    AnyObj,
+    /// Indicates that the tracked object is a generalized object.
+    Generalized
   };
-  
+
 private:
   Kind K;
   ObjKind O;
diff --git a/include/clang/StaticAnalyzer/Core/Analyses.def b/include/clang/StaticAnalyzer/Core/Analyses.def
index 04bf41b..281a2ac 100644
--- a/include/clang/StaticAnalyzer/Core/Analyses.def
+++ b/include/clang/StaticAnalyzer/Core/Analyses.def
@@ -28,9 +28,10 @@
 #define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)
 #endif
 
-ANALYSIS_DIAGNOSTICS(HTML,  "html",  "Output analysis results using HTML",   createHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", createHTMLDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(HTML_SINGLE_FILE, "html-single-file", "Output analysis results using HTML (not allowing for multi-file bugs)", createHTMLSingleFileDiagnosticConsumer)
 ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", createPlistDiagnosticConsumer)
-ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for mult-file bugs)", createPlistMultiFileDiagnosticConsumer)
+ANALYSIS_DIAGNOSTICS(PLIST_MULTI_FILE, "plist-multi-file", "Output analysis results using Plists (allowing for multi-file bugs)", createPlistMultiFileDiagnosticConsumer)
 ANALYSIS_DIAGNOSTICS(PLIST_HTML, "plist-html", "Output analysis results using HTML wrapped with Plists", createPlistHTMLDiagnosticConsumer)
 ANALYSIS_DIAGNOSTICS(TEXT, "text", "Text output of analysis results", createTextPathDiagnosticConsumer)
 
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
index 5dd6bdf..ce50cc5 100644
--- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
+++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
@@ -214,6 +214,9 @@
   /// \sa IncludeLifetimeInCFG
   Optional<bool> IncludeLifetimeInCFG;
 
+  /// \sa IncludeLoopExitInCFG
+  Optional<bool> IncludeLoopExitInCFG;
+
   /// \sa mayInlineCXXStandardLibrary
   Optional<bool> InlineCXXStandardLibrary;
   
@@ -275,6 +278,9 @@
   /// \sa shouldWidenLoops
   Optional<bool> WidenLoops;
 
+  /// \sa shouldUnrollLoops
+  Optional<bool> UnrollLoops;
+
   /// \sa shouldDisplayNotesAsEvents
   Optional<bool> DisplayNotesAsEvents;
 
@@ -415,6 +421,13 @@
   /// the values "true" and "false".
   bool includeLifetimeInCFG();
 
+  /// Returns whether or not the end of the loop information should be included
+  /// in the CFG.
+  ///
+  /// This is controlled by the 'cfg-loopexit' config option, which accepts
+  /// the values "true" and "false".
+  bool includeLoopExitInCFG();
+
   /// Returns whether or not C++ standard library functions may be considered
   /// for inlining.
   ///
@@ -560,6 +573,10 @@
   /// This is controlled by the 'widen-loops' config option.
   bool shouldWidenLoops();
 
+  /// Returns true if the analysis should try to unroll loops with known bounds.
+  /// This is controlled by the 'unroll-loops' config option.
+  bool shouldUnrollLoops();
+
   /// Returns true if the bug reporter should transparently treat extra note
   /// diagnostic pieces as event diagnostic pieces. Useful when the diagnostic
   /// consumer doesn't support the extra note pieces.
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 0f1eb09..cd1355d 100644
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -17,7 +17,7 @@
 
 #include "clang/Basic/SourceLocation.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
deleted file mode 100644
index b72bce5..0000000
--- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h
+++ /dev/null
@@ -1,379 +0,0 @@
-//===---  BugReporterVisitor.h - Generate PathDiagnostics -------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-//  This file declares BugReporterVisitors, which are used to generate enhanced
-//  diagnostic traces.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITOR_H
-#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITOR_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "llvm/ADT/FoldingSet.h"
-
-namespace clang {
-class CFGBlock;
-
-namespace ento {
-
-class BugReport;
-class BugReporterContext;
-class ExplodedNode;
-class MemRegion;
-class PathDiagnosticPiece;
-
-/// \brief BugReporterVisitors are used to add custom diagnostics along a path.
-///
-/// Custom visitors should subclass the BugReporterVisitorImpl class for a
-/// default implementation of the clone() method.
-/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
-/// default implementation of clone() will NOT do the right thing, and you
-/// will have to provide your own implementation.)
-class BugReporterVisitor : public llvm::FoldingSetNode {
-public:
-  BugReporterVisitor() = default;
-  BugReporterVisitor(const BugReporterVisitor &) = default;
-  BugReporterVisitor(BugReporterVisitor &&) {}
-  virtual ~BugReporterVisitor();
-
-  /// \brief Returns a copy of this BugReporter.
-  ///
-  /// Custom BugReporterVisitors should not override this method directly.
-  /// Instead, they should inherit from BugReporterVisitorImpl and provide
-  /// a protected or public copy constructor.
-  ///
-  /// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
-  /// default implementation of clone() will NOT do the right thing, and you
-  /// will have to provide your own implementation.)
-  virtual std::unique_ptr<BugReporterVisitor> clone() const = 0;
-
-  /// \brief Return a diagnostic piece which should be associated with the
-  /// given node.
-  ///
-  /// The last parameter can be used to register a new visitor with the given
-  /// BugReport while processing a node.
-  virtual std::shared_ptr<PathDiagnosticPiece>
-  VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred,
-            BugReporterContext &BRC, BugReport &BR) = 0;
-
-  /// \brief Provide custom definition for the final diagnostic piece on the
-  /// path - the piece, which is displayed before the path is expanded.
-  ///
-  /// If returns NULL the default implementation will be used.
-  /// Also note that at most one visitor of a BugReport should generate a
-  /// non-NULL end of path diagnostic piece.
-  virtual std::unique_ptr<PathDiagnosticPiece>
-  getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR);
-
-  virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
-
-  /// \brief Generates the default final diagnostic piece.
-  static std::unique_ptr<PathDiagnosticPiece>
-  getDefaultEndPath(BugReporterContext &BRC, const ExplodedNode *N,
-                    BugReport &BR);
-};
-
-/// This class provides a convenience implementation for clone() using the
-/// Curiously-Recurring Template Pattern. If you are implementing a custom
-/// BugReporterVisitor, subclass BugReporterVisitorImpl and provide a public
-/// or protected copy constructor.
-///
-/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
-/// default implementation of clone() will NOT do the right thing, and you
-/// will have to provide your own implementation.)
-template <class DERIVED>
-class BugReporterVisitorImpl : public BugReporterVisitor {
-  std::unique_ptr<BugReporterVisitor> clone() const override {
-    return llvm::make_unique<DERIVED>(*static_cast<const DERIVED *>(this));
-  }
-};
-
-class FindLastStoreBRVisitor final
-    : public BugReporterVisitorImpl<FindLastStoreBRVisitor> {
-  const MemRegion *R;
-  SVal V;
-  bool Satisfied;
-
-  /// If the visitor is tracking the value directly responsible for the
-  /// bug, we are going to employ false positive suppression.
-  bool EnableNullFPSuppression;
-
-public:
-  /// Creates a visitor for every VarDecl inside a Stmt and registers it with
-  /// the BugReport.
-  static void registerStatementVarDecls(BugReport &BR, const Stmt *S,
-                                        bool EnableNullFPSuppression);
-
-  FindLastStoreBRVisitor(KnownSVal V, const MemRegion *R,
-                         bool InEnableNullFPSuppression)
-  : R(R),
-    V(V),
-    Satisfied(false),
-    EnableNullFPSuppression(InEnableNullFPSuppression) {}
-
-  void Profile(llvm::FoldingSetNodeID &ID) const override;
-
-  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
-                                                 const ExplodedNode *PrevN,
-                                                 BugReporterContext &BRC,
-                                                 BugReport &BR) override;
-};
-
-class TrackConstraintBRVisitor final
-    : public BugReporterVisitorImpl<TrackConstraintBRVisitor> {
-  DefinedSVal Constraint;
-  bool Assumption;
-  bool IsSatisfied;
-  bool IsZeroCheck;
-
-  /// We should start tracking from the last node along the path in which the
-  /// value is constrained.
-  bool IsTrackingTurnedOn;
-
-public:
-  TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
-  : Constraint(constraint), Assumption(assumption), IsSatisfied(false),
-    IsZeroCheck(!Assumption && Constraint.getAs<Loc>()),
-    IsTrackingTurnedOn(false) {}
-
-  void Profile(llvm::FoldingSetNodeID &ID) const override;
-
-  /// Return the tag associated with this visitor.  This tag will be used
-  /// to make all PathDiagnosticPieces created by this visitor.
-  static const char *getTag();
-
-  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
-                                                 const ExplodedNode *PrevN,
-                                                 BugReporterContext &BRC,
-                                                 BugReport &BR) override;
-
-private:
-  /// Checks if the constraint is valid in the current state.
-  bool isUnderconstrained(const ExplodedNode *N) const;
-
-};
-
-/// \class NilReceiverBRVisitor
-/// \brief Prints path notes when a message is sent to a nil receiver.
-class NilReceiverBRVisitor final
-    : public BugReporterVisitorImpl<NilReceiverBRVisitor> {
-public:
-
-  void Profile(llvm::FoldingSetNodeID &ID) const override {
-    static int x = 0;
-    ID.AddPointer(&x);
-  }
-
-  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
-                                                 const ExplodedNode *PrevN,
-                                                 BugReporterContext &BRC,
-                                                 BugReport &BR) override;
-
-  /// If the statement is a message send expression with nil receiver, returns
-  /// the receiver expression. Returns NULL otherwise.
-  static const Expr *getNilReceiver(const Stmt *S, const ExplodedNode *N);
-};
-
-/// Visitor that tries to report interesting diagnostics from conditions.
-class ConditionBRVisitor final
-    : public BugReporterVisitorImpl<ConditionBRVisitor> {
-
-  // FIXME: constexpr initialization isn't supported by MSVC2013.
-  static const char *const GenericTrueMessage;
-  static const char *const GenericFalseMessage;
-
-public:
-  void Profile(llvm::FoldingSetNodeID &ID) const override {
-    static int x = 0;
-    ID.AddPointer(&x);
-  }
-
-  /// Return the tag associated with this visitor.  This tag will be used
-  /// to make all PathDiagnosticPieces created by this visitor.
-  static const char *getTag();
-
-  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
-                                                 const ExplodedNode *Prev,
-                                                 BugReporterContext &BRC,
-                                                 BugReport &BR) override;
-
-  std::shared_ptr<PathDiagnosticPiece> VisitNodeImpl(const ExplodedNode *N,
-                                                     const ExplodedNode *Prev,
-                                                     BugReporterContext &BRC,
-                                                     BugReport &BR);
-
-  std::shared_ptr<PathDiagnosticPiece>
-  VisitTerminator(const Stmt *Term, const ExplodedNode *N,
-                  const CFGBlock *srcBlk, const CFGBlock *dstBlk, BugReport &R,
-                  BugReporterContext &BRC);
-
-  std::shared_ptr<PathDiagnosticPiece>
-  VisitTrueTest(const Expr *Cond, bool tookTrue, BugReporterContext &BRC,
-                BugReport &R, const ExplodedNode *N);
-
-  std::shared_ptr<PathDiagnosticPiece>
-  VisitTrueTest(const Expr *Cond, const DeclRefExpr *DR, const bool tookTrue,
-                BugReporterContext &BRC, BugReport &R, const ExplodedNode *N);
-
-  std::shared_ptr<PathDiagnosticPiece>
-  VisitTrueTest(const Expr *Cond, const BinaryOperator *BExpr,
-                const bool tookTrue, BugReporterContext &BRC, BugReport &R,
-                const ExplodedNode *N);
-
-  std::shared_ptr<PathDiagnosticPiece>
-  VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr,
-                         const bool tookTrue, BugReporterContext &BRC,
-                         BugReport &R, const ExplodedNode *N);
-
-  bool patternMatch(const Expr *Ex,
-                    const Expr *ParentEx,
-                    raw_ostream &Out,
-                    BugReporterContext &BRC,
-                    BugReport &R,
-                    const ExplodedNode *N,
-                    Optional<bool> &prunable);
-
-  static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece);
-};
-
-/// \brief Suppress reports that might lead to known false positives.
-///
-/// Currently this suppresses reports based on locations of bugs.
-class LikelyFalsePositiveSuppressionBRVisitor final
-    : public BugReporterVisitorImpl<LikelyFalsePositiveSuppressionBRVisitor> {
-public:
-  static void *getTag() {
-    static int Tag = 0;
-    return static_cast<void *>(&Tag);
-  }
-
-  void Profile(llvm::FoldingSetNodeID &ID) const override {
-    ID.AddPointer(getTag());
-  }
-
-  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
-                                                 const ExplodedNode *Prev,
-                                                 BugReporterContext &BRC,
-                                                 BugReport &BR) override {
-    return nullptr;
-  }
-
-  std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
-                                                  const ExplodedNode *N,
-                                                  BugReport &BR) override;
-};
-
-/// \brief When a region containing undefined value or '0' value is passed 
-/// as an argument in a call, marks the call as interesting.
-///
-/// As a result, BugReporter will not prune the path through the function even
-/// if the region's contents are not modified/accessed by the call.
-class UndefOrNullArgVisitor final
-    : public BugReporterVisitorImpl<UndefOrNullArgVisitor> {
-
-  /// The interesting memory region this visitor is tracking.
-  const MemRegion *R;
-
-public:
-  UndefOrNullArgVisitor(const MemRegion *InR) : R(InR) {}
-
-  void Profile(llvm::FoldingSetNodeID &ID) const override {
-    static int Tag = 0;
-    ID.AddPointer(&Tag);
-    ID.AddPointer(R);
-  }
-
-  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
-                                                 const ExplodedNode *PrevN,
-                                                 BugReporterContext &BRC,
-                                                 BugReport &BR) override;
-};
-
-class SuppressInlineDefensiveChecksVisitor final
-    : public BugReporterVisitorImpl<SuppressInlineDefensiveChecksVisitor> {
-  /// The symbolic value for which we are tracking constraints.
-  /// This value is constrained to null in the end of path.
-  DefinedSVal V;
-
-  /// Track if we found the node where the constraint was first added.
-  bool IsSatisfied;
-
-  /// Since the visitors can be registered on nodes previous to the last
-  /// node in the BugReport, but the path traversal always starts with the last
-  /// node, the visitor invariant (that we start with a node in which V is null)
-  /// might not hold when node visitation starts. We are going to start tracking
-  /// from the last node in which the value is null.
-  bool IsTrackingTurnedOn;
-
-public:
-  SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N);
-
-  void Profile(llvm::FoldingSetNodeID &ID) const override;
-
-  /// Return the tag associated with this visitor.  This tag will be used
-  /// to make all PathDiagnosticPieces created by this visitor.
-  static const char *getTag();
-
-  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
-                                                 const ExplodedNode *Pred,
-                                                 BugReporterContext &BRC,
-                                                 BugReport &BR) override;
-};
-
-class CXXSelfAssignmentBRVisitor final
-  : public BugReporterVisitorImpl<CXXSelfAssignmentBRVisitor> {
-  
-  bool Satisfied;
-
-public:
-  CXXSelfAssignmentBRVisitor() : Satisfied(false) {}
-
-  void Profile(llvm::FoldingSetNodeID &ID) const override {}
-
-  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
-                                                 const ExplodedNode *Pred,
-                                                 BugReporterContext &BRC,
-                                                 BugReport &BR) override;
-};
-
-namespace bugreporter {
-
-/// Attempts to add visitors to trace a null or undefined value back to its
-/// point of origin, whether it is a symbol constrained to null or an explicit
-/// assignment.
-///
-/// \param N A node "downstream" from the evaluation of the statement.
-/// \param S The statement whose value is null or undefined.
-/// \param R The bug report to which visitors should be attached.
-/// \param IsArg Whether the statement is an argument to an inlined function.
-///              If this is the case, \p N \em must be the CallEnter node for
-///              the function.
-/// \param EnableNullFPSuppression Whether we should employ false positive
-///         suppression (inlined defensive checks, returned null).
-///
-/// \return Whether or not the function was able to add visitors for this
-///         statement. Note that returning \c true does not actually imply
-///         that any visitors were added.
-bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R,
-                           bool IsArg = false,
-                           bool EnableNullFPSuppression = true);
-
-const Expr *getDerefExpr(const Stmt *S);
-const Stmt *GetDenomExpr(const ExplodedNode *N);
-const Stmt *GetRetValExpr(const ExplodedNode *N);
-bool isDeclRefExprToReference(const Expr *E);
-
-
-} // end namespace clang
-} // end namespace ento
-} // end namespace bugreporter
-
-
-#endif
diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
new file mode 100644
index 0000000..2043896
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h
@@ -0,0 +1,379 @@
+//===---  BugReporterVisitors.h - Generate PathDiagnostics -------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file declares BugReporterVisitors, which are used to generate enhanced
+//  diagnostic traces.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
+#define LLVM_CLANG_STATICANALYZER_CORE_BUGREPORTER_BUGREPORTERVISITORS_H
+
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/FoldingSet.h"
+
+namespace clang {
+class CFGBlock;
+
+namespace ento {
+
+class BugReport;
+class BugReporterContext;
+class ExplodedNode;
+class MemRegion;
+class PathDiagnosticPiece;
+
+/// \brief BugReporterVisitors are used to add custom diagnostics along a path.
+///
+/// Custom visitors should subclass the BugReporterVisitorImpl class for a
+/// default implementation of the clone() method.
+/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
+/// default implementation of clone() will NOT do the right thing, and you
+/// will have to provide your own implementation.)
+class BugReporterVisitor : public llvm::FoldingSetNode {
+public:
+  BugReporterVisitor() = default;
+  BugReporterVisitor(const BugReporterVisitor &) = default;
+  BugReporterVisitor(BugReporterVisitor &&) {}
+  virtual ~BugReporterVisitor();
+
+  /// \brief Returns a copy of this BugReporter.
+  ///
+  /// Custom BugReporterVisitors should not override this method directly.
+  /// Instead, they should inherit from BugReporterVisitorImpl and provide
+  /// a protected or public copy constructor.
+  ///
+  /// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
+  /// default implementation of clone() will NOT do the right thing, and you
+  /// will have to provide your own implementation.)
+  virtual std::unique_ptr<BugReporterVisitor> clone() const = 0;
+
+  /// \brief Return a diagnostic piece which should be associated with the
+  /// given node.
+  ///
+  /// The last parameter can be used to register a new visitor with the given
+  /// BugReport while processing a node.
+  virtual std::shared_ptr<PathDiagnosticPiece>
+  VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred,
+            BugReporterContext &BRC, BugReport &BR) = 0;
+
+  /// \brief Provide custom definition for the final diagnostic piece on the
+  /// path - the piece, which is displayed before the path is expanded.
+  ///
+  /// If returns NULL the default implementation will be used.
+  /// Also note that at most one visitor of a BugReport should generate a
+  /// non-NULL end of path diagnostic piece.
+  virtual std::unique_ptr<PathDiagnosticPiece>
+  getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR);
+
+  virtual void Profile(llvm::FoldingSetNodeID &ID) const = 0;
+
+  /// \brief Generates the default final diagnostic piece.
+  static std::unique_ptr<PathDiagnosticPiece>
+  getDefaultEndPath(BugReporterContext &BRC, const ExplodedNode *N,
+                    BugReport &BR);
+};
+
+/// This class provides a convenience implementation for clone() using the
+/// Curiously-Recurring Template Pattern. If you are implementing a custom
+/// BugReporterVisitor, subclass BugReporterVisitorImpl and provide a public
+/// or protected copy constructor.
+///
+/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
+/// default implementation of clone() will NOT do the right thing, and you
+/// will have to provide your own implementation.)
+template <class DERIVED>
+class BugReporterVisitorImpl : public BugReporterVisitor {
+  std::unique_ptr<BugReporterVisitor> clone() const override {
+    return llvm::make_unique<DERIVED>(*static_cast<const DERIVED *>(this));
+  }
+};
+
+class FindLastStoreBRVisitor final
+    : public BugReporterVisitorImpl<FindLastStoreBRVisitor> {
+  const MemRegion *R;
+  SVal V;
+  bool Satisfied;
+
+  /// If the visitor is tracking the value directly responsible for the
+  /// bug, we are going to employ false positive suppression.
+  bool EnableNullFPSuppression;
+
+public:
+  /// Creates a visitor for every VarDecl inside a Stmt and registers it with
+  /// the BugReport.
+  static void registerStatementVarDecls(BugReport &BR, const Stmt *S,
+                                        bool EnableNullFPSuppression);
+
+  FindLastStoreBRVisitor(KnownSVal V, const MemRegion *R,
+                         bool InEnableNullFPSuppression)
+  : R(R),
+    V(V),
+    Satisfied(false),
+    EnableNullFPSuppression(InEnableNullFPSuppression) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
+};
+
+class TrackConstraintBRVisitor final
+    : public BugReporterVisitorImpl<TrackConstraintBRVisitor> {
+  DefinedSVal Constraint;
+  bool Assumption;
+  bool IsSatisfied;
+  bool IsZeroCheck;
+
+  /// We should start tracking from the last node along the path in which the
+  /// value is constrained.
+  bool IsTrackingTurnedOn;
+
+public:
+  TrackConstraintBRVisitor(DefinedSVal constraint, bool assumption)
+  : Constraint(constraint), Assumption(assumption), IsSatisfied(false),
+    IsZeroCheck(!Assumption && Constraint.getAs<Loc>()),
+    IsTrackingTurnedOn(false) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  /// Return the tag associated with this visitor.  This tag will be used
+  /// to make all PathDiagnosticPieces created by this visitor.
+  static const char *getTag();
+
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
+
+private:
+  /// Checks if the constraint is valid in the current state.
+  bool isUnderconstrained(const ExplodedNode *N) const;
+
+};
+
+/// \class NilReceiverBRVisitor
+/// \brief Prints path notes when a message is sent to a nil receiver.
+class NilReceiverBRVisitor final
+    : public BugReporterVisitorImpl<NilReceiverBRVisitor> {
+public:
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    static int x = 0;
+    ID.AddPointer(&x);
+  }
+
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
+
+  /// If the statement is a message send expression with nil receiver, returns
+  /// the receiver expression. Returns NULL otherwise.
+  static const Expr *getNilReceiver(const Stmt *S, const ExplodedNode *N);
+};
+
+/// Visitor that tries to report interesting diagnostics from conditions.
+class ConditionBRVisitor final
+    : public BugReporterVisitorImpl<ConditionBRVisitor> {
+
+  // FIXME: constexpr initialization isn't supported by MSVC2013.
+  static const char *const GenericTrueMessage;
+  static const char *const GenericFalseMessage;
+
+public:
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    static int x = 0;
+    ID.AddPointer(&x);
+  }
+
+  /// Return the tag associated with this visitor.  This tag will be used
+  /// to make all PathDiagnosticPieces created by this visitor.
+  static const char *getTag();
+
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *Prev,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
+
+  std::shared_ptr<PathDiagnosticPiece> VisitNodeImpl(const ExplodedNode *N,
+                                                     const ExplodedNode *Prev,
+                                                     BugReporterContext &BRC,
+                                                     BugReport &BR);
+
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitTerminator(const Stmt *Term, const ExplodedNode *N,
+                  const CFGBlock *srcBlk, const CFGBlock *dstBlk, BugReport &R,
+                  BugReporterContext &BRC);
+
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitTrueTest(const Expr *Cond, bool tookTrue, BugReporterContext &BRC,
+                BugReport &R, const ExplodedNode *N);
+
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitTrueTest(const Expr *Cond, const DeclRefExpr *DR, const bool tookTrue,
+                BugReporterContext &BRC, BugReport &R, const ExplodedNode *N);
+
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitTrueTest(const Expr *Cond, const BinaryOperator *BExpr,
+                const bool tookTrue, BugReporterContext &BRC, BugReport &R,
+                const ExplodedNode *N);
+
+  std::shared_ptr<PathDiagnosticPiece>
+  VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr,
+                         const bool tookTrue, BugReporterContext &BRC,
+                         BugReport &R, const ExplodedNode *N);
+
+  bool patternMatch(const Expr *Ex,
+                    const Expr *ParentEx,
+                    raw_ostream &Out,
+                    BugReporterContext &BRC,
+                    BugReport &R,
+                    const ExplodedNode *N,
+                    Optional<bool> &prunable);
+
+  static bool isPieceMessageGeneric(const PathDiagnosticPiece *Piece);
+};
+
+/// \brief Suppress reports that might lead to known false positives.
+///
+/// Currently this suppresses reports based on locations of bugs.
+class LikelyFalsePositiveSuppressionBRVisitor final
+    : public BugReporterVisitorImpl<LikelyFalsePositiveSuppressionBRVisitor> {
+public:
+  static void *getTag() {
+    static int Tag = 0;
+    return static_cast<void *>(&Tag);
+  }
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    ID.AddPointer(getTag());
+  }
+
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *Prev,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override {
+    return nullptr;
+  }
+
+  std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
+                                                  const ExplodedNode *N,
+                                                  BugReport &BR) override;
+};
+
+/// \brief When a region containing undefined value or '0' value is passed 
+/// as an argument in a call, marks the call as interesting.
+///
+/// As a result, BugReporter will not prune the path through the function even
+/// if the region's contents are not modified/accessed by the call.
+class UndefOrNullArgVisitor final
+    : public BugReporterVisitorImpl<UndefOrNullArgVisitor> {
+
+  /// The interesting memory region this visitor is tracking.
+  const MemRegion *R;
+
+public:
+  UndefOrNullArgVisitor(const MemRegion *InR) : R(InR) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    static int Tag = 0;
+    ID.AddPointer(&Tag);
+    ID.AddPointer(R);
+  }
+
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
+};
+
+class SuppressInlineDefensiveChecksVisitor final
+    : public BugReporterVisitorImpl<SuppressInlineDefensiveChecksVisitor> {
+  /// The symbolic value for which we are tracking constraints.
+  /// This value is constrained to null in the end of path.
+  DefinedSVal V;
+
+  /// Track if we found the node where the constraint was first added.
+  bool IsSatisfied;
+
+  /// Since the visitors can be registered on nodes previous to the last
+  /// node in the BugReport, but the path traversal always starts with the last
+  /// node, the visitor invariant (that we start with a node in which V is null)
+  /// might not hold when node visitation starts. We are going to start tracking
+  /// from the last node in which the value is null.
+  bool IsTrackingTurnedOn;
+
+public:
+  SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N);
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override;
+
+  /// Return the tag associated with this visitor.  This tag will be used
+  /// to make all PathDiagnosticPieces created by this visitor.
+  static const char *getTag();
+
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+                                                 const ExplodedNode *Pred,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
+};
+
+class CXXSelfAssignmentBRVisitor final
+  : public BugReporterVisitorImpl<CXXSelfAssignmentBRVisitor> {
+  
+  bool Satisfied;
+
+public:
+  CXXSelfAssignmentBRVisitor() : Satisfied(false) {}
+
+  void Profile(llvm::FoldingSetNodeID &ID) const override {}
+
+  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
+                                                 const ExplodedNode *Pred,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) override;
+};
+
+namespace bugreporter {
+
+/// Attempts to add visitors to trace a null or undefined value back to its
+/// point of origin, whether it is a symbol constrained to null or an explicit
+/// assignment.
+///
+/// \param N A node "downstream" from the evaluation of the statement.
+/// \param S The statement whose value is null or undefined.
+/// \param R The bug report to which visitors should be attached.
+/// \param IsArg Whether the statement is an argument to an inlined function.
+///              If this is the case, \p N \em must be the CallEnter node for
+///              the function.
+/// \param EnableNullFPSuppression Whether we should employ false positive
+///         suppression (inlined defensive checks, returned null).
+///
+/// \return Whether or not the function was able to add visitors for this
+///         statement. Note that returning \c true does not actually imply
+///         that any visitors were added.
+bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R,
+                           bool IsArg = false,
+                           bool EnableNullFPSuppression = true);
+
+const Expr *getDerefExpr(const Stmt *S);
+const Stmt *GetDenomExpr(const ExplodedNode *N);
+const Stmt *GetRetValExpr(const ExplodedNode *N);
+bool isDeclRefExprToReference(const Expr *E);
+
+
+} // end namespace clang
+} // end namespace ento
+} // end namespace bugreporter
+
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index 3e0913e..15b930b 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -15,7 +15,7 @@
 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H
 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H
 
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index fa7ee62..9fec217 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -19,7 +19,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
@@ -436,20 +436,7 @@
     return cast<FunctionDecl>(CallEvent::getDecl());
   }
 
-  RuntimeDefinition getRuntimeDefinition() const override {
-    const FunctionDecl *FD = getDecl();
-    // Note that the AnalysisDeclContext will have the FunctionDecl with
-    // the definition (if one exists).
-    if (FD) {
-      AnalysisDeclContext *AD =
-        getLocationContext()->getAnalysisDeclContext()->
-        getManager()->getContext(FD);
-      if (AD->getBody())
-        return RuntimeDefinition(AD->getDecl());
-    }
-
-    return RuntimeDefinition();
-  }
+  RuntimeDefinition getRuntimeDefinition() const override;
 
   bool argumentsMayEscape() const override;
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
index e380982..78d38a3 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h
@@ -196,6 +196,13 @@
     return getState()->getSVal(S, getLocationContext());
   }
 
+  /// \brief Returns true if the value of \p E is greater than or equal to \p
+  /// Val under unsigned comparison
+  bool isGreaterOrEqual(const Expr *E, unsigned long long Val);
+
+  /// Returns true if the value of \p E is negative.
+  bool isNegative(const Expr *E);
+
   /// \brief Generates a new transition in the program state graph
   /// (ExplodedGraph). Uses the default CheckerContext predecessor node.
   ///
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
index 12ec5b6..7472a71 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
@@ -16,7 +16,7 @@
 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_COREENGINE_H
 
 #include "clang/AST/Expr.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h"
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
index a66e1a1..c63ed4a 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
@@ -14,7 +14,7 @@
 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ENVIRONMENT_H
 
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 #include "llvm/ADT/ImmutableMap.h"
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
index a710ae6..dcea5e4 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h
@@ -20,14 +20,14 @@
 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_EXPLODEDGRAPH_H
 
 #include "clang/AST/Decl.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/ProgramPoint.h"
 #include "clang/Analysis/Support/BumpVector.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/GraphTraits.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
 #include <memory>
@@ -404,7 +404,7 @@
 };
 
 class ExplodedNodeSet {
-  typedef llvm::SmallPtrSet<ExplodedNode*,5> ImplTy;
+  typedef llvm::SmallSetVector<ExplodedNode*, 4> ImplTy;
   ImplTy Impl;
 
 public:
@@ -424,7 +424,7 @@
 
   unsigned size() const { return Impl.size();  }
   bool empty()    const { return Impl.empty(); }
-  bool erase(ExplodedNode *N) { return Impl.erase(N); }
+  bool erase(ExplodedNode *N) { return Impl.remove(N); }
 
   void clear() { Impl.clear(); }
   void insert(const ExplodedNodeSet &S) {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
index 067d706..ecff5c6 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -196,6 +196,8 @@
 
   void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
 
+  void ProcessLoopExit(const Stmt* S, ExplodedNode *Pred);
+
   void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
 
   void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h
new file mode 100644
index 0000000..a4c505c
--- /dev/null
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h
@@ -0,0 +1,50 @@
+//===--- LoopUnrolling.h - Unroll loops -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// This header contains the declarations of functions which are used to decide
+/// which loops should be completely unrolled and mark their corresponding
+/// CFGBlocks. It is done by tracking a stack of loops in the ProgramState. This
+/// way specific loops can be marked as completely unrolled. For considering a
+/// loop to be completely unrolled it has to fulfill the following requirements:
+/// - Currently only forStmts can be considered.
+/// - The bound has to be known.
+/// - The counter variable has not escaped before/in the body of the loop and
+///   changed only in the increment statement corresponding to the loop. It also
+///   has to be initialized by a literal in the corresponding initStmt.
+/// - Does not contain goto, switch and returnStmt.
+///
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPUNROLLING_H
+#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPUNROLLING_H
+
+#include "clang/Analysis/CFG.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
+namespace clang {
+namespace ento {
+class AnalysisManager;
+
+/// Returns if the given State indicates that is inside a completely unrolled
+/// loop.
+bool isUnrolledState(ProgramStateRef State);
+
+/// Updates the stack of loops contained by the ProgramState.
+ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx,
+                                ExplodedNode* Pred, unsigned maxVisitOnPath);
+
+/// Updates the given ProgramState. In current implementation it removes the top
+/// element of the stack of loops.
+ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State);
+
+} // end namespace ento
+} // end namespace clang
+
+#endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
index 29b1c4c..8ab6656 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
@@ -21,7 +21,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 #include "llvm/ADT/FoldingSet.h"
@@ -1412,21 +1412,18 @@
   bool hasTrait(SymbolRef Sym, InvalidationKinds IK) const;
   bool hasTrait(const MemRegion *MR, InvalidationKinds IK) const;
 };
-  
-} // end GR namespace
-
-} // end clang namespace
 
 //===----------------------------------------------------------------------===//
 // Pretty-printing regions.
 //===----------------------------------------------------------------------===//
-
-namespace llvm {
-static inline raw_ostream &operator<<(raw_ostream &os,
-                                      const clang::ento::MemRegion* R) {
+inline raw_ostream &operator<<(raw_ostream &os,
+                               const clang::ento::MemRegion *R) {
   R->dumpToStream(os);
   return os;
 }
-} // end llvm namespace
+
+} // namespace ento
+
+} // namespace clang
 
 #endif
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
index 935f001..0613258 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
@@ -103,9 +103,6 @@
     return *static_cast<const T *>(this);
   }
 
-  /// BufferTy - A temporary buffer to hold a set of SVals.
-  typedef SmallVector<SVal,5> BufferTy;
-
   inline unsigned getRawKind() const { return Kind; }
   inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); }
   inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; }
@@ -198,6 +195,10 @@
   }
 };
 
+inline raw_ostream &operator<<(raw_ostream &os, clang::ento::SVal V) {
+  V.dumpToStream(os);
+  return os;
+}
 
 class UndefinedVal : public SVal {
 public:
@@ -622,11 +623,6 @@
 } // end clang namespace
 
 namespace llvm {
-static inline raw_ostream &operator<<(raw_ostream &os,
-                                            clang::ento::SVal V) {
-  V.dumpToStream(os);
-  return os;
-}
 
 template <typename T> struct isPodLike;
 template <> struct isPodLike<clang::ento::SVal> {
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
index 7619f22..25d20a1 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
@@ -51,7 +51,7 @@
   virtual ~StoreManager() {}
 
   /// Return the value bound to specified location in a given state.
-  /// \param[in] store The analysis state.
+  /// \param[in] store The store in which to make the lookup.
   /// \param[in] loc The symbolic memory location.
   /// \param[in] T An optional type that provides a hint indicating the
   ///   expected type of the returned value.  This is used if the value is
@@ -83,12 +83,12 @@
     return getDefaultBinding(lcv.getStore(), lcv.getRegion());
   }
 
-  /// Return a state with the specified value bound to the given location.
-  /// \param[in] store The analysis state.
+  /// Return a store with the specified value bound to the given location.
+  /// \param[in] store The store in which to make the binding.
   /// \param[in] loc The symbolic memory location.
   /// \param[in] val The value to bind to location \c loc.
-  /// \return A pointer to a ProgramState object that contains the same
-  ///   bindings as \c state with the addition of having the value specified
+  /// \return A StoreRef object that contains the same
+  ///   bindings as \c store with the addition of having the value specified
   ///   by \c val bound to the location given for \c loc.
   virtual StoreRef Bind(Store store, Loc loc, SVal val) = 0;
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
index f720339..9780d01 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
@@ -98,6 +98,12 @@
   virtual const MemRegion *getOriginRegion() const { return nullptr; }
 };
 
+inline raw_ostream &operator<<(raw_ostream &os,
+                               const clang::ento::SymExpr *SE) {
+  SE->dumpToStream(os);
+  return os;
+}
+
 typedef const SymExpr *SymbolRef;
 typedef SmallVector<SymbolRef, 2> SymbolRefSmallVectorTy;
 
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
index e970114..7d2e5ad 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
@@ -17,7 +17,7 @@
 
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
@@ -633,11 +633,4 @@
 
 } // end clang namespace
 
-namespace llvm {
-static inline raw_ostream &operator<<(raw_ostream &os,
-                                      const clang::ento::SymExpr *SE) {
-  SE->dumpToStream(os);
-  return os;
-}
-} // end llvm namespace
 #endif
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..64b36e6
--- /dev/null
+++ b/lib/APINotes/APINotesReader.cpp
@@ -0,0 +1,1892 @@
+//===--- 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 (auto rawConvention = payload & 0x7) {
+      auto convention = static_cast<RetainCountConventionKind>(rawConvention-1);
+      info.setRetainCountConvention(convention);
+    }
+    payload >>= 3;
+    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);
+
+    uint8_t payload = endian::readNext<uint8_t, little, unaligned>(data);
+    if (auto rawConvention = payload & 0x7) {
+      auto convention = static_cast<RetainCountConventionKind>(rawConvention-1);
+      info.setRetainCountConvention(convention);
+    }
+    payload >>= 3;
+    info.NullabilityAudited = payload & 0x1;
+    payload >>= 1; assert(payload == 0 && "Bad API notes");
+
+    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..e0b6faf
--- /dev/null
+++ b/lib/APINotes/APINotesWriter.cpp
@@ -0,0 +1,1340 @@
+//===--- 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;
+    }
+    payload <<= 3;
+    if (auto retainCountConvention = info.getRetainCountConvention()) {
+      payload |= static_cast<uint8_t>(retainCountConvention.getValue()) + 1;
+    }
+    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);
+
+    uint8_t payload = 0;
+    payload |= info.NullabilityAudited;
+    payload <<= 3;
+    if (auto retainCountConvention = info.getRetainCountConvention()) {
+      payload |= static_cast<uint8_t>(retainCountConvention.getValue()) + 1;
+    }
+    writer.write<uint8_t>(payload);
+
+    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..c1e3420
--- /dev/null
+++ b/lib/APINotes/APINotesYAMLCompiler.cpp
@@ -0,0 +1,1533 @@
+//===--- 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;
+    Optional<NullabilityKind> Nullability;
+    Optional<api_notes::RetainCountConventionKind> RetainCountConvention;
+    StringRef Type;
+  };
+  typedef std::vector<Param> ParamsSeq;
+
+  struct Method {
+    StringRef Selector;
+    MethodKind Kind;
+    ParamsSeq Params;
+    NullabilitySeq Nullability;
+    Optional<NullabilityKind> NullabilityOfRet;
+    Optional<api_notes::RetainCountConventionKind> RetainCountConvention;
+    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;
+    Optional<NullabilityKind> NullabilityOfRet;
+    Optional<api_notes::RetainCountConventionKind> RetainCountConvention;
+    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 ScalarEnumerationTraits<api_notes::RetainCountConventionKind> {
+      static void enumeration(IO &io,
+                              api_notes::RetainCountConventionKind &value) {
+        using api_notes::RetainCountConventionKind;
+        io.enumCase(value, "none", RetainCountConventionKind::None);
+        io.enumCase(value, "CFReturnsRetained",
+                    RetainCountConventionKind::CFReturnsRetained);
+        io.enumCase(value, "CFReturnsNotRetained",
+                    RetainCountConventionKind::CFReturnsNotRetained);
+        io.enumCase(value, "NSReturnsRetained",
+                    RetainCountConventionKind::NSReturnsRetained);
+        io.enumCase(value, "NSReturnsNotRetained",
+                    RetainCountConventionKind::NSReturnsNotRetained);
+      }
+    };
+
+    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("RetainCountConvention", p.RetainCountConvention);
+        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("RetainCountConvention", m.RetainCountConvention);
+        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("RetainCountConvention", f.RetainCountConvention);
+        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);
+        pi.setRetainCountConvention(p.RetainCountConvention);
+        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);
+
+      mInfo.setRetainCountConvention(meth.RetainCountConvention);
+
+      // 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;
+        info.setRetainCountConvention(function.RetainCountConvention);
+        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());
+        p.RetainCountConvention = pi.getRetainCountConvention();
+        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);
+      method.RetainCountConvention = info.getRetainCountConvention();
+      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);
+      function.RetainCountConvention = info.getRetainCountConvention();
+      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/CMakeLists.txt b/lib/AST/CMakeLists.txt
index ab9b591..db771b5 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -20,6 +20,7 @@
   CommentLexer.cpp
   CommentParser.cpp
   CommentSema.cpp
+  DataCollection.cpp
   Decl.cpp
   DeclarationName.cpp
   DeclBase.cpp
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 403454d..6c2019e 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -813,7 +813,7 @@
 }
 
 bool Sema::isFunctionOrMethodVariadic() {
-  if (!isAnyFunctionDecl() && !isObjCMethodDecl() && !isFunctionTemplateDecl())
+  if (!isFunctionDecl() || !ThisDeclInfo->CurrentDecl)
     return false;
   if (const FunctionDecl *FD =
         dyn_cast<FunctionDecl>(ThisDeclInfo->CurrentDecl))
@@ -824,6 +824,14 @@
   if (const ObjCMethodDecl *MD =
         dyn_cast<ObjCMethodDecl>(ThisDeclInfo->CurrentDecl))
     return MD->isVariadic();
+  if (const TypedefNameDecl *TD =
+          dyn_cast<TypedefNameDecl>(ThisDeclInfo->CurrentDecl)) {
+    QualType Type = TD->getUnderlyingType();
+    if (Type->isFunctionPointerType() || Type->isBlockPointerType())
+      Type = Type->getPointeeType();
+    if (const auto *FT = Type->getAs<FunctionProtoType>())
+      return FT->isVariadic();
+  }
   return false;
 }
 
diff --git a/lib/AST/DataCollection.cpp b/lib/AST/DataCollection.cpp
new file mode 100644
index 0000000..c2ecabe
--- /dev/null
+++ b/lib/AST/DataCollection.cpp
@@ -0,0 +1,50 @@
+//===-- DataCollection.cpp --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DataCollection.h"
+
+#include "clang/Lex/Lexer.h"
+
+namespace clang {
+namespace data_collection {
+
+/// Prints the macro name that contains the given SourceLocation into the given
+/// raw_string_ostream.
+static void printMacroName(llvm::raw_string_ostream &MacroStack,
+                           ASTContext &Context, SourceLocation Loc) {
+  MacroStack << Lexer::getImmediateMacroName(Loc, Context.getSourceManager(),
+                                             Context.getLangOpts());
+
+  // Add an empty space at the end as a padding to prevent
+  // that macro names concatenate to the names of other macros.
+  MacroStack << " ";
+}
+
+/// Returns a string that represents all macro expansions that expanded into the
+/// given SourceLocation.
+///
+/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
+/// A and B are expanded from the same macros in the same order.
+std::string getMacroStack(SourceLocation Loc, ASTContext &Context) {
+  std::string MacroStack;
+  llvm::raw_string_ostream MacroStackStream(MacroStack);
+  SourceManager &SM = Context.getSourceManager();
+
+  // Iterate over all macros that expanded into the given SourceLocation.
+  while (Loc.isMacroID()) {
+    // Add the macro name to the stream.
+    printMacroName(MacroStackStream, Context, Loc);
+    Loc = SM.getImmediateMacroCallerLoc(Loc);
+  }
+  MacroStackStream.flush();
+  return MacroStack;
+}
+
+} // end namespace data_collection
+} // end namespace clang
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 573a98e..b39fb20 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -3958,9 +3958,9 @@
 
 bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
   ASTContext &Context = getASTContext();
-  if (!Context.getLangOpts().Sanitize.hasOneOf(
-          SanitizerKind::Address | SanitizerKind::KernelAddress) ||
-      !Context.getLangOpts().SanitizeAddressFieldPadding)
+  const SanitizerMask EnabledAsanMask = Context.getLangOpts().Sanitize.Mask &
+      (SanitizerKind::Address | SanitizerKind::KernelAddress);
+  if (!EnabledAsanMask || !Context.getLangOpts().SanitizeAddressFieldPadding)
     return false;
   const auto &Blacklist = Context.getSanitizerBlacklist();
   const auto *CXXRD = dyn_cast<CXXRecordDecl>(this);
@@ -3978,9 +3978,11 @@
     ReasonToReject = 4;  // has trivial destructor.
   else if (CXXRD->isStandardLayout())
     ReasonToReject = 5;  // is standard layout.
-  else if (Blacklist.isBlacklistedLocation(getLocation(), "field-padding"))
+  else if (Blacklist.isBlacklistedLocation(EnabledAsanMask, getLocation(),
+                                           "field-padding"))
     ReasonToReject = 6;  // is in a blacklisted file.
-  else if (Blacklist.isBlacklistedType(getQualifiedNameAsString(),
+  else if (Blacklist.isBlacklistedType(EnabledAsanMask,
+                                       getQualifiedNameAsString(),
                                        "field-padding"))
     ReasonToReject = 7;  // is blacklisted.
 
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/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 792e8cc..a596ba6 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1756,6 +1756,9 @@
       }
     }
     for (const auto *I : RD->fields()) {
+      if (I->isUnnamedBitfield())
+        continue;
+
       if (!CheckConstantExpression(Info, DiagLoc, I->getType(),
                                    Value.getStructField(I->getFieldIndex())))
         return false;
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/StmtDataCollectors.inc b/lib/AST/StmtDataCollectors.inc
new file mode 100644
index 0000000..b20e40d
--- /dev/null
+++ b/lib/AST/StmtDataCollectors.inc
@@ -0,0 +1,141 @@
+// The functions below collect the class specific data of each Stmt subclass.
+
+DEF_ADD_DATA(Stmt, {
+  addData(S->getStmtClass());
+  // This ensures that non-macro-generated code isn't identical to
+  // macro-generated code.
+  addData(data_collection::getMacroStack(S->getLocStart(), Context));
+  addData(data_collection::getMacroStack(S->getLocEnd(), Context));
+})
+DEF_ADD_DATA(Expr, { addData(S->getType()); })
+
+//--- Builtin functionality ----------------------------------------------//
+DEF_ADD_DATA(ArrayTypeTraitExpr, { addData(S->getTrait()); })
+DEF_ADD_DATA(ExpressionTraitExpr, { addData(S->getTrait()); })
+DEF_ADD_DATA(PredefinedExpr, { addData(S->getIdentType()); })
+DEF_ADD_DATA(TypeTraitExpr, {
+  addData(S->getTrait());
+  for (unsigned i = 0; i < S->getNumArgs(); ++i)
+    addData(S->getArg(i)->getType());
+})
+
+//--- Calls --------------------------------------------------------------//
+DEF_ADD_DATA(CallExpr, {
+  // Function pointers don't have a callee and we just skip hashing it.
+  if (const FunctionDecl *D = S->getDirectCallee()) {
+    // If the function is a template specialization, we also need to handle
+    // the template arguments as they are not included in the qualified name.
+    if (auto Args = D->getTemplateSpecializationArgs()) {
+      std::string ArgString;
+
+      // Print all template arguments into ArgString
+      llvm::raw_string_ostream OS(ArgString);
+      for (unsigned i = 0; i < Args->size(); ++i) {
+        Args->get(i).print(Context.getLangOpts(), OS);
+        // Add a padding character so that 'foo<X, XX>()' != 'foo<XX, X>()'.
+        OS << '\n';
+      }
+      OS.flush();
+
+      addData(ArgString);
+    }
+    addData(D->getQualifiedNameAsString());
+  }
+})
+
+//--- Value references ---------------------------------------------------//
+DEF_ADD_DATA(DeclRefExpr,
+             { addData(S->getDecl()->getQualifiedNameAsString()); })
+DEF_ADD_DATA(MemberExpr,
+             { addData(S->getMemberDecl()->getName()); })
+
+//--- Literals -----------------------------------------------------------//
+DEF_ADD_DATA(IntegerLiteral, { addData(llvm::hash_value(S->getValue())); })
+DEF_ADD_DATA(FloatingLiteral, { addData(llvm::hash_value(S->getValue())); })
+DEF_ADD_DATA(StringLiteral, { addData(S->getString()); })
+DEF_ADD_DATA(CXXBoolLiteralExpr, { addData(S->getValue()); })
+DEF_ADD_DATA(CharacterLiteral, { addData(S->getValue()); })
+
+//--- Exceptions ---------------------------------------------------------//
+DEF_ADD_DATA(CXXCatchStmt, { addData(S->getCaughtType()); })
+
+//--- C++ OOP Stmts ------------------------------------------------------//
+DEF_ADD_DATA(CXXDeleteExpr, {
+  addData(S->isArrayFormAsWritten());
+  addData(S->isGlobalDelete());
+})
+
+//--- Casts --------------------------------------------------------------//
+DEF_ADD_DATA(ObjCBridgedCastExpr, { addData(S->getBridgeKind()); })
+
+//--- Miscellaneous Exprs ------------------------------------------------//
+DEF_ADD_DATA(BinaryOperator, { addData(S->getOpcode()); })
+DEF_ADD_DATA(UnaryOperator, { addData(S->getOpcode()); })
+
+//--- Control flow -------------------------------------------------------//
+DEF_ADD_DATA(GotoStmt, { addData(S->getLabel()->getName()); })
+DEF_ADD_DATA(IndirectGotoStmt, {
+  if (S->getConstantTarget())
+    addData(S->getConstantTarget()->getName());
+})
+DEF_ADD_DATA(LabelStmt, { addData(S->getDecl()->getName()); })
+DEF_ADD_DATA(MSDependentExistsStmt, { addData(S->isIfExists()); })
+DEF_ADD_DATA(AddrLabelExpr, { addData(S->getLabel()->getName()); })
+
+//--- Objective-C --------------------------------------------------------//
+DEF_ADD_DATA(ObjCIndirectCopyRestoreExpr, { addData(S->shouldCopy()); })
+DEF_ADD_DATA(ObjCPropertyRefExpr, {
+  addData(S->isSuperReceiver());
+  addData(S->isImplicitProperty());
+})
+DEF_ADD_DATA(ObjCAtCatchStmt, { addData(S->hasEllipsis()); })
+
+//--- Miscellaneous Stmts ------------------------------------------------//
+DEF_ADD_DATA(CXXFoldExpr, {
+  addData(S->isRightFold());
+  addData(S->getOperator());
+})
+DEF_ADD_DATA(GenericSelectionExpr, {
+  for (unsigned i = 0; i < S->getNumAssocs(); ++i) {
+    addData(S->getAssocType(i));
+  }
+})
+DEF_ADD_DATA(LambdaExpr, {
+  for (const LambdaCapture &C : S->captures()) {
+    addData(C.isPackExpansion());
+    addData(C.getCaptureKind());
+    if (C.capturesVariable())
+      addData(C.getCapturedVar()->getType());
+  }
+  addData(S->isGenericLambda());
+  addData(S->isMutable());
+})
+DEF_ADD_DATA(DeclStmt, {
+  auto numDecls = std::distance(S->decl_begin(), S->decl_end());
+  addData(static_cast<unsigned>(numDecls));
+  for (const Decl *D : S->decls()) {
+    if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
+      addData(VD->getType());
+    }
+  }
+})
+DEF_ADD_DATA(AsmStmt, {
+  addData(S->isSimple());
+  addData(S->isVolatile());
+  addData(S->generateAsmString(Context));
+  for (unsigned i = 0; i < S->getNumInputs(); ++i) {
+    addData(S->getInputConstraint(i));
+  }
+  for (unsigned i = 0; i < S->getNumOutputs(); ++i) {
+    addData(S->getOutputConstraint(i));
+  }
+  for (unsigned i = 0; i < S->getNumClobbers(); ++i) {
+    addData(S->getClobber(i));
+  }
+})
+DEF_ADD_DATA(AttributedStmt, {
+  for (const Attr *A : S->getAttrs()) {
+    addData(std::string(A->getSpelling()));
+  }
+})
+#undef DEF_ADD_DATA
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 5ebaa32..7e77d2b 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);
@@ -1321,10 +1324,25 @@
         OS, Node->template_arguments(), Policy);
 }
 
+static bool isImplicitSelf(const Expr *E) {
+  if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
+    if (const ImplicitParamDecl *PD =
+            dyn_cast<ImplicitParamDecl>(DRE->getDecl())) {
+      if (PD->getParameterKind() == ImplicitParamDecl::ObjCSelf &&
+          DRE->getLocStart().isInvalid())
+        return true;
+    }
+  }
+  return false;
+}
+
 void StmtPrinter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
   if (Node->getBase()) {
-    PrintExpr(Node->getBase());
-    OS << (Node->isArrow() ? "->" : ".");
+    if (!Policy.SuppressImplicitBase ||
+        !isImplicitSelf(Node->getBase()->IgnoreImpCasts())) {
+      PrintExpr(Node->getBase());
+      OS << (Node->isArrow() ? "->" : ".");
+    }
   }
   OS << *Node->getDecl();
 }
@@ -1419,7 +1437,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 +1500,8 @@
 }
 
 void StmtPrinter::VisitFloatingLiteral(FloatingLiteral *Node) {
+  if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
+    return;
   PrintFloatingLiteral(OS, Node, /*PrintSuffix=*/true);
 }
 
@@ -1623,16 +1662,25 @@
   PrintCallArgs(Call);
   OS << ")";
 }
+
+static bool isImplicitThis(const Expr *E) {
+  if (const auto *TE = dyn_cast<CXXThisExpr>(E))
+    return TE->isImplicit();
+  return false;
+}
+
 void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
-  // FIXME: Suppress printing implicit bases (like "this")
-  PrintExpr(Node->getBase());
+  if (!Policy.SuppressImplicitBase || !isImplicitThis(Node->getBase())) {
+    PrintExpr(Node->getBase());
 
-  MemberExpr *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
-  FieldDecl  *ParentDecl   = ParentMember
-    ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl()) : nullptr;
+    MemberExpr *ParentMember = dyn_cast<MemberExpr>(Node->getBase());
+    FieldDecl *ParentDecl =
+        ParentMember ? dyn_cast<FieldDecl>(ParentMember->getMemberDecl())
+                     : nullptr;
 
-  if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
-    OS << (Node->isArrow() ? "->" : ".");
+    if (!ParentDecl || !ParentDecl->isAnonymousStructOrUnion())
+      OS << (Node->isArrow() ? "->" : ".");
+  }
 
   if (FieldDecl *FD = dyn_cast<FieldDecl>(Node->getMemberDecl()))
     if (FD->isAnonymousStructOrUnion())
@@ -2672,11 +2720,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/Analysis/AnalysisDeclContext.cpp b/lib/Analysis/AnalysisDeclContext.cpp
index ec15f34..181edff 100644
--- a/lib/Analysis/AnalysisDeclContext.cpp
+++ b/lib/Analysis/AnalysisDeclContext.cpp
@@ -12,8 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Analysis/AnalysisContext.h"
-#include "BodyFarm.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
@@ -23,6 +22,7 @@
 #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Analysis/Analyses/PseudoConstantAnalysis.h"
+#include "clang/Analysis/BodyFarm.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/CFGStmtMap.h"
 #include "clang/Analysis/Support/BumpVector.h"
@@ -63,33 +63,25 @@
   cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs;
 }
 
-AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG,
-                                                       bool addImplicitDtors,
-                                                       bool addInitializers,
-                                                       bool addTemporaryDtors,
-                                                       bool addLifetime,
-                                                       bool synthesizeBodies,
-                                                       bool addStaticInitBranch,
-                                                       bool addCXXNewAllocator,
-                                                       CodeInjector *injector)
-  : Injector(injector), SynthesizeBodies(synthesizeBodies)
-{
+AnalysisDeclContextManager::AnalysisDeclContextManager(
+    ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors,
+    bool addInitializers, bool addTemporaryDtors, bool addLifetime,
+    bool addLoopExit, bool synthesizeBodies, bool addStaticInitBranch,
+    bool addCXXNewAllocator, CodeInjector *injector)
+    : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
+      SynthesizeBodies(synthesizeBodies) {
   cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
   cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
   cfgBuildOptions.AddInitializers = addInitializers;
   cfgBuildOptions.AddTemporaryDtors = addTemporaryDtors;
   cfgBuildOptions.AddLifetime = addLifetime;
+  cfgBuildOptions.AddLoopExit = addLoopExit;
   cfgBuildOptions.AddStaticInitBranches = addStaticInitBranch;
   cfgBuildOptions.AddCXXNewAllocator = addCXXNewAllocator;
 }
 
 void AnalysisDeclContextManager::clear() { Contexts.clear(); }
 
-static BodyFarm &getBodyFarm(ASTContext &C, CodeInjector *injector = nullptr) {
-  static BodyFarm *BF = new BodyFarm(C, injector);
-  return *BF;
-}
-
 Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const {
   IsAutosynthesized = false;
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
@@ -97,8 +89,7 @@
     if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(Body))
       Body = CoroBody->getBody();
     if (Manager && Manager->synthesizeBodies()) {
-      Stmt *SynthesizedBody =
-          getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD);
+      Stmt *SynthesizedBody = Manager->getBodyFarm().getBody(FD);
       if (SynthesizedBody) {
         Body = SynthesizedBody;
         IsAutosynthesized = true;
@@ -109,8 +100,7 @@
   else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
     Stmt *Body = MD->getBody();
     if (Manager && Manager->synthesizeBodies()) {
-      Stmt *SynthesizedBody =
-          getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD);
+      Stmt *SynthesizedBody = Manager->getBodyFarm().getBody(MD);
       if (SynthesizedBody) {
         Body = SynthesizedBody;
         IsAutosynthesized = true;
@@ -315,6 +305,8 @@
   return AC.get();
 }
 
+BodyFarm &AnalysisDeclContextManager::getBodyFarm() { return FunctionBodyFarm; }
+
 const StackFrameContext *
 AnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S,
                                const CFGBlock *Blk, unsigned Idx) {
@@ -608,8 +600,6 @@
   }
 }
 
-AnalysisDeclContextManager::~AnalysisDeclContextManager() {}
-
 LocationContext::~LocationContext() {}
 
 LocationContextManager::~LocationContextManager() {
diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp
index 5912724..e5d3c5c 100644
--- a/lib/Analysis/BodyFarm.cpp
+++ b/lib/Analysis/BodyFarm.cpp
@@ -12,13 +12,20 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "BodyFarm.h"
+#include "clang/Analysis/BodyFarm.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
 #include "clang/Analysis/CodeInjector.h"
+#include "clang/Basic/OperatorKinds.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "body-farm"
 
 using namespace clang;
 
@@ -55,7 +62,8 @@
   CompoundStmt *makeCompound(ArrayRef<Stmt*>);
   
   /// Create a new DeclRefExpr for the referenced variable.
-  DeclRefExpr *makeDeclRefExpr(const VarDecl *D);
+  DeclRefExpr *makeDeclRefExpr(const VarDecl *D,
+                               bool RefersToEnclosingVariableOrCapture = false);
   
   /// Create a new UnaryOperator representing a dereference.
   UnaryOperator *makeDereference(const Expr *Arg, QualType Ty);
@@ -66,9 +74,19 @@
   /// Create an implicit cast to a builtin boolean type.
   ImplicitCastExpr *makeIntegralCastToBoolean(const Expr *Arg);
   
-  // Create an implicit cast for lvalue-to-rvaluate conversions.
+  /// Create an implicit cast for lvalue-to-rvaluate conversions.
   ImplicitCastExpr *makeLvalueToRvalue(const Expr *Arg, QualType Ty);
   
+  /// Make RValue out of variable declaration, creating a temporary
+  /// DeclRefExpr in the process.
+  ImplicitCastExpr *
+  makeLvalueToRvalue(const VarDecl *Decl,
+                     bool RefersToEnclosingVariableOrCapture = false);
+
+  /// Create an implicit cast of the given type.
+  ImplicitCastExpr *makeImplicitCast(const Expr *Arg, QualType Ty,
+                                     CastKind CK = CK_LValueToRValue);
+
   /// Create an Objective-C bool literal.
   ObjCBoolLiteralExpr *makeObjCBool(bool Val);
 
@@ -78,6 +96,18 @@
   /// Create a Return statement.
   ReturnStmt *makeReturn(const Expr *RetVal);
   
+  /// Create an integer literal expression of the given type.
+  IntegerLiteral *makeIntegerLiteral(uint64_t Value, QualType Ty);
+
+  /// Create a member expression.
+  MemberExpr *makeMemberExpression(Expr *base, ValueDecl *MemberDecl,
+                                   bool IsArrow = false,
+                                   ExprValueKind ValueKind = VK_LValue);
+
+  /// Returns a *first* member field of a record declaration with a given name.
+  /// \return an nullptr if no member with such a name exists.
+  ValueDecl *findMemberField(const RecordDecl *RD, StringRef Name);
+
 private:
   ASTContext &C;
 };
@@ -106,16 +136,14 @@
   return new (C) CompoundStmt(C, Stmts, SourceLocation(), SourceLocation());
 }
 
-DeclRefExpr *ASTMaker::makeDeclRefExpr(const VarDecl *D) {
-  DeclRefExpr *DR =
-    DeclRefExpr::Create(/* Ctx = */ C,
-                        /* QualifierLoc = */ NestedNameSpecifierLoc(),
-                        /* TemplateKWLoc = */ SourceLocation(),
-                        /* D = */ const_cast<VarDecl*>(D),
-                        /* RefersToEnclosingVariableOrCapture = */ false,
-                        /* NameLoc = */ SourceLocation(),
-                        /* T = */ D->getType(),
-                        /* VK = */ VK_LValue);
+DeclRefExpr *ASTMaker::makeDeclRefExpr(
+    const VarDecl *D,
+    bool RefersToEnclosingVariableOrCapture) {
+  QualType Type = D->getType().getNonReferenceType();
+
+  DeclRefExpr *DR = DeclRefExpr::Create(
+      C, NestedNameSpecifierLoc(), SourceLocation(), const_cast<VarDecl *>(D),
+      RefersToEnclosingVariableOrCapture, SourceLocation(), Type, VK_LValue);
   return DR;
 }
 
@@ -125,8 +153,25 @@
 }
 
 ImplicitCastExpr *ASTMaker::makeLvalueToRvalue(const Expr *Arg, QualType Ty) {
-  return ImplicitCastExpr::Create(C, Ty, CK_LValueToRValue,
-                                  const_cast<Expr*>(Arg), nullptr, VK_RValue);
+  return makeImplicitCast(Arg, Ty, CK_LValueToRValue);
+}
+
+ImplicitCastExpr *
+ASTMaker::makeLvalueToRvalue(const VarDecl *Arg,
+                             bool RefersToEnclosingVariableOrCapture) {
+  QualType Type = Arg->getType().getNonReferenceType();
+  return makeLvalueToRvalue(makeDeclRefExpr(Arg,
+                                            RefersToEnclosingVariableOrCapture),
+                            Type);
+}
+
+ImplicitCastExpr *ASTMaker::makeImplicitCast(const Expr *Arg, QualType Ty,
+                                             CastKind CK) {
+  return ImplicitCastExpr::Create(C, Ty,
+                                  /* CastKind=*/ CK,
+                                  /* Expr=*/ const_cast<Expr *>(Arg),
+                                  /* CXXCastPath=*/ nullptr,
+                                  /* ExprValueKind=*/ VK_RValue);
 }
 
 Expr *ASTMaker::makeIntegralCast(const Expr *Arg, QualType Ty) {
@@ -161,12 +206,259 @@
                             nullptr);
 }
 
+IntegerLiteral *ASTMaker::makeIntegerLiteral(uint64_t Value, QualType Ty) {
+  llvm::APInt APValue = llvm::APInt(C.getTypeSize(Ty), Value);
+  return IntegerLiteral::Create(C, APValue, Ty, SourceLocation());
+}
+
+MemberExpr *ASTMaker::makeMemberExpression(Expr *base, ValueDecl *MemberDecl,
+                                           bool IsArrow,
+                                           ExprValueKind ValueKind) {
+
+  DeclAccessPair FoundDecl = DeclAccessPair::make(MemberDecl, AS_public);
+  return MemberExpr::Create(
+      C, base, IsArrow, SourceLocation(), NestedNameSpecifierLoc(),
+      SourceLocation(), MemberDecl, FoundDecl,
+      DeclarationNameInfo(MemberDecl->getDeclName(), SourceLocation()),
+      /* TemplateArgumentListInfo=*/ nullptr, MemberDecl->getType(), ValueKind,
+      OK_Ordinary);
+}
+
+ValueDecl *ASTMaker::findMemberField(const RecordDecl *RD, StringRef Name) {
+
+  CXXBasePaths Paths(
+      /* FindAmbiguities=*/false,
+      /* RecordPaths=*/false,
+      /* DetectVirtual=*/ false);
+  const IdentifierInfo &II = C.Idents.get(Name);
+  DeclarationName DeclName = C.DeclarationNames.getIdentifier(&II);
+
+  DeclContextLookupResult Decls = RD->lookup(DeclName);
+  for (NamedDecl *FoundDecl : Decls)
+    if (!FoundDecl->getDeclContext()->isFunctionOrMethod())
+      return cast<ValueDecl>(FoundDecl);
+
+  return nullptr;
+}
+
 //===----------------------------------------------------------------------===//
 // Creation functions for faux ASTs.
 //===----------------------------------------------------------------------===//
 
 typedef Stmt *(*FunctionFarmer)(ASTContext &C, const FunctionDecl *D);
 
+static CallExpr *create_call_once_funcptr_call(ASTContext &C, ASTMaker M,
+                                               const ParmVarDecl *Callback,
+                                               ArrayRef<Expr *> CallArgs) {
+
+  QualType Ty = Callback->getType();
+  DeclRefExpr *Call = M.makeDeclRefExpr(Callback);
+  CastKind CK;
+  if (Ty->isRValueReferenceType()) {
+    CK = CK_LValueToRValue;
+  } else {
+    assert(Ty->isLValueReferenceType());
+    CK = CK_FunctionToPointerDecay;
+    Ty = C.getPointerType(Ty.getNonReferenceType());
+  }
+
+  return new (C)
+      CallExpr(C, M.makeImplicitCast(Call, Ty.getNonReferenceType(), CK),
+               /*args=*/CallArgs,
+               /*QualType=*/C.VoidTy,
+               /*ExprValueType=*/VK_RValue,
+               /*SourceLocation=*/SourceLocation());
+}
+
+static CallExpr *create_call_once_lambda_call(ASTContext &C, ASTMaker M,
+                                              const ParmVarDecl *Callback,
+                                              CXXRecordDecl *CallbackDecl,
+                                              ArrayRef<Expr *> CallArgs) {
+  assert(CallbackDecl != nullptr);
+  assert(CallbackDecl->isLambda());
+  FunctionDecl *callOperatorDecl = CallbackDecl->getLambdaCallOperator();
+  assert(callOperatorDecl != nullptr);
+
+  DeclRefExpr *callOperatorDeclRef =
+      DeclRefExpr::Create(/* Ctx =*/ C,
+                          /* QualifierLoc =*/ NestedNameSpecifierLoc(),
+                          /* TemplateKWLoc =*/ SourceLocation(),
+                          const_cast<FunctionDecl *>(callOperatorDecl),
+                          /* RefersToEnclosingVariableOrCapture=*/ false,
+                          /* NameLoc =*/ SourceLocation(),
+                          /* T =*/ callOperatorDecl->getType(),
+                          /* VK =*/ VK_LValue);
+
+  return new (C)
+      CXXOperatorCallExpr(/*AstContext=*/C, OO_Call, callOperatorDeclRef,
+                          /*args=*/CallArgs,
+                          /*QualType=*/C.VoidTy,
+                          /*ExprValueType=*/VK_RValue,
+                          /*SourceLocation=*/SourceLocation(), FPOptions());
+}
+
+/// Create a fake body for std::call_once.
+/// Emulates the following function body:
+///
+/// \code
+/// typedef struct once_flag_s {
+///   unsigned long __state = 0;
+/// } once_flag;
+/// template<class Callable>
+/// void call_once(once_flag& o, Callable func) {
+///   if (!o.__state) {
+///     func();
+///   }
+///   o.__state = 1;
+/// }
+/// \endcode
+static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) {
+  DEBUG(llvm::dbgs() << "Generating body for call_once\n");
+
+  // We need at least two parameters.
+  if (D->param_size() < 2)
+    return nullptr;
+
+  ASTMaker M(C);
+
+  const ParmVarDecl *Flag = D->getParamDecl(0);
+  const ParmVarDecl *Callback = D->getParamDecl(1);
+
+  if (!Callback->getType()->isReferenceType()) {
+    llvm::dbgs() << "libcxx03 std::call_once implementation, skipping.\n";
+    return nullptr;
+  }
+  if (!Flag->getType()->isReferenceType()) {
+    llvm::dbgs() << "unknown std::call_once implementation, skipping.\n";
+    return nullptr;
+  }
+
+  QualType CallbackType = Callback->getType().getNonReferenceType();
+
+  // Nullable pointer, non-null iff function is a CXXRecordDecl.
+  CXXRecordDecl *CallbackRecordDecl = CallbackType->getAsCXXRecordDecl();
+  QualType FlagType = Flag->getType().getNonReferenceType();
+  auto *FlagRecordDecl = dyn_cast_or_null<RecordDecl>(FlagType->getAsTagDecl());
+
+  if (!FlagRecordDecl) {
+    DEBUG(llvm::dbgs() << "Flag field is not a record: "
+                       << "unknown std::call_once implementation, "
+                       << "ignoring the call.\n");
+    return nullptr;
+  }
+
+  // We initially assume libc++ implementation of call_once,
+  // where the once_flag struct has a field `__state_`.
+  ValueDecl *FlagFieldDecl = M.findMemberField(FlagRecordDecl, "__state_");
+
+  // Otherwise, try libstdc++ implementation, with a field
+  // `_M_once`
+  if (!FlagFieldDecl) {
+    FlagFieldDecl = M.findMemberField(FlagRecordDecl, "_M_once");
+  }
+
+  if (!FlagFieldDecl) {
+    DEBUG(llvm::dbgs() << "No field _M_once or __state_ found on "
+                       << "std::once_flag struct: unknown std::call_once "
+                       << "implementation, ignoring the call.");
+    return nullptr;
+  }
+
+  bool isLambdaCall = CallbackRecordDecl && CallbackRecordDecl->isLambda();
+  if (CallbackRecordDecl && !isLambdaCall) {
+    DEBUG(llvm::dbgs() << "Not supported: synthesizing body for functors when "
+                       << "body farming std::call_once, ignoring the call.");
+    return nullptr;
+  }
+
+  SmallVector<Expr *, 5> CallArgs;
+  const FunctionProtoType *CallbackFunctionType;
+  if (isLambdaCall) {
+
+    // Lambda requires callback itself inserted as a first parameter.
+    CallArgs.push_back(
+        M.makeDeclRefExpr(Callback,
+                          /* RefersToEnclosingVariableOrCapture=*/ true));
+    CallbackFunctionType = CallbackRecordDecl->getLambdaCallOperator()
+                               ->getType()
+                               ->getAs<FunctionProtoType>();
+  } else if (!CallbackType->getPointeeType().isNull()) {
+    CallbackFunctionType =
+        CallbackType->getPointeeType()->getAs<FunctionProtoType>();
+  } else {
+    CallbackFunctionType = CallbackType->getAs<FunctionProtoType>();
+  }
+
+  if (!CallbackFunctionType)
+    return nullptr;
+
+  // First two arguments are used for the flag and for the callback.
+  if (D->getNumParams() != CallbackFunctionType->getNumParams() + 2) {
+    DEBUG(llvm::dbgs() << "Types of params of the callback do not match "
+                       << "params passed to std::call_once, "
+                       << "ignoring the call\n");
+    return nullptr;
+  }
+
+  // All arguments past first two ones are passed to the callback,
+  // and we turn lvalues into rvalues if the argument is not passed by
+  // reference.
+  for (unsigned int ParamIdx = 2; ParamIdx < D->getNumParams(); ParamIdx++) {
+    const ParmVarDecl *PDecl = D->getParamDecl(ParamIdx);
+    Expr *ParamExpr = M.makeDeclRefExpr(PDecl);
+    if (!CallbackFunctionType->getParamType(ParamIdx - 2)->isReferenceType()) {
+      QualType PTy = PDecl->getType().getNonReferenceType();
+      ParamExpr = M.makeLvalueToRvalue(ParamExpr, PTy);
+    }
+    CallArgs.push_back(ParamExpr);
+  }
+
+  CallExpr *CallbackCall;
+  if (isLambdaCall) {
+
+    CallbackCall = create_call_once_lambda_call(C, M, Callback,
+                                                CallbackRecordDecl, CallArgs);
+  } else {
+
+    // Function pointer case.
+    CallbackCall = create_call_once_funcptr_call(C, M, Callback, CallArgs);
+  }
+
+  DeclRefExpr *FlagDecl =
+      M.makeDeclRefExpr(Flag,
+                        /* RefersToEnclosingVariableOrCapture=*/true);
+
+
+  MemberExpr *Deref = M.makeMemberExpression(FlagDecl, FlagFieldDecl);
+  assert(Deref->isLValue());
+  QualType DerefType = Deref->getType();
+
+  // Negation predicate.
+  UnaryOperator *FlagCheck = new (C) UnaryOperator(
+      /* input=*/
+      M.makeImplicitCast(M.makeLvalueToRvalue(Deref, DerefType), DerefType,
+                         CK_IntegralToBoolean),
+      /* opc=*/ UO_LNot,
+      /* QualType=*/ C.IntTy,
+      /* ExprValueKind=*/ VK_RValue,
+      /* ExprObjectKind=*/ OK_Ordinary, SourceLocation());
+
+  // Create assignment.
+  BinaryOperator *FlagAssignment = M.makeAssignment(
+      Deref, M.makeIntegralCast(M.makeIntegerLiteral(1, C.IntTy), DerefType),
+      DerefType);
+
+  IfStmt *Out = new (C)
+      IfStmt(C, SourceLocation(),
+             /* IsConstexpr=*/ false,
+             /* init=*/ nullptr,
+             /* var=*/ nullptr,
+             /* cond=*/ FlagCheck,
+             /* then=*/ M.makeCompound({CallbackCall, FlagAssignment}));
+
+  return Out;
+}
+
 /// Create a fake body for dispatch_once.
 static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) {
   // Check if we have at least two parameters.
@@ -193,8 +485,8 @@
   // sets it, and calls the block.  Basically, an AST dump of:
   //
   // void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
-  //  if (!*predicate) {
-  //    *predicate = 1;
+  //  if (*predicate != ~0l) {
+  //    *predicate = ~0l;
   //    block();
   //  }
   // }
@@ -202,22 +494,26 @@
   ASTMaker M(C);
   
   // (1) Create the call.
-  DeclRefExpr *DR = M.makeDeclRefExpr(Block);
-  ImplicitCastExpr *ICE = M.makeLvalueToRvalue(DR, Ty);
-  CallExpr *CE = new (C) CallExpr(C, ICE, None, C.VoidTy, VK_RValue,
-                                  SourceLocation());
+  CallExpr *CE = new (C) CallExpr(
+      /*ASTContext=*/C,
+      /*StmtClass=*/M.makeLvalueToRvalue(/*Expr=*/Block),
+      /*args=*/None,
+      /*QualType=*/C.VoidTy,
+      /*ExprValueType=*/VK_RValue,
+      /*SourceLocation=*/SourceLocation());
 
   // (2) Create the assignment to the predicate.
-  IntegerLiteral *IL =
-    IntegerLiteral::Create(C, llvm::APInt(C.getTypeSize(C.IntTy), (uint64_t) 1),
-                           C.IntTy, SourceLocation());
+  Expr *DoneValue =
+      new (C) UnaryOperator(M.makeIntegerLiteral(0, C.LongTy), UO_Not, C.LongTy,
+                            VK_RValue, OK_Ordinary, SourceLocation());
+
   BinaryOperator *B =
     M.makeAssignment(
        M.makeDereference(
           M.makeLvalueToRvalue(
             M.makeDeclRefExpr(Predicate), PredicateQPtrTy),
             PredicateTy),
-       M.makeIntegralCast(IL, PredicateTy),
+       M.makeIntegralCast(DoneValue, PredicateTy),
        PredicateTy);
   
   // (3) Create the compound statement.
@@ -233,14 +529,15 @@
           PredicateQPtrTy),
         PredicateTy),
     PredicateTy);
-  
-  UnaryOperator *UO = new (C) UnaryOperator(LValToRval, UO_LNot, C.IntTy,
-                                           VK_RValue, OK_Ordinary,
-                                           SourceLocation());
-  
+
+  Expr *GuardCondition = M.makeComparison(LValToRval, DoneValue, BO_NE);
   // (5) Create the 'if' statement.
-  IfStmt *If = new (C) IfStmt(C, SourceLocation(), false, nullptr, nullptr,
-                              UO, CS);
+  IfStmt *If = new (C) IfStmt(C, SourceLocation(),
+                              /* IsConstexpr=*/ false,
+                              /* init=*/ nullptr,
+                              /* var=*/ nullptr,
+                              /* cond=*/ GuardCondition,
+                              /* then=*/ CS);
   return If;
 }
 
@@ -370,8 +667,9 @@
   if (Name.startswith("OSAtomicCompareAndSwap") ||
       Name.startswith("objc_atomicCompareAndSwap")) {
     FF = create_OSAtomicCompareAndSwap;
-  }
-  else {
+  } else if (Name == "call_once" && D->getDeclContext()->isStdNamespace()) {
+    FF = create_call_once;
+  } else {
     FF = llvm::StringSwitch<FunctionFarmer>(Name)
           .Case("dispatch_sync", create_dispatch_sync)
           .Case("dispatch_once", create_dispatch_once)
diff --git a/lib/Analysis/BodyFarm.h b/lib/Analysis/BodyFarm.h
deleted file mode 100644
index edbe996..0000000
--- a/lib/Analysis/BodyFarm.h
+++ /dev/null
@@ -1,51 +0,0 @@
-//== BodyFarm.h - Factory for conjuring up fake bodies -------------*- C++ -*-//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// BodyFarm is a factory for creating faux implementations for functions/methods
-// for analysis purposes.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
-#define LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H
-
-#include "clang/AST/DeclBase.h"
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
-
-namespace clang {
-
-class ASTContext;
-class FunctionDecl;
-class ObjCMethodDecl;
-class ObjCPropertyDecl;
-class Stmt;
-class CodeInjector;
-  
-class BodyFarm {
-public:
-  BodyFarm(ASTContext &C, CodeInjector *injector) : C(C), Injector(injector) {}
-  
-  /// Factory method for creating bodies for ordinary functions.
-  Stmt *getBody(const FunctionDecl *D);
-
-  /// Factory method for creating bodies for Objective-C properties.
-  Stmt *getBody(const ObjCMethodDecl *D);
-
-private:
-  typedef llvm::DenseMap<const Decl *, Optional<Stmt *> > BodyMap;
-
-  ASTContext &C;
-  BodyMap Bodies;
-  CodeInjector *Injector;
-};
-}
-
-#endif
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp
index 6a77455..c47a917 100644
--- a/lib/Analysis/CFG.cpp
+++ b/lib/Analysis/CFG.cpp
@@ -602,6 +602,7 @@
     return Visit(S, AddStmtChoice::AlwaysAdd);
   }
   CFGBlock *addInitializer(CXXCtorInitializer *I);
+  void addLoopExit(const Stmt *LoopStmt);
   void addAutomaticObjDtors(LocalScope::const_iterator B,
                             LocalScope::const_iterator E, Stmt *S);
   void addLifetimeEnds(LocalScope::const_iterator B,
@@ -652,6 +653,10 @@
     B->appendLifetimeEnds(VD, S, cfg->getBumpVectorContext());
   }
 
+  void appendLoopExit(CFGBlock *B, const Stmt *LoopStmt) {
+    B->appendLoopExit(LoopStmt, cfg->getBumpVectorContext());
+  }
+
   void appendDeleteDtor(CFGBlock *B, CXXRecordDecl *RD, CXXDeleteExpr *DE) {
     B->appendDeleteDtor(RD, DE, cfg->getBumpVectorContext());
   }
@@ -1253,6 +1258,16 @@
   return Init->getType();
 }
 
+
+// TODO: Support adding LoopExit element to the CFG in case where the loop is
+// ended by ReturnStmt, GotoStmt or ThrowExpr.
+void CFGBuilder::addLoopExit(const Stmt *LoopStmt){
+  if(!BuildOpts.AddLoopExit)
+    return;
+  autoCreateBlock();
+  appendLoopExit(Block, LoopStmt);
+}
+
 void CFGBuilder::addAutomaticObjHandling(LocalScope::const_iterator B,
                                          LocalScope::const_iterator E,
                                          Stmt *S) {
@@ -2543,6 +2558,8 @@
 
   addAutomaticObjHandling(ScopePos, save_scope_pos.get(), F);
 
+  addLoopExit(F);
+
   // "for" is a control-flow statement.  Thus we stop processing the current
   // block.
   if (Block) {
@@ -2882,6 +2899,7 @@
     addLocalScopeForVarDecl(VD);
     addAutomaticObjHandling(ScopePos, LoopBeginScopePos, W);
   }
+  addLoopExit(W);
 
   // "while" is a control-flow statement.  Thus we stop processing the current
   // block.
@@ -3045,6 +3063,8 @@
 CFGBlock *CFGBuilder::VisitDoStmt(DoStmt *D) {
   CFGBlock *LoopSuccessor = nullptr;
 
+  addLoopExit(D);
+
   // "do...while" is a control-flow statement.  Thus we stop processing the
   // current block.
   if (Block) {
@@ -4025,6 +4045,7 @@
     case CFGElement::Statement:
     case CFGElement::Initializer:
     case CFGElement::NewAllocator:
+    case CFGElement::LoopExit:
     case CFGElement::LifetimeEnds:
       llvm_unreachable("getDestructorDecl should only be used with "
                        "ImplicitDtors");
@@ -4442,6 +4463,9 @@
 
     OS << " (Lifetime ends)\n";
 
+  } else if (Optional<CFGLoopExit> LE = E.getAs<CFGLoopExit>()) {
+    const Stmt *LoopStmt = LE->getLoopStmt();
+    OS << LoopStmt->getStmtClassName() << " (LoopExit)\n";
   } else if (Optional<CFGNewAllocator> NE = E.getAs<CFGNewAllocator>()) {
     OS << "CFGNewAllocator(";
     if (const CXXNewExpr *AllocExpr = NE->getAllocatorExpr())
diff --git a/lib/Analysis/CloneDetection.cpp b/lib/Analysis/CloneDetection.cpp
index 5ea7498..acc1525 100644
--- a/lib/Analysis/CloneDetection.cpp
+++ b/lib/Analysis/CloneDetection.cpp
@@ -13,16 +13,12 @@
 
 #include "clang/Analysis/CloneDetection.h"
 
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/AST/Stmt.h"
-#include "clang/Lex/Lexer.h"
+#include "clang/AST/DataCollection.h"
+#include "clang/AST/DeclTemplate.h"
 #include "llvm/Support/MD5.h"
-#include "llvm/Support/raw_ostream.h"
 #include "llvm/Support/Path.h"
 
 using namespace clang;
-using namespace clang::clone_detection;
 
 StmtSequence::StmtSequence(const CompoundStmt *Stmt, const Decl *D,
                            unsigned StartIndex, unsigned EndIndex)
@@ -91,34 +87,6 @@
   return SourceRange(getStartLoc(), getEndLoc());
 }
 
-/// Prints the macro name that contains the given SourceLocation into the given
-/// raw_string_ostream.
-static void printMacroName(llvm::raw_string_ostream &MacroStack,
-                           ASTContext &Context, SourceLocation Loc) {
-  MacroStack << Lexer::getImmediateMacroName(Loc, Context.getSourceManager(),
-                                             Context.getLangOpts());
-
-  // Add an empty space at the end as a padding to prevent
-  // that macro names concatenate to the names of other macros.
-  MacroStack << " ";
-}
-
-std::string clone_detection::getMacroStack(SourceLocation Loc,
-                                           ASTContext &Context) {
-  std::string MacroStack;
-  llvm::raw_string_ostream MacroStackStream(MacroStack);
-  SourceManager &SM = Context.getSourceManager();
-
-  // Iterate over all macros that expanded into the given SourceLocation.
-  while (Loc.isMacroID()) {
-    // Add the macro name to the stream.
-    printMacroName(MacroStackStream, Context, Loc);
-    Loc = SM.getImmediateMacroCallerLoc(Loc);
-  }
-  MacroStackStream.flush();
-  return MacroStack;
-}
-
 void CloneDetector::analyzeCodeBody(const Decl *D) {
   assert(D);
   assert(D->hasBody());
@@ -184,16 +152,17 @@
   }
 }
 
-bool FilenamePatternConstraint::isAutoGenerated(const CloneDetector::CloneGroup &Group) {
+bool FilenamePatternConstraint::isAutoGenerated(
+    const CloneDetector::CloneGroup &Group) {
   std::string Error;
-  if (IgnoredFilesPattern.empty() || Group.empty() || 
+  if (IgnoredFilesPattern.empty() || Group.empty() ||
       !IgnoredFilesRegex->isValid(Error))
     return false;
 
   for (const StmtSequence &S : Group) {
     const SourceManager &SM = S.getASTContext().getSourceManager();
-    StringRef Filename = llvm::sys::path::filename(SM.getFilename(
-        S.getContainingDecl()->getLocation()));
+    StringRef Filename = llvm::sys::path::filename(
+        SM.getFilename(S.getContainingDecl()->getLocation()));
     if (IgnoredFilesRegex->match(Filename))
       return true;
   }
@@ -201,6 +170,59 @@
   return false;
 }
 
+/// This class defines what a type II code clone is: If it collects for two
+/// statements the same data, then those two statements are considered to be
+/// clones of each other.
+///
+/// All collected data is forwarded to the given data consumer of the type T.
+/// The data consumer class needs to provide a member method with the signature:
+///   update(StringRef Str)
+namespace {
+template <class T>
+class CloneTypeIIStmtDataCollector
+    : public ConstStmtVisitor<CloneTypeIIStmtDataCollector<T>> {
+  ASTContext &Context;
+  /// The data sink to which all data is forwarded.
+  T &DataConsumer;
+
+  template <class Ty> void addData(const Ty &Data) {
+    data_collection::addDataToConsumer(DataConsumer, Data);
+  }
+
+public:
+  CloneTypeIIStmtDataCollector(const Stmt *S, ASTContext &Context,
+                               T &DataConsumer)
+      : Context(Context), DataConsumer(DataConsumer) {
+    this->Visit(S);
+  }
+
+// Define a visit method for each class to collect data and subsequently visit
+// all parent classes. This uses a template so that custom visit methods by us
+// take precedence.
+#define DEF_ADD_DATA(CLASS, CODE)                                              \
+  template <class = void> void Visit##CLASS(const CLASS *S) {                  \
+    CODE;                                                                      \
+    ConstStmtVisitor<CloneTypeIIStmtDataCollector<T>>::Visit##CLASS(S);        \
+  }
+
+#include "../AST/StmtDataCollectors.inc"
+
+// Type II clones ignore variable names and literals, so let's skip them.
+#define SKIP(CLASS)                                                            \
+  void Visit##CLASS(const CLASS *S) {                                          \
+    ConstStmtVisitor<CloneTypeIIStmtDataCollector<T>>::Visit##CLASS(S);        \
+  }
+  SKIP(DeclRefExpr)
+  SKIP(MemberExpr)
+  SKIP(IntegerLiteral)
+  SKIP(FloatingLiteral)
+  SKIP(StringLiteral)
+  SKIP(CXXBoolLiteralExpr)
+  SKIP(CharacterLiteral)
+#undef SKIP
+};
+} // end anonymous namespace
+
 static size_t createHash(llvm::MD5 &Hash) {
   size_t HashCode;
 
@@ -216,13 +238,22 @@
   return HashCode;
 }
 
-size_t RecursiveCloneTypeIIConstraint::saveHash(
-    const Stmt *S, const Decl *D,
-    std::vector<std::pair<size_t, StmtSequence>> &StmtsByHash) {
+/// Generates and saves a hash code for the given Stmt.
+/// \param S The given Stmt.
+/// \param D The Decl containing S.
+/// \param StmtsByHash Output parameter that will contain the hash codes for
+///                    each StmtSequence in the given Stmt.
+/// \return The hash code of the given Stmt.
+///
+/// If the given Stmt is a CompoundStmt, this method will also generate
+/// hashes for all possible StmtSequences in the children of this Stmt.
+static size_t
+saveHash(const Stmt *S, const Decl *D,
+         std::vector<std::pair<size_t, StmtSequence>> &StmtsByHash) {
   llvm::MD5 Hash;
   ASTContext &Context = D->getASTContext();
 
-  StmtDataCollector<llvm::MD5>(S, Context, Hash);
+  CloneTypeIIStmtDataCollector<llvm::MD5>(S, Context, Hash);
 
   auto CS = dyn_cast<CompoundStmt>(S);
   SmallVector<size_t, 8> ChildHashes;
@@ -288,8 +319,8 @@
 static void CollectStmtSequenceData(const StmtSequence &Sequence,
                                     FoldingSetNodeIDWrapper &OutputData) {
   for (const Stmt *S : Sequence) {
-    StmtDataCollector<FoldingSetNodeIDWrapper>(S, Sequence.getASTContext(),
-                                               OutputData);
+    CloneTypeIIStmtDataCollector<FoldingSetNodeIDWrapper>(
+        S, Sequence.getASTContext(), OutputData);
 
     for (const Stmt *Child : S->children()) {
       if (!Child)
@@ -318,7 +349,7 @@
   return DataLHS == DataRHS;
 }
 
-void RecursiveCloneTypeIIConstraint::constrain(
+void RecursiveCloneTypeIIHashConstraint::constrain(
     std::vector<CloneDetector::CloneGroup> &Sequences) {
   // FIXME: Maybe we can do this in-place and don't need this additional vector.
   std::vector<CloneDetector::CloneGroup> Result;
@@ -339,7 +370,7 @@
     // Sort hash_codes in StmtsByHash.
     std::stable_sort(StmtsByHash.begin(), StmtsByHash.end(),
                      [](std::pair<size_t, StmtSequence> LHS,
-                            std::pair<size_t, StmtSequence> RHS) {
+                        std::pair<size_t, StmtSequence> RHS) {
                        return LHS.first < RHS.first;
                      });
 
@@ -359,8 +390,7 @@
 
       for (; i < StmtsByHash.size(); ++i) {
         // A different hash value means we have reached the end of the sequence.
-        if (PrototypeHash != StmtsByHash[i].first ||
-            !areSequencesClones(StmtsByHash[i].second, Current.second)) {
+        if (PrototypeHash != StmtsByHash[i].first) {
           // The current sequence could be the start of a new CloneGroup. So we
           // decrement i so that we visit it again in the outer loop.
           // Note: i can never be 0 at this point because we are just comparing
@@ -383,8 +413,17 @@
   Sequences = Result;
 }
 
+void RecursiveCloneTypeIIVerifyConstraint::constrain(
+    std::vector<CloneDetector::CloneGroup> &Sequences) {
+  CloneConstraint::splitCloneGroups(
+      Sequences, [](const StmtSequence &A, const StmtSequence &B) {
+        return areSequencesClones(A, B);
+      });
+}
+
 size_t MinComplexityConstraint::calculateStmtComplexity(
-    const StmtSequence &Seq, const std::string &ParentMacroStack) {
+    const StmtSequence &Seq, std::size_t Limit,
+    const std::string &ParentMacroStack) {
   if (Seq.empty())
     return 0;
 
@@ -393,8 +432,8 @@
   ASTContext &Context = Seq.getASTContext();
 
   // Look up what macros expanded into the current statement.
-  std::string StartMacroStack = getMacroStack(Seq.getStartLoc(), Context);
-  std::string EndMacroStack = getMacroStack(Seq.getEndLoc(), Context);
+  std::string MacroStack =
+      data_collection::getMacroStack(Seq.getStartLoc(), Context);
 
   // First, check if ParentMacroStack is not empty which means we are currently
   // dealing with a parent statement which was expanded from a macro.
@@ -404,8 +443,7 @@
   // macro expansion will only increase the total complexity by one.
   // Note: This is not the final complexity of this statement as we still
   // add the complexity of the child statements to the complexity value.
-  if (!ParentMacroStack.empty() && (StartMacroStack == ParentMacroStack &&
-                                    EndMacroStack == ParentMacroStack)) {
+  if (!ParentMacroStack.empty() && MacroStack == ParentMacroStack) {
     Complexity = 0;
   }
 
@@ -414,12 +452,16 @@
   if (Seq.holdsSequence()) {
     for (const Stmt *S : Seq) {
       Complexity += calculateStmtComplexity(
-          StmtSequence(S, Seq.getContainingDecl()), StartMacroStack);
+          StmtSequence(S, Seq.getContainingDecl()), Limit, MacroStack);
+      if (Complexity >= Limit)
+        return Limit;
     }
   } else {
     for (const Stmt *S : Seq.front()->children()) {
       Complexity += calculateStmtComplexity(
-          StmtSequence(S, Seq.getContainingDecl()), StartMacroStack);
+          StmtSequence(S, Seq.getContainingDecl()), Limit, MacroStack);
+      if (Complexity >= Limit)
+        return Limit;
     }
   }
   return Complexity;
@@ -437,7 +479,8 @@
 
 void CloneConstraint::splitCloneGroups(
     std::vector<CloneDetector::CloneGroup> &CloneGroups,
-    std::function<bool(const StmtSequence &, const StmtSequence &)> Compare) {
+    llvm::function_ref<bool(const StmtSequence &, const StmtSequence &)>
+        Compare) {
   std::vector<CloneDetector::CloneGroup> Result;
   for (auto &HashGroup : CloneGroups) {
     // Contains all indexes in HashGroup that were already added to a
diff --git a/lib/Analysis/Consumed.cpp b/lib/Analysis/Consumed.cpp
index f6fe78a..96edad0 100644
--- a/lib/Analysis/Consumed.cpp
+++ b/lib/Analysis/Consumed.cpp
@@ -22,7 +22,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/Type.h"
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/SourceLocation.h"
@@ -749,8 +749,7 @@
 
   // Special case for the std::move function.
   // TODO: Make this more specific. (Deferred)
-  if (Call->getNumArgs() == 1 && FunDecl->getNameAsString() == "move" &&
-      FunDecl->isInStdNamespace()) {
+  if (Call->isCallToStdMove()) {
     copyInfo(Call->getArg(0), Call, CS_Consumed);
     return;
   }
diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp
index cd73a62..4752c2b 100644
--- a/lib/Analysis/LiveVariables.cpp
+++ b/lib/Analysis/LiveVariables.cpp
@@ -15,7 +15,7 @@
 #include "clang/AST/Stmt.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/PostOrderIterator.h"
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index 60724ea..7e72795 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -18,7 +18,7 @@
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ParentMap.h"
 #include "clang/AST/StmtCXX.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Lex/Preprocessor.h"
diff --git a/lib/Analysis/ScanfFormatString.cpp b/lib/Analysis/ScanfFormatString.cpp
index 5342259..734dc75 100644
--- a/lib/Analysis/ScanfFormatString.cpp
+++ b/lib/Analysis/ScanfFormatString.cpp
@@ -251,8 +251,7 @@
         case LengthModifier::AsIntMax:
           return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
         case LengthModifier::AsSizeT:
-          // FIXME: ssize_t.
-          return ArgType();
+          return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
         case LengthModifier::AsPtrDiff:
           return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
         case LengthModifier::AsLongDouble:
@@ -386,7 +385,7 @@
         case LengthModifier::AsIntMax:
           return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
         case LengthModifier::AsSizeT:
-          return ArgType(); // FIXME: ssize_t
+          return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
         case LengthModifier::AsPtrDiff:
           return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
         case LengthModifier::AsLongDouble:
diff --git a/lib/Analysis/ThreadSafety.cpp b/lib/Analysis/ThreadSafety.cpp
index 879a15c..6a9c9a0 100644
--- a/lib/Analysis/ThreadSafety.cpp
+++ b/lib/Analysis/ThreadSafety.cpp
@@ -26,7 +26,7 @@
 #include "clang/Analysis/Analyses/ThreadSafetyLogical.h"
 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
 #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/CFGStmtMap.h"
 #include "clang/Basic/OperatorKinds.h"
@@ -1735,8 +1735,23 @@
         CapExprSet AssertLocks;
         Analyzer->getMutexIDs(AssertLocks, A, Exp, D, VD);
         for (const auto &AssertLock : AssertLocks)
-          Analyzer->addLock(FSet, llvm::make_unique<LockableFactEntry>(
-                                      AssertLock, LK_Shared, Loc, false, true),
+          Analyzer->addLock(FSet,
+                            llvm::make_unique<LockableFactEntry>(
+                                AssertLock, LK_Shared, Loc, false, true),
+                            ClassifyDiagnostic(A));
+        break;
+      }
+
+      case attr::AssertCapability: {
+        AssertCapabilityAttr *A = cast<AssertCapabilityAttr>(At);
+        CapExprSet AssertLocks;
+        Analyzer->getMutexIDs(AssertLocks, A, Exp, D, VD);
+        for (const auto &AssertLock : AssertLocks)
+          Analyzer->addLock(FSet,
+                            llvm::make_unique<LockableFactEntry>(
+                                AssertLock,
+                                A->isShared() ? LK_Shared : LK_Exclusive, Loc,
+                                false, true),
                             ClassifyDiagnostic(A));
         break;
       }
diff --git a/lib/Analysis/ThreadSafetyCommon.cpp b/lib/Analysis/ThreadSafetyCommon.cpp
index cbd5464..875f28c 100644
--- a/lib/Analysis/ThreadSafetyCommon.cpp
+++ b/lib/Analysis/ThreadSafetyCommon.cpp
@@ -19,7 +19,7 @@
 #include "clang/AST/StmtCXX.h"
 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
 #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/SourceLocation.h"
diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp
index d5289fb..5f11d8a 100644
--- a/lib/Analysis/UninitializedValues.cpp
+++ b/lib/Analysis/UninitializedValues.cpp
@@ -18,7 +18,7 @@
 #include "clang/AST/StmtVisitor.h"
 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
 #include "clang/Analysis/Analyses/UninitializedValues.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/DomainSpecific/ObjCNoReturn.h"
 #include "llvm/ADT/DenseMap.h"
@@ -440,16 +440,11 @@
 
 void ClassifyRefs::VisitCallExpr(CallExpr *CE) {
   // Classify arguments to std::move as used.
-  if (CE->getNumArgs() == 1) {
-    if (FunctionDecl *FD = CE->getDirectCallee()) {
-      if (FD->isInStdNamespace() && FD->getIdentifier() &&
-          FD->getIdentifier()->isStr("move")) {
-        // RecordTypes are handled in SemaDeclCXX.cpp.
-        if (!CE->getArg(0)->getType()->isRecordType())
-          classify(CE->getArg(0), Use);
-        return;
-      }
-    }
+  if (CE->isCallToStdMove()) {
+    // RecordTypes are handled in SemaDeclCXX.cpp.
+    if (!CE->getArg(0)->getType()->isRecordType())
+      classify(CE->getArg(0), Use);
+    return;
   }
 
   // If a value is passed by const pointer or by const reference to a function,
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index e971b55..b572af9 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -95,9 +95,11 @@
   OpenMPKinds.cpp
   OperatorPrecedence.cpp
   SanitizerBlacklist.cpp
+  SanitizerSpecialCaseList.cpp
   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/SanitizerBlacklist.cpp b/lib/Basic/SanitizerBlacklist.cpp
index de78c94..199ded1 100644
--- a/lib/Basic/SanitizerBlacklist.cpp
+++ b/lib/Basic/SanitizerBlacklist.cpp
@@ -17,30 +17,35 @@
 
 SanitizerBlacklist::SanitizerBlacklist(
     const std::vector<std::string> &BlacklistPaths, SourceManager &SM)
-    : SCL(llvm::SpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {}
+    : SSCL(SanitizerSpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {}
 
-bool SanitizerBlacklist::isBlacklistedGlobal(StringRef GlobalName,
+bool SanitizerBlacklist::isBlacklistedGlobal(SanitizerMask Mask,
+                                             StringRef GlobalName,
                                              StringRef Category) const {
-  return SCL->inSection("global", GlobalName, Category);
+  return SSCL->inSection(Mask, "global", GlobalName, Category);
 }
 
-bool SanitizerBlacklist::isBlacklistedType(StringRef MangledTypeName,
+bool SanitizerBlacklist::isBlacklistedType(SanitizerMask Mask,
+                                           StringRef MangledTypeName,
                                            StringRef Category) const {
-  return SCL->inSection("type", MangledTypeName, Category);
+  return SSCL->inSection(Mask, "type", MangledTypeName, Category);
 }
 
-bool SanitizerBlacklist::isBlacklistedFunction(StringRef FunctionName) const {
-  return SCL->inSection("fun", FunctionName);
+bool SanitizerBlacklist::isBlacklistedFunction(SanitizerMask Mask,
+                                               StringRef FunctionName) const {
+  return SSCL->inSection(Mask, "fun", FunctionName);
 }
 
-bool SanitizerBlacklist::isBlacklistedFile(StringRef FileName,
+bool SanitizerBlacklist::isBlacklistedFile(SanitizerMask Mask,
+                                           StringRef FileName,
                                            StringRef Category) const {
-  return SCL->inSection("src", FileName, Category);
+  return SSCL->inSection(Mask, "src", FileName, Category);
 }
 
-bool SanitizerBlacklist::isBlacklistedLocation(SourceLocation Loc,
+bool SanitizerBlacklist::isBlacklistedLocation(SanitizerMask Mask,
+                                               SourceLocation Loc,
                                                StringRef Category) const {
   return Loc.isValid() &&
-         isBlacklistedFile(SM.getFilename(SM.getFileLoc(Loc)), Category);
+         isBlacklistedFile(Mask, SM.getFilename(SM.getFileLoc(Loc)), Category);
 }
 
diff --git a/lib/Basic/SanitizerSpecialCaseList.cpp b/lib/Basic/SanitizerSpecialCaseList.cpp
new file mode 100644
index 0000000..4dd52ee
--- /dev/null
+++ b/lib/Basic/SanitizerSpecialCaseList.cpp
@@ -0,0 +1,64 @@
+//===--- SanitizerSpecialCaseList.cpp - SCL for sanitizers ----------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// An extension of SpecialCaseList to allowing querying sections by
+// SanitizerMask.
+//
+//===----------------------------------------------------------------------===//
+#include "clang/Basic/SanitizerSpecialCaseList.h"
+
+using namespace clang;
+
+std::unique_ptr<SanitizerSpecialCaseList>
+SanitizerSpecialCaseList::create(const std::vector<std::string> &Paths,
+                                 std::string &Error) {
+  std::unique_ptr<clang::SanitizerSpecialCaseList> SSCL(
+      new SanitizerSpecialCaseList());
+  if (SSCL->createInternal(Paths, Error)) {
+    SSCL->createSanitizerSections();
+    return SSCL;
+  }
+  return nullptr;
+}
+
+std::unique_ptr<SanitizerSpecialCaseList>
+SanitizerSpecialCaseList::createOrDie(const std::vector<std::string> &Paths) {
+  std::string Error;
+  if (auto SSCL = create(Paths, Error))
+    return SSCL;
+  llvm::report_fatal_error(Error);
+}
+
+void SanitizerSpecialCaseList::createSanitizerSections() {
+  for (auto &S : Sections) {
+    SanitizerMask Mask = 0;
+
+#define SANITIZER(NAME, ID)                                                    \
+  if (S.SectionMatcher->match(NAME))                                           \
+    Mask |= SanitizerKind::ID;
+#define SANITIZER_GROUP(NAME, ID, ALIAS) SANITIZER(NAME, ID)
+
+#include "clang/Basic/Sanitizers.def"
+#undef SANITIZER
+#undef SANITIZER_GROUP
+
+    SanitizerSections.emplace_back(Mask, S.Entries);
+  }
+}
+
+bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,
+                                         StringRef Query,
+                                         StringRef Category) const {
+  for (auto &S : SanitizerSections)
+    if ((S.Mask & Mask) &&
+        SpecialCaseList::inSection(S.Entries, Prefix, Query, Category))
+      return true;
+
+  return false;
+}
diff --git a/lib/Basic/SourceMgrAdapter.cpp b/lib/Basic/SourceMgrAdapter.cpp
new file mode 100644
index 0000000..c80112e
--- /dev/null
+++ b/lib/Basic/SourceMgrAdapter.cpp
@@ -0,0 +1,140 @@
+//=== 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_Remark:
+    llvm_unreachable("remarks not implemented");
+
+  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/Basic/XRayLists.cpp b/lib/Basic/XRayLists.cpp
index 0a439c7..462777d 100644
--- a/lib/Basic/XRayLists.cpp
+++ b/lib/Basic/XRayLists.cpp
@@ -26,11 +26,13 @@
 XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const {
   // First apply the always instrument list, than if it isn't an "always" see
   // whether it's treated as a "never" instrument function.
-  if (AlwaysInstrument->inSection("fun", FunctionName, "arg1"))
+  if (AlwaysInstrument->inSection("xray_always_instrument", "fun", FunctionName,
+                                  "arg1"))
     return ImbueAttribute::ALWAYS_ARG1;
-  if (AlwaysInstrument->inSection("fun", FunctionName))
+  if (AlwaysInstrument->inSection("xray_always_instrument", "fun",
+                                  FunctionName))
     return ImbueAttribute::ALWAYS;
-  if (NeverInstrument->inSection("fun", FunctionName))
+  if (NeverInstrument->inSection("xray_never_instrument", "fun", FunctionName))
     return ImbueAttribute::NEVER;
   return ImbueAttribute::NONE;
 }
@@ -38,9 +40,11 @@
 XRayFunctionFilter::ImbueAttribute
 XRayFunctionFilter::shouldImbueFunctionsInFile(StringRef Filename,
                                                StringRef Category) const {
-  if (AlwaysInstrument->inSection("src", Filename, Category))
+  if (AlwaysInstrument->inSection("xray_always_instrument", "src", Filename,
+                                  Category))
     return ImbueAttribute::ALWAYS;
-  if (NeverInstrument->inSection("src", Filename, Category))
+  if (NeverInstrument->inSection("xray_never_instrument", "src", Filename,
+                                 Category))
     return ImbueAttribute::NEVER;
   return ImbueAttribute::NONE;
 }
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..8ad9063 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,
@@ -1184,20 +1183,17 @@
                                                llvm::Value *arg) {
   assert(BlockInfo && "not emitting prologue of block invocation function?!");
 
-  llvm::Value *localAddr = nullptr;
-  if (CGM.getCodeGenOpts().OptimizationLevel == 0) {
-    // Allocate a stack slot to let the debug info survive the RA.
-    Address alloc = CreateMemTemp(D->getType(), D->getName() + ".addr");
-    Builder.CreateStore(arg, alloc);
-    localAddr = Builder.CreateLoad(alloc);
-  }
-
+  // Allocate a stack slot like for any local variable to guarantee optimal
+  // debug info at -O0. The mem2reg pass will eliminate it when optimizing.
+  Address alloc = CreateMemTemp(D->getType(), D->getName() + ".addr");
+  Builder.CreateStore(arg, alloc);
   if (CGDebugInfo *DI = getDebugInfo()) {
     if (CGM.getCodeGenOpts().getDebugInfo() >=
         codegenoptions::LimitedDebugInfo) {
       DI->setLocation(D->getLocation());
-      DI->EmitDeclareOfBlockLiteralArgVariable(*BlockInfo, arg, argNum,
-                                               localAddr, Builder);
+      DI->EmitDeclareOfBlockLiteralArgVariable(
+          *BlockInfo, D->getName(), argNum,
+          cast<llvm::AllocaInst>(alloc.getPointer()), Builder);
     }
   }
 
@@ -1225,7 +1221,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 +1281,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(),
@@ -1529,10 +1530,8 @@
 
   CGM.SetInternalFunctionAttributes(nullptr, Fn, FI);
 
-  auto NL = ApplyDebugLocation::CreateEmpty(*this);
   StartFunction(FD, C.VoidTy, Fn, FI, args);
-  // Create a scope with an artificial location for the body of this function.
-  auto AL = ApplyDebugLocation::CreateArtificial(*this);
+  ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getLocStart()};
   llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
 
   Address src = GetAddrOfLocalVar(&SrcDecl);
@@ -1701,10 +1700,8 @@
 
   CGM.SetInternalFunctionAttributes(nullptr, Fn, FI);
 
-  // Create a scope with an artificial location for the body of this function.
-  auto NL = ApplyDebugLocation::CreateEmpty(*this);
   StartFunction(FD, C.VoidTy, Fn, FI, args);
-  auto AL = ApplyDebugLocation::CreateArtificial(*this);
+  ApplyDebugLocation NL{*this, blockInfo.getBlockExpr()->getLocStart()};
 
   llvm::Type *structPtrTy = blockInfo.StructureType->getPointerTo();
 
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index f3527b0..dfcf320 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"
@@ -29,6 +30,7 @@
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/MDBuilder.h"
+#include "llvm/Support/ScopedPrinter.h"
 #include <sstream>
 
 using namespace clang;
@@ -641,6 +643,200 @@
 };
 }
 
+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;
+}
+
+/// Get the argument type for arguments to os_log_helper.
+static CanQualType getOSLogArgType(ASTContext &C, int Size) {
+  QualType UnsignedTy = C.getIntTypeForBitwidth(Size * 8, /*Signed=*/false);
+  return C.getCanonicalType(UnsignedTy);
+}
+
+llvm::Function *CodeGenFunction::generateBuiltinOSLogHelperFunction(
+    const analyze_os_log::OSLogBufferLayout &Layout,
+    CharUnits BufferAlignment) {
+  ASTContext &Ctx = getContext();
+
+  llvm::SmallString<64> Name;
+  {
+    raw_svector_ostream OS(Name);
+    OS << "__os_log_helper";
+    OS << "_" << BufferAlignment.getQuantity();
+    OS << "_" << int(Layout.getSummaryByte());
+    OS << "_" << int(Layout.getNumArgsByte());
+    for (const auto &Item : Layout.Items)
+      OS << "_" << int(Item.getSizeByte()) << "_"
+         << int(Item.getDescriptorByte());
+  }
+
+  if (llvm::Function *F = CGM.getModule().getFunction(Name))
+    return F;
+
+  llvm::SmallVector<ImplicitParamDecl, 4> Params;
+  Params.emplace_back(Ctx, nullptr, SourceLocation(), &Ctx.Idents.get("buffer"),
+                      Ctx.VoidPtrTy, ImplicitParamDecl::Other);
+
+  for (unsigned int I = 0, E = Layout.Items.size(); I < E; ++I) {
+    char Size = Layout.Items[I].getSizeByte();
+    if (!Size)
+      continue;
+
+    Params.emplace_back(
+        Ctx, nullptr, SourceLocation(),
+        &Ctx.Idents.get(std::string("arg") + llvm::to_string(I)),
+        getOSLogArgType(Ctx, Size), ImplicitParamDecl::Other);
+  }
+
+  FunctionArgList Args;
+  for (auto &P : Params)
+    Args.push_back(&P);
+
+  // The helper function has linkonce_odr linkage to enable the linker to merge
+  // identical functions. To ensure the merging always happens, 'noinline' is
+  // attached to the function when compiling with -Oz.
+  const CGFunctionInfo &FI =
+      CGM.getTypes().arrangeBuiltinFunctionDeclaration(Ctx.VoidTy, Args);
+  llvm::FunctionType *FuncTy = CGM.getTypes().GetFunctionType(FI);
+  llvm::Function *Fn = llvm::Function::Create(
+      FuncTy, llvm::GlobalValue::LinkOnceODRLinkage, Name, &CGM.getModule());
+  Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
+  CGM.SetLLVMFunctionAttributes(nullptr, FI, Fn);
+  CGM.SetLLVMFunctionAttributesForDefinition(nullptr, Fn);
+
+  // Attach 'noinline' at -Oz.
+  if (CGM.getCodeGenOpts().OptimizeSize == 2)
+    Fn->addFnAttr(llvm::Attribute::NoInline);
+
+  auto NL = ApplyDebugLocation::CreateEmpty(*this);
+  IdentifierInfo *II = &Ctx.Idents.get(Name);
+  FunctionDecl *FD = FunctionDecl::Create(
+      Ctx, Ctx.getTranslationUnitDecl(), SourceLocation(), SourceLocation(), II,
+      Ctx.VoidTy, nullptr, SC_PrivateExtern, false, false);
+
+  StartFunction(FD, Ctx.VoidTy, Fn, FI, Args);
+
+  // Create a scope with an artificial location for the body of this function.
+  auto AL = ApplyDebugLocation::CreateArtificial(*this);
+
+  CharUnits Offset;
+  Address BufAddr(Builder.CreateLoad(GetAddrOfLocalVar(&Params[0]), "buf"),
+                  BufferAlignment);
+  Builder.CreateStore(Builder.getInt8(Layout.getSummaryByte()),
+                      Builder.CreateConstByteGEP(BufAddr, Offset++, "summary"));
+  Builder.CreateStore(Builder.getInt8(Layout.getNumArgsByte()),
+                      Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs"));
+
+  unsigned I = 1;
+  for (const auto &Item : Layout.Items) {
+    Builder.CreateStore(
+        Builder.getInt8(Item.getDescriptorByte()),
+        Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor"));
+    Builder.CreateStore(
+        Builder.getInt8(Item.getSizeByte()),
+        Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize"));
+
+    CharUnits Size = Item.size();
+    if (!Size.getQuantity())
+      continue;
+
+    Address Arg = GetAddrOfLocalVar(&Params[I]);
+    Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset, "argData");
+    Addr = Builder.CreateBitCast(Addr, Arg.getPointer()->getType(),
+                                 "argDataCast");
+    Builder.CreateStore(Builder.CreateLoad(Arg), Addr);
+    Offset += Size;
+    ++I;
+  }
+
+  FinishFunction();
+
+  return Fn;
+}
+
+RValue CodeGenFunction::emitBuiltinOSLogFormat(const CallExpr &E) {
+  assert(E.getNumArgs() >= 2 &&
+         "__builtin_os_log_format takes at least 2 arguments");
+  ASTContext &Ctx = getContext();
+  analyze_os_log::OSLogBufferLayout Layout;
+  analyze_os_log::computeOSLogBufferLayout(Ctx, &E, Layout);
+  Address BufAddr = EmitPointerWithAlignment(E.getArg(0));
+  llvm::SmallVector<llvm::Value *, 4> RetainableOperands;
+
+  // Ignore argument 1, the format string. It is not currently used.
+  CallArgList Args;
+  Args.add(RValue::get(BufAddr.getPointer()), Ctx.VoidPtrTy);
+
+  for (const auto &Item : Layout.Items) {
+    int Size = Item.getSizeByte();
+    if (!Size)
+      continue;
+
+    llvm::Value *ArgVal;
+
+    if (const Expr *TheExpr = Item.getExpr()) {
+      ArgVal = EmitScalarExpr(TheExpr, /*Ignore*/ false);
+
+      // Check if this is a retainable type.
+      if (TheExpr->getType()->isObjCRetainableType()) {
+        assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar &&
+               "Only scalar can be a ObjC retainable type");
+        // Check if the object is constant, if not, save it in
+        // RetainableOperands.
+        if (!isa<Constant>(ArgVal))
+          RetainableOperands.push_back(ArgVal);
+      }
+    } else {
+      ArgVal = Builder.getInt32(Item.getConstValue().getQuantity());
+    }
+
+    unsigned ArgValSize =
+        CGM.getDataLayout().getTypeSizeInBits(ArgVal->getType());
+    llvm::IntegerType *IntTy = llvm::Type::getIntNTy(getLLVMContext(),
+                                                     ArgValSize);
+    ArgVal = Builder.CreateBitOrPointerCast(ArgVal, IntTy);
+    CanQualType ArgTy = getOSLogArgType(Ctx, Size);
+    // If ArgVal has type x86_fp80, zero-extend ArgVal.
+    ArgVal = Builder.CreateZExtOrBitCast(ArgVal, ConvertType(ArgTy));
+    Args.add(RValue::get(ArgVal), ArgTy);
+  }
+
+  const CGFunctionInfo &FI =
+      CGM.getTypes().arrangeBuiltinFunctionCall(Ctx.VoidTy, Args);
+  llvm::Function *F = CodeGenFunction(CGM).generateBuiltinOSLogHelperFunction(
+      Layout, BufAddr.getAlignment());
+  EmitCall(FI, CGCallee::forDirect(F), ReturnValueSlot(), Args);
+
+  // Push a clang.arc.use cleanup for each object in RetainableOperands. The
+  // cleanup will cause the use to appear after the final log call, keeping
+  // the object valid while it’s held in the log buffer.  Note that if there’s
+  // a release cleanup on the object, it will already be active; since
+  // cleanups are emitted in reverse order, the use will occur before the
+  // object is released.
+  if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount &&
+      CGM.getCodeGenOpts().OptimizationLevel != 0)
+    for (llvm::Value *Object : RetainableOperands)
+      pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), Object);
+
+  return RValue::get(BufAddr.getPointer());
+}
+
 RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
                                         unsigned BuiltinID, const CallExpr *E,
                                         ReturnValueSlot ReturnValue) {
@@ -660,7 +856,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 +988,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 +1005,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 +1542,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 +1552,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));
   }
@@ -2699,69 +2895,8 @@
     // Fall through - it's already mapped to the intrinsic by GCCBuiltin.
     break;
   }
-  case Builtin::BI__builtin_os_log_format: {
-    assert(E->getNumArgs() >= 2 &&
-           "__builtin_os_log_format takes at least 2 arguments");
-    analyze_os_log::OSLogBufferLayout Layout;
-    analyze_os_log::computeOSLogBufferLayout(CGM.getContext(), E, Layout);
-    Address BufAddr = EmitPointerWithAlignment(E->getArg(0));
-    // Ignore argument 1, the format string. It is not currently used.
-    CharUnits Offset;
-    Builder.CreateStore(
-        Builder.getInt8(Layout.getSummaryByte()),
-        Builder.CreateConstByteGEP(BufAddr, Offset++, "summary"));
-    Builder.CreateStore(
-        Builder.getInt8(Layout.getNumArgsByte()),
-        Builder.CreateConstByteGEP(BufAddr, Offset++, "numArgs"));
-
-    llvm::SmallVector<llvm::Value *, 4> RetainableOperands;
-    for (const auto &Item : Layout.Items) {
-      Builder.CreateStore(
-          Builder.getInt8(Item.getDescriptorByte()),
-          Builder.CreateConstByteGEP(BufAddr, Offset++, "argDescriptor"));
-      Builder.CreateStore(
-          Builder.getInt8(Item.getSizeByte()),
-          Builder.CreateConstByteGEP(BufAddr, Offset++, "argSize"));
-      Address Addr = Builder.CreateConstByteGEP(BufAddr, Offset);
-      if (const Expr *TheExpr = Item.getExpr()) {
-        Addr = Builder.CreateElementBitCast(
-            Addr, ConvertTypeForMem(TheExpr->getType()));
-        // Check if this is a retainable type.
-        if (TheExpr->getType()->isObjCRetainableType()) {
-          assert(getEvaluationKind(TheExpr->getType()) == TEK_Scalar &&
-                 "Only scalar can be a ObjC retainable type");
-          llvm::Value *SV = EmitScalarExpr(TheExpr, /*Ignore*/ false);
-          RValue RV = RValue::get(SV);
-          LValue LV = MakeAddrLValue(Addr, TheExpr->getType());
-          EmitStoreThroughLValue(RV, LV);
-          // Check if the object is constant, if not, save it in
-          // RetainableOperands.
-          if (!isa<Constant>(SV))
-            RetainableOperands.push_back(SV);
-        } else {
-          EmitAnyExprToMem(TheExpr, Addr, Qualifiers(), /*isInit*/ true);
-        }
-      } else {
-        Addr = Builder.CreateElementBitCast(Addr, Int32Ty);
-        Builder.CreateStore(
-            Builder.getInt32(Item.getConstValue().getQuantity()), Addr);
-      }
-      Offset += Item.size();
-    }
-
-    // Push a clang.arc.use cleanup for each object in RetainableOperands. The
-    // cleanup will cause the use to appear after the final log call, keeping
-    // the object valid while it's held in the log buffer.  Note that if there's
-    // a release cleanup on the object, it will already be active; since
-    // cleanups are emitted in reverse order, the use will occur before the
-    // object is released.
-    if (!RetainableOperands.empty() && getLangOpts().ObjCAutoRefCount &&
-        CGM.getCodeGenOpts().OptimizationLevel != 0)
-      for (llvm::Value *object : RetainableOperands)
-        pushFullExprCleanup<CallObjCArcUse>(getARCCleanupKind(), object);
-
-    return RValue::get(BufAddr.getPointer());
-  }
+  case Builtin::BI__builtin_os_log_format:
+    return emitBuiltinOSLogFormat(*E);
 
   case Builtin::BI__builtin_os_log_format_buffer_size: {
     analyze_os_log::OSLogBufferLayout Layout;
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/CGClass.cpp b/lib/CodeGen/CGClass.cpp
index 50d702c..d1f54bb 100644
--- a/lib/CodeGen/CGClass.cpp
+++ b/lib/CodeGen/CGClass.cpp
@@ -2604,28 +2604,34 @@
       !CGM.HasHiddenLTOVisibility(RD))
     return;
 
-  std::string TypeName = RD->getQualifiedNameAsString();
-  if (getContext().getSanitizerBlacklist().isBlacklistedType(TypeName))
-    return;
-
-  SanitizerScope SanScope(this);
+  SanitizerMask M;
   llvm::SanitizerStatKind SSK;
   switch (TCK) {
   case CFITCK_VCall:
+    M = SanitizerKind::CFIVCall;
     SSK = llvm::SanStat_CFI_VCall;
     break;
   case CFITCK_NVCall:
+    M = SanitizerKind::CFINVCall;
     SSK = llvm::SanStat_CFI_NVCall;
     break;
   case CFITCK_DerivedCast:
+    M = SanitizerKind::CFIDerivedCast;
     SSK = llvm::SanStat_CFI_DerivedCast;
     break;
   case CFITCK_UnrelatedCast:
+    M = SanitizerKind::CFIUnrelatedCast;
     SSK = llvm::SanStat_CFI_UnrelatedCast;
     break;
   case CFITCK_ICall:
     llvm_unreachable("not expecting CFITCK_ICall");
   }
+
+  std::string TypeName = RD->getQualifiedNameAsString();
+  if (getContext().getSanitizerBlacklist().isBlacklistedType(M, TypeName))
+    return;
+
+  SanitizerScope SanScope(this);
   EmitSanitizerStatReport(SSK);
 
   llvm::Metadata *MD =
@@ -2636,24 +2642,6 @@
   llvm::Value *TypeTest = Builder.CreateCall(
       CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, TypeId});
 
-  SanitizerMask M;
-  switch (TCK) {
-  case CFITCK_VCall:
-    M = SanitizerKind::CFIVCall;
-    break;
-  case CFITCK_NVCall:
-    M = SanitizerKind::CFINVCall;
-    break;
-  case CFITCK_DerivedCast:
-    M = SanitizerKind::CFIDerivedCast;
-    break;
-  case CFITCK_UnrelatedCast:
-    M = SanitizerKind::CFIUnrelatedCast;
-    break;
-  case CFITCK_ICall:
-    llvm_unreachable("not expecting CFITCK_ICall");
-  }
-
   llvm::Constant *StaticData[] = {
       llvm::ConstantInt::get(Int8Ty, TCK),
       EmitCheckSourceLocation(Loc),
@@ -2688,7 +2676,8 @@
     return false;
 
   std::string TypeName = RD->getQualifiedNameAsString();
-  return !getContext().getSanitizerBlacklist().isBlacklistedType(TypeName);
+  return !getContext().getSanitizerBlacklist().isBlacklistedType(
+      SanitizerKind::CFIVCall, TypeName);
 }
 
 llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 18b1d10..b3dad82 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) {
@@ -3655,9 +3659,9 @@
 }
 
 void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
-                                                       llvm::Value *Arg,
+                                                       StringRef Name,
                                                        unsigned ArgNo,
-                                                       llvm::Value *LocalAddr,
+                                                       llvm::AllocaInst *Alloca,
                                                        CGBuilderTy &Builder) {
   assert(DebugKind >= codegenoptions::LimitedDebugInfo);
   ASTContext &C = CGM.getContext();
@@ -3789,19 +3793,11 @@
 
   // Create the descriptor for the parameter.
   auto *debugVar = DBuilder.createParameterVariable(
-      scope, Arg->getName(), ArgNo, tunit, line, type,
+      scope, Name, ArgNo, tunit, line, type,
       CGM.getLangOpts().Optimize, flags);
 
-  if (LocalAddr) {
-    // Insert an llvm.dbg.value into the current block.
-    DBuilder.insertDbgValueIntrinsic(
-        LocalAddr, 0, debugVar, DBuilder.createExpression(),
-        llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
-        Builder.GetInsertBlock());
-  }
-
   // Insert an llvm.dbg.declare into the current block.
-  DBuilder.insertDeclare(Arg, debugVar, DBuilder.createExpression(),
+  DBuilder.insertDeclare(Alloca, debugVar, DBuilder.createExpression(),
                          llvm::DebugLoc::get(line, column, scope, CurInlinedAt),
                          Builder.GetInsertBlock());
 }
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 39249c7..25b8604 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -398,8 +398,8 @@
   /// Emit call to \c llvm.dbg.declare for the block-literal argument
   /// to a block invocation function.
   void EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
-                                            llvm::Value *Arg, unsigned ArgNo,
-                                            llvm::Value *LocalAddr,
+                                            StringRef Name, unsigned ArgNo,
+                                            llvm::AllocaInst *LocalAddr,
                                             CGBuilderTy &Builder);
 
   /// Emit information about a global variable.
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/CGDeclCXX.cpp b/lib/CodeGen/CGDeclCXX.cpp
index d8768be..2280657 100644
--- a/lib/CodeGen/CGDeclCXX.cpp
+++ b/lib/CodeGen/CGDeclCXX.cpp
@@ -278,17 +278,25 @@
   if (!getLangOpts().Exceptions)
     Fn->setDoesNotThrow();
 
-  if (!isInSanitizerBlacklist(Fn, Loc)) {
-    if (getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
-                                        SanitizerKind::KernelAddress))
-      Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
-    if (getLangOpts().Sanitize.has(SanitizerKind::Thread))
-      Fn->addFnAttr(llvm::Attribute::SanitizeThread);
-    if (getLangOpts().Sanitize.has(SanitizerKind::Memory))
-      Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
-    if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack))
-      Fn->addFnAttr(llvm::Attribute::SafeStack);
-  }
+  if (getLangOpts().Sanitize.has(SanitizerKind::Address) &&
+      !isInSanitizerBlacklist(SanitizerKind::Address, Fn, Loc))
+    Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) &&
+      !isInSanitizerBlacklist(SanitizerKind::KernelAddress, Fn, Loc))
+    Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::Thread) &&
+      !isInSanitizerBlacklist(SanitizerKind::Thread, Fn, Loc))
+    Fn->addFnAttr(llvm::Attribute::SanitizeThread);
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::Memory) &&
+      !isInSanitizerBlacklist(SanitizerKind::Memory, Fn, Loc))
+    Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
+
+  if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) &&
+      !isInSanitizerBlacklist(SanitizerKind::SafeStack, Fn, Loc))
+    Fn->addFnAttr(llvm::Attribute::SafeStack);
 
   return Fn;
 }
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 63c7b3d..a5d177b 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(
@@ -568,6 +569,19 @@
   return Builder.CreateMul(B1, KMul);
 }
 
+bool CodeGenFunction::isNullPointerAllowed(TypeCheckKind TCK) {
+  return TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
+         TCK == TCK_UpcastToVirtualBase;
+}
+
+bool CodeGenFunction::isVptrCheckRequired(TypeCheckKind TCK, QualType Ty) {
+  CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
+  return (RD && RD->hasDefinition() && RD->isDynamicClass()) &&
+         (TCK == TCK_MemberAccess || TCK == TCK_MemberCall ||
+          TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||
+          TCK == TCK_UpcastToVirtualBase);
+}
+
 bool CodeGenFunction::sanitizePerformTypeCheck() const {
   return SanOpts.has(SanitizerKind::Null) |
          SanOpts.has(SanitizerKind::Alignment) |
@@ -604,20 +618,22 @@
   auto PtrToAlloca =
       dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases());
 
-  bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
-                           TCK == TCK_UpcastToVirtualBase;
+  llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext());
+  llvm::Value *IsNonNull = nullptr;
+  bool IsGuaranteedNonNull =
+      SkippedChecks.has(SanitizerKind::Null) || PtrToAlloca;
+  bool AllowNullPointers = isNullPointerAllowed(TCK);
   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 =
-        IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext());
+    IsGuaranteedNonNull = IsNonNull == True;
 
     // 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.
@@ -652,6 +668,7 @@
   }
 
   uint64_t AlignVal = 0;
+  llvm::Value *PtrAsInt = nullptr;
 
   if (SanOpts.has(SanitizerKind::Alignment) &&
       !SkippedChecks.has(SanitizerKind::Alignment)) {
@@ -662,12 +679,13 @@
     // The glvalue must be suitably aligned.
     if (AlignVal > 1 &&
         (!PtrToAlloca || PtrToAlloca->getAlignment() < AlignVal)) {
-      llvm::Value *Align =
-          Builder.CreateAnd(Builder.CreatePtrToInt(Ptr, IntPtrTy),
-                            llvm::ConstantInt::get(IntPtrTy, AlignVal - 1));
+      PtrAsInt = Builder.CreatePtrToInt(Ptr, IntPtrTy);
+      llvm::Value *Align = Builder.CreateAnd(
+          PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal - 1));
       llvm::Value *Aligned =
-        Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
-      Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment));
+          Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
+      if (Aligned != True)
+        Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment));
     }
   }
 
@@ -679,7 +697,8 @@
         EmitCheckSourceLocation(Loc), EmitCheckTypeDescriptor(Ty),
         llvm::ConstantInt::get(Int8Ty, AlignVal ? llvm::Log2_64(AlignVal) : 1),
         llvm::ConstantInt::get(Int8Ty, TCK)};
-    EmitCheck(Checks, SanitizerHandler::TypeMismatch, StaticData, Ptr);
+    EmitCheck(Checks, SanitizerHandler::TypeMismatch, StaticData,
+              PtrAsInt ? PtrAsInt : Ptr);
   }
 
   // If possible, check that the vptr indicates that there is a subobject of
@@ -690,13 +709,20 @@
   //   The program has undefined behavior if:
   //    -- the [pointer or glvalue] is used to access a non-static data member
   //       or call a non-static member function
-  CXXRecordDecl *RD = Ty->getAsCXXRecordDecl();
   if (SanOpts.has(SanitizerKind::Vptr) &&
-      !SkippedChecks.has(SanitizerKind::Vptr) &&
-      (TCK == TCK_MemberAccess || TCK == TCK_MemberCall ||
-       TCK == TCK_DowncastPointer || TCK == TCK_DowncastReference ||
-       TCK == TCK_UpcastToVirtualBase) &&
-      RD && RD->hasDefinition() && RD->isDynamicClass()) {
+      !SkippedChecks.has(SanitizerKind::Vptr) && isVptrCheckRequired(TCK, Ty)) {
+    // 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
@@ -709,7 +735,7 @@
 
     // Blacklist based on the mangled type.
     if (!CGM.getContext().getSanitizerBlacklist().isBlacklistedType(
-            Out.str())) {
+            SanitizerKind::Vptr, Out.str())) {
       llvm::hash_code TypeHash = hash_value(Out.str());
 
       // Load the vptr, and compute hash_16_bytes(TypeHash, vptr).
@@ -1303,7 +1329,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 +1349,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(),
@@ -1412,17 +1458,17 @@
   if (!getRangeForType(*this, Ty, Min, End, /*StrictEnums=*/true, IsBool))
     return true;
 
+  auto &Ctx = getLLVMContext();
   SanitizerScope SanScope(this);
   llvm::Value *Check;
   --End;
   if (!Min) {
-    Check = Builder.CreateICmpULE(
-        Value, llvm::ConstantInt::get(getLLVMContext(), End));
+    Check = Builder.CreateICmpULE(Value, llvm::ConstantInt::get(Ctx, End));
   } else {
-    llvm::Value *Upper = Builder.CreateICmpSLE(
-        Value, llvm::ConstantInt::get(getLLVMContext(), End));
-    llvm::Value *Lower = Builder.CreateICmpSGE(
-        Value, llvm::ConstantInt::get(getLLVMContext(), Min));
+    llvm::Value *Upper =
+        Builder.CreateICmpSLE(Value, llvm::ConstantInt::get(Ctx, End));
+    llvm::Value *Lower =
+        Builder.CreateICmpSGE(Value, llvm::ConstantInt::get(Ctx, Min));
     Check = Builder.CreateAnd(Upper, Lower);
   }
   llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc),
@@ -2268,7 +2314,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.
 
@@ -2556,6 +2604,9 @@
 llvm::Value *CodeGenFunction::EmitCheckValue(llvm::Value *V) {
   llvm::Type *TargetTy = IntPtrTy;
 
+  if (V->getType() == TargetTy)
+    return V;
+
   // Floating-point types which fit into intptr_t are bitcast to integers
   // and then passed directly (after zero-extension, if necessary).
   if (V->getType()->isFloatingPointTy()) {
@@ -2685,13 +2736,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 +2832,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 =
@@ -3515,6 +3571,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;
@@ -3541,9 +3602,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);
 
@@ -4358,10 +4416,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);
 
@@ -4382,8 +4437,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..7d44bff 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -5084,6 +5084,11 @@
 
   // Drill down into arrays.
   uint64_t numElts = 1;
+  if (auto arrayType = CGM.getContext().getAsIncompleteArrayType(fieldType)) {
+    numElts = 0;
+    fieldType = arrayType->getElementType();
+  }
+  // Unlike incomplete arrays, constant arrays can be nested.
   while (auto arrayType = CGM.getContext().getAsConstantArrayType(fieldType)) {
     numElts *= arrayType->getSize().getZExtValue();
     fieldType = arrayType->getElementType();
@@ -7142,7 +7147,12 @@
   }
 
   assert(GV->getLinkage() == L);
-  return GV;
+
+  if (IsForDefinition ||
+      GV->getValueType() == ObjCTypes.ClassnfABITy)
+    return GV;
+
+  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ClassnfABIPtrTy);
 }
 
 llvm::Value *
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index ef9ef19..2280f47 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -2452,7 +2452,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};
@@ -3353,14 +3353,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()) {
@@ -3864,7 +3864,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));
@@ -4550,8 +4551,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,
@@ -4562,11 +4563,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,
@@ -7050,7 +7052,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);
@@ -7770,3 +7772,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 185c01d..897e809 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.
@@ -1328,6 +1333,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 cf430f8..84af53e 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;
 }
@@ -2731,6 +2752,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(
@@ -2762,7 +2784,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(
@@ -3073,7 +3096,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/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp
index 4f03de5..54cbf9e 100644
--- a/lib/CodeGen/CodeGenAction.cpp
+++ b/lib/CodeGen/CodeGenAction.cpp
@@ -46,6 +46,32 @@
 using namespace llvm;
 
 namespace clang {
+  class BackendConsumer;
+  class ClangDiagnosticHandler final : public DiagnosticHandler {
+  public:
+    ClangDiagnosticHandler(const CodeGenOptions &CGOpts, BackendConsumer *BCon)
+        : CodeGenOpts(CGOpts), BackendCon(BCon) {}
+
+    bool handleDiagnostics(const DiagnosticInfo &DI) override;
+
+    bool isAnalysisRemarkEnabled(StringRef PassName) const override {
+      return (CodeGenOpts.OptimizationRemarkAnalysisPattern &&
+              CodeGenOpts.OptimizationRemarkAnalysisPattern->match(PassName));
+    }
+    bool isMissedOptRemarkEnabled(StringRef PassName) const override {
+      return (CodeGenOpts.OptimizationRemarkMissedPattern &&
+              CodeGenOpts.OptimizationRemarkMissedPattern->match(PassName));
+    }
+    bool isPassedOptRemarkEnabled(StringRef PassName) const override {
+      return (CodeGenOpts.OptimizationRemarkPattern &&
+              CodeGenOpts.OptimizationRemarkPattern->match(PassName));
+    }
+
+  private:
+    const CodeGenOptions &CodeGenOpts;
+    BackendConsumer *BackendCon;
+  };
+
   class BackendConsumer : public ASTConsumer {
     using LinkModule = CodeGenAction::LinkModule;
 
@@ -224,10 +250,10 @@
       void *OldContext = Ctx.getInlineAsmDiagnosticContext();
       Ctx.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, this);
 
-      LLVMContext::DiagnosticHandlerTy OldDiagnosticHandler =
+      std::unique_ptr<DiagnosticHandler> OldDiagnosticHandler =
           Ctx.getDiagnosticHandler();
-      void *OldDiagnosticContext = Ctx.getDiagnosticContext();
-      Ctx.setDiagnosticHandler(DiagnosticHandler, this);
+      Ctx.setDiagnosticHandler(llvm::make_unique<ClangDiagnosticHandler>(
+        CodeGenOpts, this));
       Ctx.setDiagnosticsHotnessRequested(CodeGenOpts.DiagnosticsWithHotness);
       if (CodeGenOpts.DiagnosticsHotnessThreshold != 0)
         Ctx.setDiagnosticsHotnessThreshold(
@@ -264,7 +290,7 @@
 
       Ctx.setInlineAsmDiagnosticHandler(OldHandler, OldContext);
 
-      Ctx.setDiagnosticHandler(OldDiagnosticHandler, OldDiagnosticContext);
+      Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler));
 
       if (OptRecordFile)
         OptRecordFile->keep();
@@ -299,11 +325,6 @@
       ((BackendConsumer*)Context)->InlineAsmDiagHandler2(SM, Loc);
     }
 
-    static void DiagnosticHandler(const llvm::DiagnosticInfo &DI,
-                                  void *Context) {
-      ((BackendConsumer *)Context)->DiagnosticHandlerImpl(DI);
-    }
-
     /// Get the best possible source location to represent a diagnostic that
     /// may have associated debug info.
     const FullSourceLoc
@@ -343,6 +364,11 @@
   void BackendConsumer::anchor() {}
 }
 
+bool ClangDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) {
+  BackendCon->DiagnosticHandlerImpl(DI);
+  return true;
+}
+
 /// ConvertBackendLocation - Convert a location in a temporary llvm::SourceMgr
 /// buffer to be a valid FullSourceLoc.
 static FullSourceLoc ConvertBackendLocation(const llvm::SMDiagnostic &D,
@@ -402,6 +428,8 @@
   case llvm::SourceMgr::DK_Note:
     DiagID = diag::note_fe_inline_asm;
     break;
+  case llvm::SourceMgr::DK_Remark:
+    llvm_unreachable("remarks unexpected");
   }
   // If this problem has clang-level source location information, report the
   // issue in the source with a note showing the instantiated
@@ -884,6 +912,8 @@
   case llvm::SourceMgr::DK_Note:
     DiagID = diag::note_fe_inline_asm;
     break;
+  case llvm::SourceMgr::DK_Remark:
+    llvm_unreachable("remarks unexpected");
   }
 
   Diags->Report(DiagID).AddString("cannot compile inline asm");
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp
index c23b25e..15383a2 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.
@@ -721,6 +758,15 @@
   Fn->removeFnAttr(llvm::Attribute::SanitizeThread);
 }
 
+/// Return the UBSan prologue signature for \p FD if one is available.
+static llvm::Constant *getPrologueSignature(CodeGenModule &CGM,
+                                            const FunctionDecl *FD) {
+  if (const auto *MD = dyn_cast<CXXMethodDecl>(FD))
+    if (!MD->isStatic())
+      return nullptr;
+  return CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM);
+}
+
 void CodeGenFunction::StartFunction(GlobalDecl GD,
                                     QualType RetTy,
                                     llvm::Function *Fn,
@@ -744,8 +790,19 @@
   CurFnInfo = &FnInfo;
   assert(CurFn->isDeclaration() && "Function already has body?");
 
-  if (CGM.isInSanitizerBlacklist(Fn, Loc))
-    SanOpts.clear();
+  // If this function has been blacklisted for any of the enabled sanitizers,
+  // disable the sanitizer for the function.
+  do {
+#define SANITIZER(NAME, ID)                                                    \
+  if (SanOpts.empty())                                                         \
+    break;                                                                     \
+  if (SanOpts.has(SanitizerKind::ID))                                          \
+    if (CGM.isInSanitizerBlacklist(SanitizerKind::ID, Fn, Loc))                \
+      SanOpts.set(SanitizerKind::ID, false);
+
+#include "clang/Basic/Sanitizers.def"
+#undef SANITIZER
+  } while (0);
 
   if (D) {
     // Apply the no_sanitize* attributes to SanOpts.
@@ -817,11 +874,13 @@
   // prologue data.
   if (getLangOpts().CPlusPlus && SanOpts.has(SanitizerKind::Function)) {
     if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
-      if (llvm::Constant *PrologueSig =
-              CGM.getTargetCodeGenInfo().getUBSanFunctionSignature(CGM)) {
+      if (llvm::Constant *PrologueSig = getPrologueSignature(CGM, FD)) {
         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 6a1fa48..c4017d1 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -76,6 +76,10 @@
 class ObjCAtSynchronizedStmt;
 class ObjCAutoreleasePoolStmt;
 
+namespace analyze_os_log {
+class OSLogBufferLayout;
+}
+
 namespace CodeGen {
 class CodeGenTypes;
 class CGCallee;
@@ -111,6 +115,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 +1588,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 +1780,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.
@@ -1816,8 +1831,7 @@
   /// TypeOfSelfObject - Return type of object that this self represents.
   QualType TypeOfSelfObject();
 
-  /// hasAggregateLLVMType - Return true if the specified AST type will map into
-  /// an aggregate LLVM type or is void.
+  /// getEvaluationKind - Return the TypeEvaluationKind of QualType \c T.
   static TypeEvaluationKind getEvaluationKind(QualType T);
 
   static bool hasScalarEvaluationKind(QualType T) {
@@ -2345,6 +2359,12 @@
     TCK_NonnullAssign
   };
 
+  /// Determine whether the pointer type check \p TCK permits null pointers.
+  static bool isNullPointerAllowed(TypeCheckKind TCK);
+
+  /// Determine whether the pointer type check \p TCK requires a vptr check.
+  static bool isVptrCheckRequired(TypeCheckKind TCK, QualType Ty);
+
   /// \brief Whether any type-checking sanitizers are enabled. If \c false,
   /// calls to EmitTypeCheck can be skipped.
   bool sanitizePerformTypeCheck() const;
@@ -3159,6 +3179,7 @@
   };
 
   ConstantEmission tryEmitAsConstant(DeclRefExpr *refExpr);
+  ConstantEmission tryEmitAsConstant(const MemberExpr *ME);
 
   RValue EmitPseudoObjectRValue(const PseudoObjectExpr *e,
                                 AggValueSlot slot = AggValueSlot::ignored());
@@ -3286,6 +3307,13 @@
                          unsigned BuiltinID, const CallExpr *E,
                          ReturnValueSlot ReturnValue);
 
+  /// Emit IR for __builtin_os_log_format.
+  RValue emitBuiltinOSLogFormat(const CallExpr &E);
+
+  llvm::Function *generateBuiltinOSLogHelperFunction(
+      const analyze_os_log::OSLogBufferLayout &Layout,
+      CharUnits BufferAlignment);
+
   RValue EmitBlockCallExpr(const CallExpr *E, ReturnValueSlot ReturnValue);
 
   /// EmitTargetBuiltinExpr - Emit the given builtin call. Returns 0 if the call
@@ -3607,6 +3635,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..9436b02 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"
@@ -1530,20 +1531,21 @@
     Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation()));
 }
 
-bool CodeGenModule::isInSanitizerBlacklist(llvm::Function *Fn,
+bool CodeGenModule::isInSanitizerBlacklist(SanitizerMask Kind,
+                                           llvm::Function *Fn,
                                            SourceLocation Loc) const {
   const auto &SanitizerBL = getContext().getSanitizerBlacklist();
   // Blacklist by function name.
-  if (SanitizerBL.isBlacklistedFunction(Fn->getName()))
+  if (SanitizerBL.isBlacklistedFunction(Kind, Fn->getName()))
     return true;
   // Blacklist by location.
   if (Loc.isValid())
-    return SanitizerBL.isBlacklistedLocation(Loc);
+    return SanitizerBL.isBlacklistedLocation(Kind, Loc);
   // If location is unknown, this may be a compiler-generated function. Assume
   // it's located in the main file.
   auto &SM = Context.getSourceManager();
   if (const auto *MainFile = SM.getFileEntryForID(SM.getMainFileID())) {
-    return SanitizerBL.isBlacklistedFile(MainFile->getName());
+    return SanitizerBL.isBlacklistedFile(Kind, MainFile->getName());
   }
   return false;
 }
@@ -1552,13 +1554,14 @@
                                            SourceLocation Loc, QualType Ty,
                                            StringRef Category) const {
   // For now globals can be blacklisted only in ASan and KASan.
-  if (!LangOpts.Sanitize.hasOneOf(
-          SanitizerKind::Address | SanitizerKind::KernelAddress))
+  const SanitizerMask EnabledAsanMask = LangOpts.Sanitize.Mask &
+      (SanitizerKind::Address | SanitizerKind::KernelAddress);
+  if (!EnabledAsanMask)
     return false;
   const auto &SanitizerBL = getContext().getSanitizerBlacklist();
-  if (SanitizerBL.isBlacklistedGlobal(GV->getName(), Category))
+  if (SanitizerBL.isBlacklistedGlobal(EnabledAsanMask, GV->getName(), Category))
     return true;
-  if (SanitizerBL.isBlacklistedLocation(Loc, Category))
+  if (SanitizerBL.isBlacklistedLocation(EnabledAsanMask, Loc, Category))
     return true;
   // Check global type.
   if (!Ty.isNull()) {
@@ -1570,7 +1573,7 @@
     // We allow to blacklist only record types (classes, structs etc.)
     if (Ty->isRecordType()) {
       std::string TypeStr = Ty.getAsString(getContext().getPrintingPolicy());
-      if (SanitizerBL.isBlacklistedType(TypeStr, Category))
+      if (SanitizerBL.isBlacklistedType(EnabledAsanMask, TypeStr, Category))
         return true;
     }
   }
@@ -2678,6 +2681,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 +2703,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 +2817,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 +3735,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 +3771,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 +4540,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..d3dad5c 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,
@@ -1124,7 +1103,8 @@
   /// annotations are emitted during finalization of the LLVM code.
   void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV);
 
-  bool isInSanitizerBlacklist(llvm::Function *Fn, SourceLocation Loc) const;
+  bool isInSanitizerBlacklist(SanitizerMask Kind, llvm::Function *Fn,
+                              SourceLocation Loc) const;
 
   bool isInSanitizerBlacklist(llvm::GlobalVariable *GV, SourceLocation Loc,
                               QualType Ty,
@@ -1355,6 +1335,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..6e0099b 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.
@@ -397,6 +445,9 @@
   /// expressions cross file or macro boundaries.
   SourceLocation MostRecentLocation;
 
+  /// Location of the last terminated region.
+  Optional<std::pair<SourceLocation, size_t>> LastTerminatedRegion;
+
   /// \brief Return a counter for the subtraction of \c RHS from \c LHS
   Counter subtractCounters(Counter LHS, Counter RHS) {
     return Builder.subtract(LHS, RHS);
@@ -424,19 +475,84 @@
   /// 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.
+    FileID StartFile = SM.getFileID(DR.getStartLoc());
+    if (SM.getFileID(DeferredEndLoc) != StartFile) {
+      if (isNestedIn(DeferredEndLoc, StartFile)) {
+        do {
+          DeferredEndLoc = getIncludeOrExpansionLoc(DeferredEndLoc);
+        } while (StartFile != SM.getFileID(DeferredEndLoc));
+      } else {
+        return Index;
+      }
+    }
+
+    // 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;
+  }
+
+  /// Complete a deferred region created after a terminated region at the
+  /// top-level.
+  void completeTopLevelDeferredRegion(Counter Count,
+                                      SourceLocation DeferredEndLoc) {
+    if (DeferredRegion || !LastTerminatedRegion)
+      return;
+
+    if (LastTerminatedRegion->second != RegionStack.size())
+      return;
+
+    SourceLocation Start = LastTerminatedRegion->first;
+    if (SM.getFileID(Start) != SM.getMainFileID())
+      return;
+
+    SourceMappingRegion DR = RegionStack.back();
+    DR.setStartLoc(Start);
+    DR.setDeferred(false);
+    DeferredRegion = DR;
+    completeDeferred(Count, DeferredEndLoc);
+  }
+
   /// \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 +584,32 @@
 
         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.
+              !EndLoc.isMacroID())
+            DeferredRegion =
+                SourceMappingRegion(Counter::getZero(), EndLoc, None);
+        }
+      } else if (Region.isDeferred()) {
+        assert(!ParentOfDeferredRegion && "Consecutive deferred regions");
+        ParentOfDeferredRegion = true;
       }
       RegionStack.pop_back();
+
+      // If the zero region pushed after the last terminated region no longer
+      // exists, clear its cached information.
+      if (LastTerminatedRegion &&
+          RegionStack.size() < LastTerminatedRegion->second)
+        LastTerminatedRegion = None;
     }
+    assert(!ParentOfDeferredRegion && "Deferred region with no parent");
   }
 
   /// \brief Return the currently active region.
@@ -481,15 +620,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,15 +736,34 @@
     handleFileExit(StartLoc);
     if (!Region.hasStartLoc())
       Region.setStartLoc(StartLoc);
+
+    completeDeferred(Region.getCounter(), StartLoc);
   }
 
   /// \brief Mark \c S as a terminator, starting a zero region.
   void terminateRegion(const Stmt *S) {
     extendRegion(S);
     SourceMappingRegion &Region = getRegion();
+    SourceLocation EndLoc = getEnd(S);
     if (!Region.hasEndLoc())
-      Region.setEndLoc(getEnd(S));
+      Region.setEndLoc(EndLoc);
     pushRegion(Counter::getZero());
+    auto &ZeroRegion = getRegion();
+    ZeroRegion.setDeferred(true);
+    LastTerminatedRegion = {EndLoc, RegionStack.size()};
+  }
+
+  /// Emit a gap region between \p StartLoc and \p EndLoc with the given count.
+  void fillGapAreaWithCount(SourceLocation StartLoc, SourceLocation EndLoc,
+                            Counter Count) {
+    if (StartLoc == EndLoc || StartLoc.isMacroID() || EndLoc.isMacroID() ||
+        !SM.isWrittenInSameFile(StartLoc, EndLoc))
+      return;
+    handleFileExit(StartLoc);
+    size_t Index = pushRegion(Count, StartLoc, EndLoc);
+    getRegion().setGap(true);
+    handleFileExit(EndLoc);
+    popRegions(Index);
   }
 
   /// \brief Keep counts of breaks and continues inside loops.
@@ -617,13 +777,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();
 
@@ -644,14 +806,42 @@
     handleFileExit(getEnd(S));
   }
 
+  /// Determine whether the final deferred region emitted in \p Body should be
+  /// discarded.
+  static bool discardFinalDeferredRegionInDecl(Stmt *Body) {
+    if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
+      Stmt *LastStmt = CS->body_back();
+      if (auto *IfElse = dyn_cast<IfStmt>(LastStmt)) {
+        if (auto *Else = dyn_cast_or_null<CompoundStmt>(IfElse->getElse()))
+          LastStmt = Else->body_back();
+        else
+          LastStmt = IfElse->getElse();
+      }
+      return dyn_cast_or_null<ReturnStmt>(LastStmt);
+    }
+    return false;
+  }
+
   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");
+
+    if (DeferredRegion) {
+      // Complete (or discard) any deferred regions introduced by the last
+      // statement.
+      if (discardFinalDeferredRegionInDecl(Body))
+        DeferredRegion = None;
+      else
+        popRegions(completeDeferred(ExitCount, getEnd(Body)));
+    }
   }
 
   void VisitReturnStmt(const ReturnStmt *S) {
@@ -671,10 +861,12 @@
   void VisitGotoStmt(const GotoStmt *S) { terminateRegion(S); }
 
   void VisitLabelStmt(const LabelStmt *S) {
+    Counter LabelCount = getRegionCounter(S);
     SourceLocation Start = getStart(S);
+    completeTopLevelDeferredRegion(LabelCount, Start);
     // We can't extendRegion here or we risk overlapping with our new region.
     handleFileExit(Start);
-    pushRegion(getRegionCounter(S), Start);
+    pushRegion(LabelCount, Start);
     Visit(S->getSubStmt());
   }
 
@@ -682,6 +874,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 +886,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 +1027,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
@@ -889,12 +1098,19 @@
     // counter for the body when looking at the coverage.
     propagateCounts(ParentCount, S->getCond());
 
+    // The 'then' count applies to the area immediately after the condition.
+    fillGapAreaWithCount(getPreciseTokenLocEnd(getEnd(S->getCond())),
+                         getStart(S->getThen()), ThenCount);
+
     extendRegion(S->getThen());
     Counter OutCount = propagateCounts(ThenCount, S->getThen());
 
     Counter ElseCount = subtractCounters(ParentCount, ThenCount);
     if (const Stmt *Else = S->getElse()) {
-      extendRegion(S->getElse());
+      // The 'else' count applies to the area immediately after the 'then'.
+      fillGapAreaWithCount(getPreciseTokenLocEnd(getEnd(S->getThen())),
+                           getStart(Else), ElseCount);
+      extendRegion(Else);
       OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
     } else
       OutCount = addCounters(OutCount, ElseCount);
@@ -931,25 +1147,32 @@
     Visit(E->getCond());
 
     if (!isa<BinaryConditionalOperator>(E)) {
+      // The 'then' count applies to the area immediately after the condition.
+      fillGapAreaWithCount(E->getQuestionLoc(), getStart(E->getTrueExpr()),
+                           TrueCount);
+
       extendRegion(E->getTrueExpr());
       propagateCounts(TrueCount, E->getTrueExpr());
     }
+
     extendRegion(E->getFalseExpr());
     propagateCounts(subtractCounters(ParentCount, TrueCount),
                     E->getFalseExpr());
   }
 
   void VisitBinLAnd(const BinaryOperator *E) {
-    extendRegion(E);
-    Visit(E->getLHS());
+    extendRegion(E->getLHS());
+    propagateCounts(getRegion().getCounter(), E->getLHS());
+    handleFileExit(getEnd(E->getLHS()));
 
     extendRegion(E->getRHS());
     propagateCounts(getRegionCounter(E), E->getRHS());
   }
 
   void VisitBinLOr(const BinaryOperator *E) {
-    extendRegion(E);
-    Visit(E->getLHS());
+    extendRegion(E->getLHS());
+    propagateCounts(getRegion().getCounter(), E->getLHS());
+    handleFileExit(getEnd(E->getLHS()));
 
     extendRegion(E->getRHS());
     propagateCounts(getRegionCounter(E), E->getRHS());
@@ -992,6 +1215,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..8e6b98b 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);
   }
 
@@ -6211,7 +6195,7 @@
     return occupiesMoreThan(CGT, scalars, /*total*/ 4);
   }
   bool isSwiftErrorInRegister() const override {
-    return true;
+    return false;
   }
 };
 
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/Compilation.cpp b/lib/Driver/Compilation.cpp
index cf86644..176f0c6 100644
--- a/lib/Driver/Compilation.cpp
+++ b/lib/Driver/Compilation.cpp
@@ -167,16 +167,51 @@
   return ExecutionFailed ? 1 : Res;
 }
 
-void Compilation::ExecuteJobs(
-    const JobList &Jobs,
-    SmallVectorImpl<std::pair<int, const Command *>> &FailingCommands) const {
+using FailingCommandList = SmallVectorImpl<std::pair<int, const Command *>>;
+
+static bool ActionFailed(const Action *A,
+                         const FailingCommandList &FailingCommands) {
+
+  if (FailingCommands.empty())
+    return false;
+
+  // CUDA can have the same input source code compiled multiple times so do not
+  // compiled again if there are already failures. It is OK to abort the CUDA
+  // pipeline on errors.
+  if (A->isOffloading(Action::OFK_Cuda))
+    return true;
+
+  for (const auto &CI : FailingCommands)
+    if (A == &(CI.second->getSource()))
+      return true;
+
+  for (const Action *AI : A->inputs())
+    if (ActionFailed(AI, FailingCommands))
+      return true;
+
+  return false;
+}
+
+static bool InputsOk(const Command &C,
+                     const FailingCommandList &FailingCommands) {
+  return !ActionFailed(&C.getSource(), FailingCommands);
+}
+
+void Compilation::ExecuteJobs(const JobList &Jobs,
+                              FailingCommandList &FailingCommands) const {
+  // According to UNIX standard, driver need to continue compiling all the
+  // inputs on the command line even one of them failed.
+  // In all but CLMode, execute all the jobs unless the necessary inputs for the
+  // job is missing due to previous failures.
   for (const auto &Job : Jobs) {
+    if (!InputsOk(Job, FailingCommands))
+      continue;
     const Command *FailingCommand = nullptr;
     if (int Res = ExecuteCommand(Job, FailingCommand)) {
       FailingCommands.push_back(std::make_pair(Res, FailingCommand));
-      // Bail as soon as one command fails, so we don't output duplicate error
-      // messages if we die on e.g. the same file.
-      return;
+      // Bail as soon as one command fails in cl driver mode.
+      if (TheDriver.IsCLMode())
+        return;
     }
   }
 }
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..4f41fa9 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);
@@ -168,7 +172,7 @@
   return ((Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
           CoverageFeatures) &&
          !Sanitizers.has(Address) && !Sanitizers.has(Memory) &&
-         !Sanitizers.has(Thread) && !Sanitizers.has(DataFlow) && 
+         !Sanitizers.has(Thread) && !Sanitizers.has(DataFlow) &&
          !Sanitizers.has(Leak) && !CfiCrossDso;
 }
 
@@ -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) {
@@ -552,10 +594,13 @@
       !(CoverageFeatures & InsertionPointTypes))
     CoverageFeatures |= CoverageEdge;
 
+  SharedRuntime =
+      Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
+                   TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() ||
+                       TC.getTriple().isOSDarwin());
+
   if (AllAddedKinds & Address) {
-    AsanSharedRuntime =
-        Args.hasArg(options::OPT_shared_libasan) || TC.getTriple().isAndroid();
-    NeedPIE |= TC.getTriple().isAndroid();
+    NeedPIE |= TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia();
     if (Arg *A =
             Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
         StringRef S = A->getValue();
@@ -589,7 +634,7 @@
     // globals in ASan is disabled by default on ELF targets.
     // See https://sourceware.org/bugzilla/show_bug.cgi?id=19002
     AsanGlobalsDeadStripping =
-        !TC.getTriple().isOSBinFormatELF() ||
+        !TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSFuchsia() ||
         Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
   } else {
     AsanUseAfterScope = false;
@@ -736,6 +781,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..150198e 100644
--- a/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/lib/Driver/ToolChains/CommonArgs.cpp
@@ -538,26 +538,35 @@
                          SmallVectorImpl<StringRef> &RequiredSymbols) {
   const SanitizerArgs &SanArgs = TC.getSanitizerArgs();
   // Collect shared runtimes.
-  if (SanArgs.needsAsanRt() && SanArgs.needsSharedAsanRt()) {
-    SharedRuntimes.push_back("asan");
+  if (SanArgs.needsSharedRt()) {
+    if (SanArgs.needsAsanRt()) {
+      SharedRuntimes.push_back("asan");
+      if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
+        HelperStaticRuntimes.push_back("asan-preinit");
+    }
+
+    if (SanArgs.needsUbsanRt()) {
+      if (SanArgs.requiresMinimalRuntime()) {
+        SharedRuntimes.push_back("ubsan_minimal");
+      } else {
+        SharedRuntimes.push_back("ubsan_standalone");
+      }
+    }
   }
+
   // The stats_client library is also statically linked into DSOs.
   if (SanArgs.needsStatsRt())
     StaticRuntimes.push_back("stats_client");
 
   // Collect static runtimes.
-  if (Args.hasArg(options::OPT_shared) || TC.getTriple().isAndroid()) {
-    // Don't link static runtimes into DSOs or if compiling for Android.
+  if (Args.hasArg(options::OPT_shared) || SanArgs.needsSharedRt()) {
+    // Don't link static runtimes into DSOs or if -shared-libasan.
     return;
   }
   if (SanArgs.needsAsanRt()) {
-    if (SanArgs.needsSharedAsanRt()) {
-      HelperStaticRuntimes.push_back("asan-preinit");
-    } else {
-      StaticRuntimes.push_back("asan");
-      if (SanArgs.linkCXXRuntimes())
-        StaticRuntimes.push_back("asan_cxx");
-    }
+    StaticRuntimes.push_back("asan");
+    if (SanArgs.linkCXXRuntimes())
+      StaticRuntimes.push_back("asan_cxx");
   }
   if (SanArgs.needsDfsanRt())
     StaticRuntimes.push_back("dfsan");
@@ -574,9 +583,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 +610,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 +619,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..e744227 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:
@@ -992,24 +990,56 @@
   llvm_unreachable("Unsupported platform");
 }
 
+/// Check if the link command contains a symbol export directive.
+static bool hasExportSymbolDirective(const ArgList &Args) {
+  for (Arg *A : Args) {
+    if (!A->getOption().matches(options::OPT_Wl_COMMA) &&
+        !A->getOption().matches(options::OPT_Xlinker))
+      continue;
+    if (A->containsValue("-exported_symbols_list") ||
+        A->containsValue("-exported_symbol"))
+      return true;
+  }
+  return false;
+}
+
+/// Add an export directive for \p Symbol to the link command.
+static void addExportedSymbol(ArgStringList &CmdArgs, const char *Symbol) {
+  CmdArgs.push_back("-exported_symbol");
+  CmdArgs.push_back(Symbol);
+}
+
 void Darwin::addProfileRTLibs(const ArgList &Args,
                               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));
+
+  // If we have a symbol export directive and we're linking in the profile
+  // runtime, automatically export symbols necessary to implement some of the
+  // runtime's functionality.
+  if (hasExportSymbolDirective(Args)) {
+    addExportedSymbol(CmdArgs, "_VPMergeHook");
+    addExportedSymbol(CmdArgs, "___llvm_profile_filename");
+    addExportedSymbol(CmdArgs, "___llvm_profile_raw_version");
+    addExportedSymbol(CmdArgs, "_lprofCurFilename");
+  }
 }
 
 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 +1080,23 @@
   if (Sanitize.needsLsanRt())
     AddLinkSanitizerLibArgs(Args, CmdArgs, "lsan");
   if (Sanitize.needsUbsanRt())
-    AddLinkSanitizerLibArgs(Args, CmdArgs, "ubsan");
+    AddLinkSanitizerLibArgs(Args, CmdArgs,
+                            Sanitize.requiresMinimalRuntime() ? "ubsan_minimal"
+                                                              : "ubsan",
+                            Sanitize.needsSharedRt());
   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 +1778,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 +2060,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..5cea62b 100644
--- a/lib/Driver/ToolChains/Fuchsia.cpp
+++ b/lib/Driver/ToolChains/Fuchsia.cpp
@@ -14,6 +14,7 @@
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
 #include "llvm/Option/ArgList.h"
 #include "llvm/Support/Path.h"
 
@@ -63,27 +64,28 @@
   if (Args.hasArg(options::OPT_s))
     CmdArgs.push_back("-s");
 
-  if (Args.hasArg(options::OPT_r))
+  if (Args.hasArg(options::OPT_r)) {
     CmdArgs.push_back("-r");
-  else
+  } else {
     CmdArgs.push_back("--build-id");
+    CmdArgs.push_back("--hash-style=gnu");
+  }
 
-  if (!Args.hasArg(options::OPT_static))
-    CmdArgs.push_back("--eh-frame-hdr");
+  CmdArgs.push_back("--eh-frame-hdr");
 
   if (Args.hasArg(options::OPT_static))
     CmdArgs.push_back("-Bstatic");
   else if (Args.hasArg(options::OPT_shared))
     CmdArgs.push_back("-shared");
 
-  if (!Args.hasArg(options::OPT_static)) {
-    if (Args.hasArg(options::OPT_rdynamic))
-      CmdArgs.push_back("-export-dynamic");
-
-    if (!Args.hasArg(options::OPT_shared)) {
-      CmdArgs.push_back("-dynamic-linker");
-      CmdArgs.push_back(Args.MakeArgString(D.DyldPrefix + "ld.so.1"));
-    }
+  if (!Args.hasArg(options::OPT_shared)) {
+    std::string Dyld = D.DyldPrefix;
+    if (ToolChain.getSanitizerArgs().needsAsanRt() &&
+        ToolChain.getSanitizerArgs().needsSharedRt())
+      Dyld += "asan/";
+    Dyld += "ld.so.1";
+    CmdArgs.push_back("-dynamic-linker");
+    CmdArgs.push_back(Args.MakeArgString(Dyld));
   }
 
   CmdArgs.push_back("-o");
@@ -100,6 +102,8 @@
 
   ToolChain.AddFilePathLibArgs(Args, CmdArgs);
 
+  addSanitizerRuntimes(ToolChain, Args, CmdArgs);
+
   AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
 
   if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
@@ -107,13 +111,8 @@
       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))
+        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
       CmdArgs.push_back("-lm");
     }
 
@@ -282,5 +281,6 @@
 SanitizerMask Fuchsia::getSupportedSanitizers() const {
   SanitizerMask Res = ToolChain::getSupportedSanitizers();
   Res |= SanitizerKind::SafeStack;
+  Res |= SanitizerKind::Address;
   return Res;
 }
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/MSVC.cpp b/lib/Driver/ToolChains/MSVC.cpp
index 7978a69..c110628 100644
--- a/lib/Driver/ToolChains/MSVC.cpp
+++ b/lib/Driver/ToolChains/MSVC.cpp
@@ -375,7 +375,7 @@
   if (TC.getSanitizerArgs().needsAsanRt()) {
     CmdArgs.push_back(Args.MakeArgString("-debug"));
     CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
-    if (TC.getSanitizerArgs().needsSharedAsanRt() ||
+    if (TC.getSanitizerArgs().needsSharedRt() ||
         Args.hasArg(options::OPT__SLASH_MD, options::OPT__SLASH_MDd)) {
       for (const auto &Lib : {"asan_dynamic", "asan_dynamic_runtime_thunk"})
         CmdArgs.push_back(TC.getCompilerRTArgString(Args, Lib));
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..59c10a3 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -243,7 +243,8 @@
   
   uint64_t Contexts = 0;
   if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND) || 
-      isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND)) {
+      isa<ClassTemplateDecl>(ND) || isa<TemplateTemplateParmDecl>(ND) ||
+      isa<TypeAliasTemplateDecl>(ND)) {
     // Types can appear in these contexts.
     if (LangOpts.CPlusPlus || !isa<TagDecl>(ND))
       Contexts |= (1LL << CodeCompletionContext::CCC_TopLevel)
@@ -263,8 +264,12 @@
       Contexts |= (1LL << CodeCompletionContext::CCC_ObjCMessageReceiver);
     
     // In Objective-C, you can only be a subclass of another Objective-C class
-    if (isa<ObjCInterfaceDecl>(ND))
+    if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
+      // Objective-C interfaces can be used in a class property expression.
+      if (ID->getDefinition())
+        Contexts |= (1LL << CodeCompletionContext::CCC_Expression);
       Contexts |= (1LL << CodeCompletionContext::CCC_ObjCInterfaceName);
+    }
 
     // Deal with tag names.
     if (isa<EnumDecl>(ND)) {
@@ -542,6 +547,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/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 914039a..8ae9038 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -143,6 +143,8 @@
                      ArrayRef<int> Ids) override;
   void PragmaWarningPush(SourceLocation Loc, int Level) override;
   void PragmaWarningPop(SourceLocation Loc) override;
+  void PragmaAssumeNonNullBegin(SourceLocation Loc) override;
+  void PragmaAssumeNonNullEnd(SourceLocation Loc) override;
 
   bool HandleFirstTokOnLine(Token &Tok);
 
@@ -549,6 +551,22 @@
   setEmittedDirectiveOnThisLine();
 }
 
+void PrintPPOutputPPCallbacks::
+PragmaAssumeNonNullBegin(SourceLocation Loc) {
+  startNewLineIfNeeded();
+  MoveToLine(Loc);
+  OS << "#pragma clang assume_nonnull begin";
+  setEmittedDirectiveOnThisLine();
+}
+
+void PrintPPOutputPPCallbacks::
+PragmaAssumeNonNullEnd(SourceLocation Loc) {
+  startNewLineIfNeeded();
+  MoveToLine(Loc);
+  OS << "#pragma clang assume_nonnull end";
+  setEmittedDirectiveOnThisLine();
+}
+
 /// HandleFirstTokOnLine - When emitting a preprocessed file in -E mode, this
 /// is called for the first token on each new line.  If this really is the start
 /// of a new logical line, handle it and return true, otherwise return false.
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/IndexBody.cpp b/lib/Index/IndexBody.cpp
index 6bbd381..ac34956 100644
--- a/lib/Index/IndexBody.cpp
+++ b/lib/Index/IndexBody.cpp
@@ -427,6 +427,17 @@
 
     return true;
   }
+
+  bool VisitOffsetOfExpr(OffsetOfExpr *S) {
+    for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
+      const OffsetOfNode &Component = S->getComponent(I);
+      if (Component.getKind() == OffsetOfNode::Field)
+        IndexCtx.handleReference(Component.getField(), Component.getLocEnd(),
+                                 Parent, ParentDC, SymbolRoleSet(), {});
+      // FIXME: Try to resolve dependent field references.
+    }
+    return true;
+  }
 };
 
 } // anonymous namespace
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..0615aea 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 =
@@ -350,12 +354,10 @@
         gatherTemplatePseudoOverrides(D, Relations);
         IndexCtx.indexTagDecl(D, Relations);
       } else {
-        auto *Parent = dyn_cast<NamedDecl>(D->getDeclContext());
         SmallVector<SymbolRelation, 1> Relations;
         gatherTemplatePseudoOverrides(D, Relations);
-        return IndexCtx.handleReference(D, D->getLocation(), Parent,
-                                        D->getLexicalDeclContext(),
-                                        SymbolRoleSet(), Relations);
+        return IndexCtx.handleDecl(D, D->getLocation(), SymbolRoleSet(),
+                                   Relations, D->getLexicalDeclContext());
       }
     }
     return true;
@@ -607,6 +609,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
@@ -644,7 +664,6 @@
   }
 
   bool VisitTemplateDecl(const TemplateDecl *D) {
-    // FIXME: Template parameters.
 
     // Index the default values for the template parameters.
     const NamedDecl *Parent = D->getTemplatedDecl();
@@ -661,7 +680,7 @@
         } else if (const auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(TP)) {
           if (TTPD->hasDefaultArgument())
             handleTemplateArgumentLoc(TTPD->getDefaultArgument(), Parent,
-                                      /*DC=*/nullptr);
+                                      TP->getLexicalDeclContext());
         }
       }
     }
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..e3371bb 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
@@ -749,8 +753,12 @@
     if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
       Out << 'F';
       VisitType(FT->getReturnType());
-      for (const auto &I : FT->param_types())
+      Out << '(';
+      for (const auto &I : FT->param_types()) {
+        Out << '#';
         VisitType(I);
+      }
+      Out << ')';
       if (FT->isVariadic())
         Out << '.';
       return;
@@ -797,13 +805,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;
     }
@@ -817,6 +819,25 @@
       T = VT->getElementType();
       continue;
     }
+    if (const auto *const AT = dyn_cast<ArrayType>(T)) {
+      Out << '{';
+      switch (AT->getSizeModifier()) {
+      case ArrayType::Static:
+        Out << 's';
+        break;
+      case ArrayType::Star:
+        Out << '*';
+        break;
+      case ArrayType::Normal:
+        Out << 'n';
+        break;
+      }
+      if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
+        Out << CAT->getSize();
+
+      T = AT->getElementType();
+      continue;
+    }
 
     // Unhandled type.
     Out << ' ';
@@ -912,6 +933,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..3b03ba6 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,
@@ -2131,7 +2160,8 @@
     // If we read multiple characters, and one of those characters was a \r or
     // \n, then we had an escaped newline within the comment.  Emit diagnostic
     // unless the next line is also a // comment.
-    if (CurPtr != OldPtr+1 && C != '/' && CurPtr[0] != '/') {
+    if (CurPtr != OldPtr + 1 && C != '/' &&
+        (CurPtr == BufferEnd + 1 || CurPtr[0] != '/')) {
       for (; OldPtr != CurPtr; ++OldPtr)
         if (OldPtr[0] == '\n' || OldPtr[0] == '\r') {
           // Okay, we found a // comment that ends in a newline, if the next
@@ -3526,7 +3556,8 @@
     } else if (LangOpts.Digraphs && Char == '%') {     // '<%' -> '{'
       CurPtr = ConsumeChar(CurPtr, SizeTmp, Result);
       Kind = tok::l_brace;
-    } else if (Char == '#' && lexEditorPlaceholder(Result, CurPtr)) {
+    } else if (Char == '#' && /*Not a trigraph*/ SizeTmp == 1 &&
+               lexEditorPlaceholder(Result, CurPtr)) {
       return true;
     } else {
       Kind = tok::less;
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/Pragma.cpp b/lib/Lex/Pragma.cpp
index bf2363a..b5d0f93 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -1725,6 +1725,7 @@
 
     // The start location we want after processing this.
     SourceLocation NewLoc;
+    PPCallbacks *Callbacks = PP.getPPCallbacks();
 
     if (IsBegin) {
       // Complain about attempts to re-enter an audit.
@@ -1733,6 +1734,8 @@
         PP.Diag(BeginLoc, diag::note_pragma_entered_here);
       }
       NewLoc = Loc;
+      if (Callbacks)
+        Callbacks->PragmaAssumeNonNullBegin(NewLoc);
     } else {
       // Complain about attempts to leave an audit that doesn't exist.
       if (!BeginLoc.isValid()) {
@@ -1740,6 +1743,8 @@
         return;
       }
       NewLoc = SourceLocation();
+      if (Callbacks)
+        Callbacks->PragmaAssumeNonNullEnd(NewLoc);
     }
 
     PP.setPragmaAssumeNonNullLoc(NewLoc);
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/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 44b87af..b3309f0 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -2762,7 +2762,7 @@
 /// \endverbatim
 bool Parser::ParseExpressionList(SmallVectorImpl<Expr *> &Exprs,
                                  SmallVectorImpl<SourceLocation> &CommaLocs,
-                                 std::function<void()> Completer) {
+                                 llvm::function_ref<void()> Completer) {
   bool SawError = false;
   while (1) {
     if (Tok.is(tok::code_completion)) {
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/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index b1fbb20..f760046 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -1477,6 +1477,9 @@
   DiagnoseAndSkipCXX11Attributes();
 
   ExprResult Cond = ParseExpression();
+  // Correct the typos in condition before closing the scope.
+  if (Cond.isUsable())
+    Cond = Actions.CorrectDelayedTyposInExpr(Cond);
   T.consumeClose();
   DoScope.Exit();
 
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/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 944cd77..8e7f01a 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -197,10 +197,11 @@
   MaybeParseCXX11Attributes(prefixAttrs);
 
   if (Tok.is(tok::kw_using)) {
-    // FIXME: We should return the DeclGroup to the caller.
-    ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
-                                     prefixAttrs);
-    return nullptr;
+    auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
+                                                         prefixAttrs);
+    if (!usingDeclPtr || !usingDeclPtr.get().isSingleDecl())
+      return nullptr;
+    return usingDeclPtr.get().getSingleDecl();
   }
 
   // Parse the declaration specifiers, stealing any diagnostics from
diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 1ed7ef9..89b7d0d 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;
@@ -753,9 +761,15 @@
     SingleDecl = ParseObjCMethodDefinition();
     break;
   case tok::code_completion:
-      Actions.CodeCompleteOrdinaryName(getCurScope(), 
-                             CurParsedObjCImpl? Sema::PCC_ObjCImplementation
-                                              : Sema::PCC_Namespace);
+    if (CurParsedObjCImpl) {
+      // Code-complete Objective-C methods even without leading '-'/'+' prefix.
+      Actions.CodeCompleteObjCMethodDecl(getCurScope(),
+                                         /*IsInstanceMethod=*/None,
+                                         /*ReturnType=*/nullptr);
+    }
+    Actions.CodeCompleteOrdinaryName(
+        getCurScope(),
+        CurParsedObjCImpl ? Sema::PCC_ObjCImplementation : Sema::PCC_Namespace);
     cutOffParsing();
     return nullptr;
   case tok::kw_export:
diff --git a/lib/Rewrite/HTMLRewrite.cpp b/lib/Rewrite/HTMLRewrite.cpp
index 9e307f3..23d1895 100644
--- a/lib/Rewrite/HTMLRewrite.cpp
+++ b/lib/Rewrite/HTMLRewrite.cpp
@@ -289,6 +289,11 @@
       " body { color:#000000; background-color:#ffffff }\n"
       " body { font-family:Helvetica, sans-serif; font-size:10pt }\n"
       " h1 { font-size:14pt }\n"
+      " .FileName { margin-top: 5px; margin-bottom: 5px; display: inline; }\n"
+      " .FileNav { margin-left: 5px; margin-right: 5px; display: inline; }\n"
+      " .FileNav a { text-decoration:none; font-size: larger; }\n"
+      " .divider { margin-top: 30px; margin-bottom: 30px; height: 15px; }\n"
+      " .divider { background-color: gray; }\n"
       " .code { border-collapse:collapse; width:100%; }\n"
       " .code { font-family: \"Monospace\", monospace; font-size:10pt }\n"
       " .code { line-height: 1.2em }\n"
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index f83baa7..0b48838 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -29,7 +29,7 @@
 #include "clang/Analysis/Analyses/ReachableCode.h"
 #include "clang/Analysis/Analyses/ThreadSafety.h"
 #include "clang/Analysis/Analyses/UninitializedValues.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/Analysis/CFGStmtMap.h"
 #include "clang/Basic/SourceLocation.h"
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..7f627a3 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(
@@ -383,14 +389,26 @@
 }
 
 void Sema::diagnoseZeroToNullptrConversion(CastKind Kind, const Expr* E) {
-  if (Kind != CK_NullToPointer && Kind != CK_NullToMemberPointer)
-    return;
-  if (E->getType()->isNullPtrType())
+  if (Diags.isIgnored(diag::warn_zero_as_null_pointer_constant,
+                      E->getLocStart()))
     return;
   // nullptr only exists from C++11 on, so don't warn on its absence earlier.
   if (!getLangOpts().CPlusPlus11)
     return;
 
+  if (Kind != CK_NullToPointer && Kind != CK_NullToMemberPointer)
+    return;
+  if (E->IgnoreParenImpCasts()->getType()->isNullPtrType())
+    return;
+
+  // If it is a macro from system header, and if the macro name is not "NULL",
+  // do not warn.
+  SourceLocation MaybeMacroLoc = E->getLocStart();
+  if (Diags.getSuppressSystemWarnings() &&
+      SourceMgr.isInSystemMacro(MaybeMacroLoc) &&
+      !findMacroSpelling(MaybeMacroLoc, "NULL"))
+    return;
+
   Diag(E->getLocStart(), diag::warn_zero_as_null_pointer_constant)
       << FixItHint::CreateReplacement(E->getSourceRange(), "nullptr");
 }
diff --git a/lib/Sema/SemaAPINotes.cpp b/lib/Sema/SemaAPINotes.cpp
new file mode 100644
index 0000000..d472f35
--- /dev/null
+++ b/lib/Sema/SemaAPINotes.cpp
@@ -0,0 +1,952 @@
+//===--- 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<Decl::attr_iterator(const Decl*)> getExistingAttr) {
+    if (metadata.IsActive) {
+      auto existing = getExistingAttr(D);
+      if (existing != D->attr_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);
+        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,
+                               [](const Decl *decl) {
+      return llvm::find_if(decl->attrs(), [](const Attr *next) {
+        return isa<A>(next);
+      });
+    });
+  }
+}
+
+template <typename A = CFReturnsRetainedAttr>
+static void handleAPINotedRetainCountAttribute(Sema &S, Decl *D,
+                                               bool shouldAddAttribute,
+                                               VersionedInfoMetadata metadata) {
+  // The template argument has a default to make the "removal" case more
+  // concise; it doesn't matter /which/ attribute is being removed.
+  handleAPINotedAttribute<A>(S, D, shouldAddAttribute, metadata, [&] {
+    return A::CreateImplicit(S.Context);
+  }, [](const Decl *D) -> Decl::attr_iterator {
+    return llvm::find_if(D->attrs(), [](const Attr *next) -> bool {
+      return isa<CFReturnsRetainedAttr>(next) ||
+             isa<CFReturnsNotRetainedAttr>(next) ||
+             isa<NSReturnsRetainedAttr>(next) ||
+             isa<NSReturnsNotRetainedAttr>(next);
+    });
+  });
+}
+
+static void handleAPINotedRetainCountConvention(
+    Sema &S, Decl *D, VersionedInfoMetadata metadata,
+    Optional<api_notes::RetainCountConventionKind> convention) {
+  if (!convention)
+    return;
+  switch (convention.getValue()) {
+  case api_notes::RetainCountConventionKind::None:
+    handleAPINotedRetainCountAttribute(S, D, /*shouldAddAttribute*/false,
+                                       metadata);
+    break;
+  case api_notes::RetainCountConventionKind::CFReturnsRetained:
+    handleAPINotedRetainCountAttribute<CFReturnsRetainedAttr>(
+        S, D, /*shouldAddAttribute*/true, metadata);
+    break;
+  case api_notes::RetainCountConventionKind::CFReturnsNotRetained:
+    handleAPINotedRetainCountAttribute<CFReturnsNotRetainedAttr>(
+        S, D, /*shouldAddAttribute*/true, metadata);
+    break;
+  case api_notes::RetainCountConventionKind::NSReturnsRetained:
+    handleAPINotedRetainCountAttribute<NSReturnsRetainedAttr>(
+        S, D, /*shouldAddAttribute*/true, metadata);
+    break;
+  case api_notes::RetainCountConventionKind::NSReturnsNotRetained:
+    handleAPINotedRetainCountAttribute<NSReturnsNotRetainedAttr>(
+        S, D, /*shouldAddAttribute*/true, metadata);
+    break;
+  }
+}
+
+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());
+    },
+    [](const Decl *decl) {
+      return llvm::find_if(decl->attrs(), [](const Attr *next) -> bool {
+        auto *AA = dyn_cast<AvailabilityAttr>(next);
+        if (!AA)
+          return false;
+        const IdentifierInfo *platform = AA->getPlatform();
+        if (!platform)
+          return false;
+        return platform->isStr("swift");
+      });
+    });
+  }
+
+  // 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);
+    });
+  }
+
+  // Retain count convention
+  handleAPINotedRetainCountConvention(S, D, metadata,
+                                      info.getRetainCountConvention());
+
+  // 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()));
+    }
+  }
+
+  // Retain count convention
+  handleAPINotedRetainCountConvention(S, D, metadata,
+                                      info.getRetainCountConvention());
+
+  // 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..a122f87 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;
 }
@@ -6200,7 +6210,7 @@
       CastFix << ")";
 
       SmallVector<FixItHint,4> Hints;
-      if (!AT.matchesType(S.Context, IntendedTy))
+      if (!AT.matchesType(S.Context, IntendedTy) || ShouldNotPrintDirectly) 
         Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str()));
 
       if (const CStyleCastExpr *CCast = dyn_cast<CStyleCastExpr>(E)) {
@@ -11577,9 +11587,7 @@
     return;
 
   // Check for a call to std::move
-  const FunctionDecl *FD = CE->getDirectCallee();
-  if (!FD || !FD->isInStdNamespace() || !FD->getIdentifier() ||
-      !FD->getIdentifier()->isStr("move"))
+  if (!CE->isCallToStdMove())
     return;
 
   // Get argument from std::move
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 4de7d42..7115485 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;
 }
 
@@ -1070,9 +1022,16 @@
 /// ordinary name lookup but is not a type name.
 bool ResultBuilder::IsOrdinaryNonTypeName(const NamedDecl *ND) const {
   ND = cast<NamedDecl>(ND->getUnderlyingDecl());
-  if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND))
+  if (isa<TypeDecl>(ND))
     return false;
-  
+  // Objective-C interfaces names are not filtered by this method because they
+  // can be used in a class property expression. We can still filter out
+  // @class declarations though.
+  if (const auto *ID = dyn_cast<ObjCInterfaceDecl>(ND)) {
+    if (!ID->getDefinition())
+      return false;
+  }
+
   unsigned IDNS = Decl::IDNS_Ordinary | Decl::IDNS_LocalExtern;
   if (SemaRef.getLangOpts().CPlusPlus)
     IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace | Decl::IDNS_Member;
@@ -3366,9 +3325,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 +4188,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.
@@ -6630,7 +6589,7 @@
 /// indexed by selector so they can be easily found.
 static void FindImplementableMethods(ASTContext &Context,
                                      ObjCContainerDecl *Container,
-                                     bool WantInstanceMethods,
+                                     Optional<bool> WantInstanceMethods,
                                      QualType ReturnType,
                                      KnownMethodsMap &KnownMethods,
                                      bool InOriginalClass = true) {
@@ -6701,7 +6660,7 @@
   // we want the methods from this container to override any methods
   // we've previously seen with the same selector.
   for (auto *M : Container->methods()) {
-    if (M->isInstanceMethod() == WantInstanceMethods) {
+    if (!WantInstanceMethods || M->isInstanceMethod() == *WantInstanceMethods) {
       if (!ReturnType.isNull() &&
           !Context.hasSameUnqualifiedType(ReturnType, M->getReturnType()))
         continue;
@@ -7373,8 +7332,7 @@
   }
 }
 
-void Sema::CodeCompleteObjCMethodDecl(Scope *S, 
-                                      bool IsInstanceMethod,
+void Sema::CodeCompleteObjCMethodDecl(Scope *S, Optional<bool> IsInstanceMethod,
                                       ParsedType ReturnTy) {
   // Determine the return type of the method we're declaring, if
   // provided.
@@ -7429,7 +7387,13 @@
     ObjCMethodDecl *Method = M->second.getPointer();
     CodeCompletionBuilder Builder(Results.getAllocator(),
                                   Results.getCodeCompletionTUInfo());
-    
+
+    // Add the '-'/'+' prefix if it wasn't provided yet.
+    if (!IsInstanceMethod) {
+      Builder.AddTextChunk(Method->isInstanceMethod() ? "-" : "+");
+      Builder.AddChunk(CodeCompletionString::CK_HorizontalSpace);
+    }
+
     // If the result type was not already provided, add it to the
     // pattern as (type).
     if (ReturnType.isNull()) {
@@ -7531,11 +7495,13 @@
     if (IFace)
       for (auto *Cat : IFace->visible_categories())
         Containers.push_back(Cat);
-    
-    for (unsigned I = 0, N = Containers.size(); I != N; ++I)
-      for (auto *P : Containers[I]->instance_properties())
-        AddObjCKeyValueCompletions(P, IsInstanceMethod, ReturnType, Context, 
-                                   KnownSelectors, Results);
+
+    if (IsInstanceMethod) {
+      for (unsigned I = 0, N = Containers.size(); I != N; ++I)
+        for (auto *P : Containers[I]->instance_properties())
+          AddObjCKeyValueCompletions(P, *IsInstanceMethod, ReturnType, Context,
+                                     KnownSelectors, Results);
+    }
   }
   
   Results.ExitScope();
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 692a77e..9ee9a25 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());
@@ -8874,10 +8880,10 @@
           diag::ext_function_specialization_in_class :
           diag::err_function_specialization_in_class)
           << NewFD->getDeclName();
-      } else if (CheckFunctionTemplateSpecialization(NewFD,
-                                  (HasExplicitTemplateArgs ? &TemplateArgs
-                                                           : nullptr),
-                                                     Previous))
+      } else if (!NewFD->isInvalidDecl() &&
+                 CheckFunctionTemplateSpecialization(
+                     NewFD, (HasExplicitTemplateArgs ? &TemplateArgs : nullptr),
+                     Previous))
         NewFD->setInvalidDecl();
 
       // C++ [dcl.stc]p1:
@@ -9984,14 +9990,9 @@
 
     void VisitCallExpr(CallExpr *E) {
       // Treat std::move as a use.
-      if (E->getNumArgs() == 1) {
-        if (FunctionDecl *FD = E->getDirectCallee()) {
-          if (FD->isInStdNamespace() && FD->getIdentifier() &&
-              FD->getIdentifier()->isStr("move")) {
-            HandleValue(E->getArg(0));
-            return;
-          }
-        }
+      if (E->isCallToStdMove()) {
+        HandleValue(E->getArg(0));
+        return;
       }
 
       Inherited::VisitCallExpr(E);
@@ -11802,10 +11803,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 +11819,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 +11828,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 +12603,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 +13936,13 @@
     Invalid = true;
   }
 
+  if (!Invalid && getLangOpts().CPlusPlus && 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 +15266,7 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Record, Attr);
+  ProcessAPINotes(Record);
 }
 
 /// \brief Determine whether the given integral value is representable within
@@ -15548,6 +15567,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 +15792,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..e860b4b 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.
 //===----------------------------------------------------------------------===//
@@ -5665,8 +6164,12 @@
 
 static void handleAssertCapabilityAttr(Sema &S, Decl *D,
                                        const AttributeList &Attr) {
+  SmallVector<Expr*, 1> Args;
+  if (!checkLockFunAttrCommon(S, D, Attr, Args))
+    return;
+
   D->addAttr(::new (S.Context) AssertCapabilityAttr(Attr.getRange(), S.Context,
-                                                    Attr.getArgAsExpr(0),
+                                                    Args.data(), Args.size(),
                                         Attr.getAttributeSpellingListIndex()));
 }
 
@@ -6120,6 +6623,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 +6692,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 +6754,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 +7029,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 +7290,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 +7537,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 +7769,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 +8179,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..8880acf 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -3387,14 +3387,9 @@
 
     void VisitCallExpr(CallExpr *E) {
       // Treat std::move as a use.
-      if (E->getNumArgs() == 1) {
-        if (FunctionDecl *FD = E->getDirectCallee()) {
-          if (FD->isInStdNamespace() && FD->getIdentifier() &&
-              FD->getIdentifier()->isStr("move")) {
-            HandleValue(E->getArg(0), false /*AddressOf*/);
-            return;
-          }
-        }
+      if (E->isCallToStdMove()) {
+        HandleValue(E->getArg(0), /*AddressOf=*/false);
+        return;
       }
 
       Inherited::VisitCallExpr(E);
@@ -5726,53 +5721,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 +5865,6 @@
   }
 
   checkClassLevelDLLAttribute(Record);
-
-  Record->setCanPassInRegisters(computeCanPassInRegisters(*this, Record));
 }
 
 /// Look up the special member function that would be called by a special
@@ -7545,7 +7491,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 +8461,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 +8851,7 @@
 
   if (UDir)
     ProcessDeclAttributeList(S, UDir, AttrList);
+  ProcessAPINotes(UDir);
 
   return UDir;
 }
@@ -10001,6 +9950,7 @@
 
   ProcessDeclAttributeList(S, NewTD, AttrList);
   AddPragmaAttributes(S, NewTD);
+  ProcessAPINotes(NewTD);
 
   CheckTypedefForVariablyModifiedType(S, NewTD);
   Invalid |= NewTD->isInvalidDecl();
@@ -11977,10 +11927,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..7891c75 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
@@ -12482,8 +12614,8 @@
   // Look for an explicit signature in that function type.
   FunctionProtoTypeLoc ExplicitSignature;
 
-  TypeLoc tmp = Sig->getTypeLoc().IgnoreParens();
-  if ((ExplicitSignature = tmp.getAs<FunctionProtoTypeLoc>())) {
+  if ((ExplicitSignature =
+           Sig->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>())) {
 
     // Check whether that explicit signature was synthesized by
     // GetTypeForDeclarator.  If so, don't save that as part of the
@@ -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/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 32024cb..dcbeddd 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -6328,6 +6328,10 @@
     if (!VD || !VD->hasLocalStorage())
       return;
 
+    // __block variables are not moved implicitly.
+    if (VD->hasAttr<BlocksAttr>())
+      return;
+
     QualType SourceType = VD->getType();
     if (!SourceType->isRecordType())
       return;
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index bfb0071..c980ddd 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);
 
@@ -1599,7 +1599,11 @@
   // meaningless for readonly properties, so don't diagnose if the
   // atomic property is 'readonly'.
   checkAtomicPropertyMismatch(*this, SuperProperty, Property, false);
-  if (Property->getSetterName() != SuperProperty->getSetterName()) {
+  // Readonly properties from protocols can be implemented as "readwrite"
+  // with a custom setter name.
+  if (Property->getSetterName() != SuperProperty->getSetterName() &&
+      !(SuperProperty->isReadOnly() &&
+        isa<ObjCProtocolDecl>(SuperProperty->getDeclContext()))) {
     Diag(Property->getLocation(), diag::warn_property_attribute)
       << Property->getDeclName() << "setter" << inheritedName;
     Diag(SuperProperty->getLocation(), diag::note_property_declare);
@@ -1895,7 +1899,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 +2398,8 @@
           SectionAttr::CreateImplicit(Context, SectionAttr::GNU_section,
                                       SA->getName(), Loc));
 
+    ProcessAPINotes(GetterMethod);
+
     if (getLangOpts().ObjCAutoRefCount)
       CheckARCMethodDecl(GetterMethod);
   } else
@@ -2459,6 +2465,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 1ae6f9d..c55f496 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..25356ed 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,33 @@
   }
 }
 
+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. CFErrorRef used to be declared with "objc_bridge" but
+  // is now declared with "objc_bridge_mutable", so look for either one of the
+  // two attributes.
+  if (recordDecl->getTagKind() == TTK_Struct) {
+    IdentifierInfo *bridgedType = nullptr;
+    if (auto bridgeAttr = recordDecl->getAttr<ObjCBridgeAttr>())
+      bridgedType = bridgeAttr->getBridgedType();
+    else if (auto bridgeAttr =
+                 recordDecl->getAttr<ObjCBridgeMutableAttr>())
+      bridgedType = bridgeAttr->getBridgedType();
+
+    if (bridgedType == 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 +6050,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 +6086,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 +6096,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 +6116,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 +6141,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 +6179,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 +6947,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/BlockInCriticalSectionChecker.cpp b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
index d19630e..c31f279 100644
--- a/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/BlockInCriticalSectionChecker.cpp
@@ -26,15 +26,22 @@
 
 namespace {
 
-class BlockInCriticalSectionChecker : public Checker<check::PostCall,
-                                                     check::PreCall> {
+class BlockInCriticalSectionChecker : public Checker<check::PostCall> {
+
+  mutable IdentifierInfo *IILockGuard, *IIUniqueLock;
 
   CallDescription LockFn, UnlockFn, SleepFn, GetcFn, FgetsFn, ReadFn, RecvFn,
                   PthreadLockFn, PthreadTryLockFn, PthreadUnlockFn,
                   MtxLock, MtxTimedLock, MtxTryLock, MtxUnlock;
 
+  StringRef ClassLockGuard, ClassUniqueLock;
+
+  mutable bool IdentifierInfoInitialized;
+
   std::unique_ptr<BugType> BlockInCritSectionBugType;
 
+  void initIdentifierInfo(ASTContext &Ctx) const;
+
   void reportBlockInCritSection(SymbolRef FileDescSym,
                                 const CallEvent &call,
                                 CheckerContext &C) const;
@@ -46,13 +53,10 @@
   bool isLockFunction(const CallEvent &Call) const;
   bool isUnlockFunction(const CallEvent &Call) const;
 
-  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
-
   /// Process unlock.
   /// Process lock.
   /// Process blocking functions (sleep, getc, fgets, read, recv)
   void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
-
 };
 
 } // end anonymous namespace
@@ -60,7 +64,8 @@
 REGISTER_TRAIT_WITH_PROGRAMSTATE(MutexCounter, unsigned)
 
 BlockInCriticalSectionChecker::BlockInCriticalSectionChecker()
-    : LockFn("lock"), UnlockFn("unlock"), SleepFn("sleep"), GetcFn("getc"),
+    : IILockGuard(nullptr), IIUniqueLock(nullptr),
+      LockFn("lock"), UnlockFn("unlock"), SleepFn("sleep"), GetcFn("getc"),
       FgetsFn("fgets"), ReadFn("read"), RecvFn("recv"),
       PthreadLockFn("pthread_mutex_lock"),
       PthreadTryLockFn("pthread_mutex_trylock"),
@@ -68,13 +73,29 @@
       MtxLock("mtx_lock"),
       MtxTimedLock("mtx_timedlock"),
       MtxTryLock("mtx_trylock"),
-      MtxUnlock("mtx_unlock") {
+      MtxUnlock("mtx_unlock"),
+      ClassLockGuard("lock_guard"),
+      ClassUniqueLock("unique_lock"),
+      IdentifierInfoInitialized(false) {
   // Initialize the bug type.
   BlockInCritSectionBugType.reset(
       new BugType(this, "Call to blocking function in critical section",
                         "Blocking Error"));
 }
 
+void BlockInCriticalSectionChecker::initIdentifierInfo(ASTContext &Ctx) const {
+  if (!IdentifierInfoInitialized) {
+    /* In case of checking C code, or when the corresponding headers are not
+     * included, we might end up query the identifier table every time when this
+     * function is called instead of early returning it. To avoid this, a bool
+     * variable (IdentifierInfoInitialized) is used and the function will be run
+     * only once. */
+    IILockGuard  = &Ctx.Idents.get(ClassLockGuard);
+    IIUniqueLock = &Ctx.Idents.get(ClassUniqueLock);
+    IdentifierInfoInitialized = true;
+  }
+}
+
 bool BlockInCriticalSectionChecker::isBlockingFunction(const CallEvent &Call) const {
   if (Call.isCalled(SleepFn)
       || Call.isCalled(GetcFn)
@@ -87,6 +108,12 @@
 }
 
 bool BlockInCriticalSectionChecker::isLockFunction(const CallEvent &Call) const {
+  if (const auto *Ctor = dyn_cast<CXXConstructorCall>(&Call)) {
+    auto IdentifierInfo = Ctor->getDecl()->getParent()->getIdentifier();
+    if (IdentifierInfo == IILockGuard || IdentifierInfo == IIUniqueLock)
+      return true;
+  }
+
   if (Call.isCalled(LockFn)
       || Call.isCalled(PthreadLockFn)
       || Call.isCalled(PthreadTryLockFn)
@@ -99,6 +126,13 @@
 }
 
 bool BlockInCriticalSectionChecker::isUnlockFunction(const CallEvent &Call) const {
+  if (const auto *Dtor = dyn_cast<CXXDestructorCall>(&Call)) {
+    const auto *DRecordDecl = dyn_cast<CXXRecordDecl>(Dtor->getDecl()->getParent());
+    auto IdentifierInfo = DRecordDecl->getIdentifier();
+    if (IdentifierInfo == IILockGuard || IdentifierInfo == IIUniqueLock)
+      return true;
+  }
+
   if (Call.isCalled(UnlockFn)
        || Call.isCalled(PthreadUnlockFn)
        || Call.isCalled(MtxUnlock)) {
@@ -107,12 +141,10 @@
   return false;
 }
 
-void BlockInCriticalSectionChecker::checkPreCall(const CallEvent &Call,
-                                                 CheckerContext &C) const {
-}
-
 void BlockInCriticalSectionChecker::checkPostCall(const CallEvent &Call,
                                                   CheckerContext &C) const {
+  initIdentifierInfo(C.getASTContext());
+
   if (!isBlockingFunction(Call)
       && !isLockFunction(Call)
       && !isUnlockFunction(Call))
diff --git a/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index 2759240..7ab9c61 100644
--- a/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -29,6 +29,7 @@
   CXXSelfAssignmentChecker.cpp
   DeadStoresChecker.cpp
   DebugCheckers.cpp
+  DeleteWithNonVirtualDtorChecker.cpp
   DereferenceChecker.cpp
   DirectIvarAssignment.cpp
   DivZeroChecker.cpp
@@ -56,6 +57,7 @@
   NSErrorChecker.cpp
   NoReturnFunctionChecker.cpp
   NonNullParamChecker.cpp
+  NonnullGlobalConstantsChecker.cpp
   NullabilityChecker.cpp
   NumberObjectConversionChecker.cpp
   ObjCAtSyncChecker.cpp
diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
index 77c2462..28ad7e9 100644
--- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp
@@ -289,8 +289,8 @@
   if (!ER)
     return state;
 
-  assert(ER->getValueType() == C.getASTContext().CharTy &&
-    "CheckLocation should only be called with char* ElementRegions");
+  if (ER->getValueType() != C.getASTContext().CharTy)
+    return state;
 
   // Get the size of the array.
   const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion());
@@ -874,6 +874,8 @@
   if (!ER)
     return true; // cf top comment.
 
+  // FIXME: Does this crash when a non-standard definition
+  // of a library function is encountered?
   assert(ER->getValueType() == C.getASTContext().CharTy &&
          "IsFirstBufInBound should only be called with char* ElementRegions");
 
@@ -1050,31 +1052,22 @@
     // If this is mempcpy, get the byte after the last byte copied and
     // bind the expr.
     if (IsMempcpy) {
-      loc::MemRegionVal destRegVal = destVal.castAs<loc::MemRegionVal>();
-
-      // Get the length to copy.
-      if (Optional<NonLoc> lenValNonLoc = sizeVal.getAs<NonLoc>()) {
-        // Get the byte after the last byte copied.
-        SValBuilder &SvalBuilder = C.getSValBuilder();
-        ASTContext &Ctx = SvalBuilder.getContext();
-        QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
-        loc::MemRegionVal DestRegCharVal = SvalBuilder.evalCast(destRegVal,
-          CharPtrTy, Dest->getType()).castAs<loc::MemRegionVal>();
-        SVal lastElement = C.getSValBuilder().evalBinOpLN(state, BO_Add,
-                                                          DestRegCharVal,
-                                                          *lenValNonLoc,
-                                                          Dest->getType());
-
-        // The byte after the last byte copied is the return value.
-        state = state->BindExpr(CE, LCtx, lastElement);
-      } else {
-        // If we don't know how much we copied, we can at least
-        // conjure a return value for later.
-        SVal result = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
+      // Get the byte after the last byte copied.
+      SValBuilder &SvalBuilder = C.getSValBuilder();
+      ASTContext &Ctx = SvalBuilder.getContext();
+      QualType CharPtrTy = Ctx.getPointerType(Ctx.CharTy);
+      SVal DestRegCharVal =
+          SvalBuilder.evalCast(destVal, CharPtrTy, Dest->getType());
+      SVal lastElement = C.getSValBuilder().evalBinOp(
+          state, BO_Add, DestRegCharVal, sizeVal, Dest->getType());
+      // If we don't know how much we copied, we can at least
+      // conjure a return value for later.
+      if (lastElement.isUnknown())
+        lastElement = C.getSValBuilder().conjureSymbolVal(nullptr, CE, LCtx,
                                                           C.blockCount());
-        state = state->BindExpr(CE, LCtx, result);
-      }
 
+      // The byte after the last byte copied is the return value.
+      state = state->BindExpr(CE, LCtx, lastElement);
     } else {
       // All other copies return the destination buffer.
       // (Well, bcopy() has a void return type, but this won't hurt.)
diff --git a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
index 391b843..4b5e97b 100644
--- a/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
@@ -16,7 +16,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/StmtVisitor.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/TypeTraits.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
diff --git a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
index 60f1618..f5903e0 100644
--- a/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
+++ b/lib/StaticAnalyzer/Checkers/CheckSecuritySyntaxOnly.cpp
@@ -13,7 +13,7 @@
 
 #include "ClangSACheckers.h"
 #include "clang/AST/StmtVisitor.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
diff --git a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
index 83955c5..ee517ed 100644
--- a/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/CloneChecker.cpp
@@ -64,7 +64,7 @@
   // the CloneDetector. The only thing left to do is to report the found clones.
 
   int MinComplexity = Mgr.getAnalyzerOptions().getOptionAsInteger(
-      "MinimumCloneComplexity", 10, this);
+      "MinimumCloneComplexity", 50, this);
   assert(MinComplexity >= 0);
 
   bool ReportSuspiciousClones = Mgr.getAnalyzerOptions().getBooleanOption(
@@ -81,11 +81,11 @@
   // because reportSuspiciousClones() wants to search them for errors.
   std::vector<CloneDetector::CloneGroup> AllCloneGroups;
 
-  Detector.findClones(AllCloneGroups,
-                      FilenamePatternConstraint(IgnoredFilesPattern),
-                      RecursiveCloneTypeIIConstraint(),
-                      MinComplexityConstraint(MinComplexity),
-                      MinGroupSizeConstraint(2), OnlyLargestCloneConstraint());
+  Detector.findClones(
+      AllCloneGroups, FilenamePatternConstraint(IgnoredFilesPattern),
+      RecursiveCloneTypeIIHashConstraint(), MinGroupSizeConstraint(2),
+      MinComplexityConstraint(MinComplexity),
+      RecursiveCloneTypeIIVerifyConstraint(), OnlyLargestCloneConstraint());
 
   if (ReportSuspiciousClones)
     reportSuspiciousClones(BR, Mgr, AllCloneGroups);
diff --git a/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp b/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
index ea894c8..17ec2c2 100644
--- a/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ConversionChecker.cpp
@@ -123,57 +123,6 @@
   C.emitReport(std::move(R));
 }
 
-// Is E value greater or equal than Val?
-static bool isGreaterEqual(CheckerContext &C, const Expr *E,
-                           unsigned long long Val) {
-  ProgramStateRef State = C.getState();
-  SVal EVal = C.getSVal(E);
-  if (EVal.isUnknownOrUndef())
-    return false;
-  if (!EVal.getAs<NonLoc>() && EVal.getAs<Loc>()) {
-    ProgramStateManager &Mgr = C.getStateManager();
-    EVal =
-        Mgr.getStoreManager().getBinding(State->getStore(), EVal.castAs<Loc>());
-  }
-  if (EVal.isUnknownOrUndef() || !EVal.getAs<NonLoc>())
-    return false;
-
-  SValBuilder &Bldr = C.getSValBuilder();
-  DefinedSVal V = Bldr.makeIntVal(Val, C.getASTContext().LongLongTy);
-
-  // Is DefinedEVal greater or equal with V?
-  SVal GE = Bldr.evalBinOp(State, BO_GE, EVal, V, Bldr.getConditionType());
-  if (GE.isUnknownOrUndef())
-    return false;
-  ConstraintManager &CM = C.getConstraintManager();
-  ProgramStateRef StGE, StLT;
-  std::tie(StGE, StLT) = CM.assumeDual(State, GE.castAs<DefinedSVal>());
-  return StGE && !StLT;
-}
-
-// Is E value negative?
-static bool isNegative(CheckerContext &C, const Expr *E) {
-  ProgramStateRef State = C.getState();
-  SVal EVal = State->getSVal(E, C.getLocationContext());
-  if (EVal.isUnknownOrUndef() || !EVal.getAs<NonLoc>())
-    return false;
-  DefinedSVal DefinedEVal = EVal.castAs<DefinedSVal>();
-
-  SValBuilder &Bldr = C.getSValBuilder();
-  DefinedSVal V = Bldr.makeIntVal(0, false);
-
-  SVal LT =
-      Bldr.evalBinOp(State, BO_LT, DefinedEVal, V, Bldr.getConditionType());
-
-  // Is E value greater than MaxVal?
-  ConstraintManager &CM = C.getConstraintManager();
-  ProgramStateRef StNegative, StPositive;
-  std::tie(StNegative, StPositive) =
-      CM.assumeDual(State, LT.castAs<DefinedSVal>());
-
-  return StNegative && !StPositive;
-}
-
 bool ConversionChecker::isLossOfPrecision(const ImplicitCastExpr *Cast,
                                           QualType DestType,
                                           CheckerContext &C) const {
@@ -195,18 +144,18 @@
     return false;
 
   unsigned long long MaxVal = 1ULL << W;
-  return isGreaterEqual(C, Cast->getSubExpr(), MaxVal);
+  return C.isGreaterOrEqual(Cast->getSubExpr(), MaxVal);
 }
 
 bool ConversionChecker::isLossOfSign(const ImplicitCastExpr *Cast,
-                                   CheckerContext &C) const {
+                                     CheckerContext &C) const {
   QualType CastType = Cast->getType();
   QualType SubType = Cast->IgnoreParenImpCasts()->getType();
 
   if (!CastType->isUnsignedIntegerType() || !SubType->isSignedIntegerType())
     return false;
 
-  return isNegative(C, Cast->getSubExpr());
+  return C.isNegative(Cast->getSubExpr());
 }
 
 void ento::registerConversionChecker(CheckerManager &mgr) {
diff --git a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
index 2eef168..810a33e 100644
--- a/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
+++ b/lib/StaticAnalyzer/Checkers/DebugCheckers.cpp
@@ -16,7 +16,6 @@
 #include "clang/Analysis/Analyses/LiveVariables.h"
 #include "clang/Analysis/CallGraph.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
-#include "clang/StaticAnalyzer/Core/IssueHash.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
@@ -213,35 +212,3 @@
   mgr.registerChecker<ExplodedGraphViewer>();
 }
 
-//===----------------------------------------------------------------------===//
-// DumpBugHash 
-//===----------------------------------------------------------------------===//
-
-namespace {
-class BugHashDumper : public Checker<check::PostStmt<Stmt>> {
-public:
-  mutable std::unique_ptr<BugType> BT;
-
-  void checkPostStmt(const Stmt *S, CheckerContext &C) const {
-    if (!BT)
-      BT.reset(new BugType(this, "Dump hash components", "debug"));
-
-    ExplodedNode *N = C.generateNonFatalErrorNode();
-    if (!N)
-      return;
-
-    const LangOptions &Opts = C.getLangOpts();
-    const SourceManager &SM = C.getSourceManager();
-    FullSourceLoc FL(S->getLocStart(), SM);
-    std::string HashContent =
-        GetIssueString(SM, FL, getCheckName().getName(), BT->getCategory(),
-                       C.getLocationContext()->getDecl(), Opts);
-
-    C.emitReport(llvm::make_unique<BugReport>(*BT, HashContent, N));
-  }
-};
-}
-
-void ento::registerBugHashDumper(CheckerManager &mgr) {
-  mgr.registerChecker<BugHashDumper>();
-}
diff --git a/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp b/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp
new file mode 100644
index 0000000..e04e2ab
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/DeleteWithNonVirtualDtorChecker.cpp
@@ -0,0 +1,153 @@
+//===-- DeleteWithNonVirtualDtorChecker.cpp -----------------------*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Defines a checker for the OOP52-CPP CERT rule: Do not delete a polymorphic
+// object without a virtual destructor.
+//
+// Diagnostic flags -Wnon-virtual-dtor and -Wdelete-non-virtual-dtor report if
+// an object with a virtual function but a non-virtual destructor exists or is
+// deleted, respectively.
+//
+// This check exceeds them by comparing the dynamic and static types of the
+// object at the point of destruction and only warns if it happens through a
+// pointer to a base type without a virtual destructor. The check places a note
+// at the last point where the conversion from derived to base happened.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class DeleteWithNonVirtualDtorChecker
+    : public Checker<check::PreStmt<CXXDeleteExpr>> {
+  mutable std::unique_ptr<BugType> BT;
+
+  class DeleteBugVisitor : public BugReporterVisitorImpl<DeleteBugVisitor> {
+  public:
+    DeleteBugVisitor() : Satisfied(false) {}
+    void Profile(llvm::FoldingSetNodeID &ID) const override {
+      static int X = 0;
+      ID.AddPointer(&X);
+    }
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
+
+  private:
+    bool Satisfied;
+  };
+
+public:
+  void checkPreStmt(const CXXDeleteExpr *DE, CheckerContext &C) const;
+};
+} // end anonymous namespace
+
+void DeleteWithNonVirtualDtorChecker::checkPreStmt(const CXXDeleteExpr *DE,
+                                                   CheckerContext &C) const {
+  const Expr *DeletedObj = DE->getArgument();
+  const MemRegion *MR = C.getSVal(DeletedObj).getAsRegion();
+  if (!MR)
+    return;
+
+  const auto *BaseClassRegion = MR->getAs<TypedValueRegion>();
+  const auto *DerivedClassRegion = MR->getBaseRegion()->getAs<SymbolicRegion>();
+  if (!BaseClassRegion || !DerivedClassRegion)
+    return;
+
+  const auto *BaseClass = BaseClassRegion->getValueType()->getAsCXXRecordDecl();
+  const auto *DerivedClass =
+      DerivedClassRegion->getSymbol()->getType()->getPointeeCXXRecordDecl();
+  if (!BaseClass || !DerivedClass)
+    return;
+
+  if (!BaseClass->hasDefinition() || !DerivedClass->hasDefinition())
+    return;
+
+  if (BaseClass->getDestructor()->isVirtual())
+    return;
+
+  if (!DerivedClass->isDerivedFrom(BaseClass))
+    return;
+
+  if (!BT)
+    BT.reset(new BugType(this,
+                         "Destruction of a polymorphic object with no "
+                         "virtual destructor",
+                         "Logic error"));
+
+  ExplodedNode *N = C.generateNonFatalErrorNode();
+  auto R = llvm::make_unique<BugReport>(*BT, BT->getName(), N);
+
+  // Mark region of problematic base class for later use in the BugVisitor.
+  R->markInteresting(BaseClassRegion);
+  R->addVisitor(llvm::make_unique<DeleteBugVisitor>());
+  C.emitReport(std::move(R));
+}
+
+std::shared_ptr<PathDiagnosticPiece>
+DeleteWithNonVirtualDtorChecker::DeleteBugVisitor::VisitNode(
+    const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
+    BugReport &BR) {
+  // Stop traversal after the first conversion was found on a path.
+  if (Satisfied)
+    return nullptr;
+
+  ProgramStateRef State = N->getState();
+  const LocationContext *LC = N->getLocationContext();
+  const Stmt *S = PathDiagnosticLocation::getStmt(N);
+  if (!S)
+    return nullptr;
+
+  const auto *CastE = dyn_cast<CastExpr>(S);
+  if (!CastE)
+    return nullptr;
+
+  // Only interested in DerivedToBase implicit casts.
+  // Explicit casts can have different CastKinds.
+  if (const auto *ImplCastE = dyn_cast<ImplicitCastExpr>(CastE)) {
+    if (ImplCastE->getCastKind() != CK_DerivedToBase)
+      return nullptr;
+  }
+
+  // Region associated with the current cast expression.
+  const MemRegion *M = State->getSVal(CastE, LC).getAsRegion();
+  if (!M)
+    return nullptr;
+
+  // Check if target region was marked as problematic previously.
+  if (!BR.isInteresting(M))
+    return nullptr;
+
+  // Stop traversal on this path.
+  Satisfied = true;
+
+  SmallString<256> Buf;
+  llvm::raw_svector_ostream OS(Buf);
+  OS << "Conversion from derived to base happened here";
+  PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
+                             N->getLocationContext());
+  return std::make_shared<PathDiagnosticEventPiece>(Pos, OS.str(), true,
+                                                    nullptr);
+}
+
+void ento::registerDeleteWithNonVirtualDtorChecker(CheckerManager &mgr) {
+  mgr.registerChecker<DeleteWithNonVirtualDtorChecker>();
+}
diff --git a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 0891ea8..26fd83f 100644
--- a/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -626,7 +626,7 @@
       : public RecursiveASTVisitor<IsObjCTypeParamDependentTypeVisitor> {
   public:
     IsObjCTypeParamDependentTypeVisitor() : Result(false) {}
-    bool VisitObjCTypeParamType(const ObjCTypeParamType *Type) {
+    bool VisitTypedefType(const TypedefType *Type) {
       if (isa<ObjCTypeParamDecl>(Type->getDecl())) {
         Result = true;
         return false;
diff --git a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
index 32040e7..0005ec4 100644
--- a/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
@@ -8,10 +8,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Checkers/SValExplainer.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/IssueHash.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Checkers/SValExplainer.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ScopedPrinter.h"
 
@@ -41,6 +42,7 @@
   void analyzerExplain(const CallExpr *CE, CheckerContext &C) const;
   void analyzerPrintState(const CallExpr *CE, CheckerContext &C) const;
   void analyzerGetExtent(const CallExpr *CE, CheckerContext &C) const;
+  void analyzerHashDump(const CallExpr *CE, CheckerContext &C) const;
 
   typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
                                                  CheckerContext &C) const;
@@ -79,6 +81,7 @@
           &ExprInspectionChecker::analyzerPrintState)
     .Case("clang_analyzer_numTimesReached",
           &ExprInspectionChecker::analyzerNumTimesReached)
+    .Case("clang_analyzer_hashDump", &ExprInspectionChecker::analyzerHashDump)
     .Default(nullptr);
 
   if (!Handler)
@@ -272,6 +275,7 @@
 
     reportBug(llvm::to_string(NumTimesReached), BR, N);
   }
+  ReachedStats.clear();
 }
 
 void ExprInspectionChecker::analyzerCrash(const CallExpr *CE,
@@ -279,7 +283,18 @@
   LLVM_BUILTIN_TRAP;
 }
 
+void ExprInspectionChecker::analyzerHashDump(const CallExpr *CE,
+                                             CheckerContext &C) const {
+  const LangOptions &Opts = C.getLangOpts();
+  const SourceManager &SM = C.getSourceManager();
+  FullSourceLoc FL(CE->getArg(0)->getLocStart(), SM);
+  std::string HashContent =
+      GetIssueString(SM, FL, getCheckName().getName(), "Category",
+                     C.getLocationContext()->getDecl(), Opts);
+
+  reportBug(HashContent, C);
+}
+
 void ento::registerExprInspectionChecker(CheckerManager &Mgr) {
   Mgr.registerChecker<ExprInspectionChecker>();
 }
-
diff --git a/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp b/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp
index decc552..497978f 100644
--- a/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MisusedMovedObjectChecker.cpp
@@ -56,8 +56,11 @@
                      ArrayRef<const MemRegion *> ExplicitRegions,
                      ArrayRef<const MemRegion *> Regions,
                      const LocationContext *LCtx, const CallEvent *Call) const;
+  void printState(raw_ostream &Out, ProgramStateRef State,
+                  const char *NL, const char *Sep) const override;
 
 private:
+  enum MisuseKind {MK_FunCall, MK_Copy, MK_Move};
   class MovedBugVisitor : public BugReporterVisitorImpl<MovedBugVisitor> {
   public:
     MovedBugVisitor(const MemRegion *R) : Region(R), Found(false) {}
@@ -81,7 +84,7 @@
 
   mutable std::unique_ptr<BugType> BT;
   ExplodedNode *reportBug(const MemRegion *Region, const CallEvent &Call,
-                          CheckerContext &C, bool isCopy) const;
+                          CheckerContext &C, MisuseKind MK) const;
   bool isInMoveSafeContext(const LocationContext *LC) const;
   bool isStateResetMethod(const CXXMethodDecl *MethodDec) const;
   bool isMoveSafeMethod(const CXXMethodDecl *MethodDec) const;
@@ -177,7 +180,7 @@
 ExplodedNode *MisusedMovedObjectChecker::reportBug(const MemRegion *Region,
                                                    const CallEvent &Call,
                                                    CheckerContext &C,
-                                                   bool isCopy = false) const {
+                                                   MisuseKind MK) const {
   if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
     if (!BT)
       BT.reset(new BugType(this, "Usage of a 'moved-from' object",
@@ -193,10 +196,17 @@
 
     // Creating the error message.
     std::string ErrorMessage;
-    if (isCopy)
-      ErrorMessage = "Copying a 'moved-from' object";
-    else
-      ErrorMessage = "Method call on a 'moved-from' object";
+    switch(MK) {
+      case MK_FunCall:
+        ErrorMessage = "Method call on a 'moved-from' object";
+        break;
+      case MK_Copy:
+        ErrorMessage = "Copying a 'moved-from' object";
+        break;
+      case MK_Move:
+        ErrorMessage = "Moving a 'moved-from' object";
+        break;
+    }
     if (const auto DecReg = Region->getAs<DeclRegion>()) {
       const auto *RegionDecl = dyn_cast<NamedDecl>(DecReg->getDecl());
       ErrorMessage += " '" + RegionDecl->getNameAsString() + "'";
@@ -350,7 +360,7 @@
   const LocationContext *LC = C.getLocationContext();
   ExplodedNode *N = nullptr;
 
-  // Remove the MemRegions from the map on which a ctor/dtor call or assignement
+  // Remove the MemRegions from the map on which a ctor/dtor call or assignment
   // happened.
 
   // Checking constructor calls.
@@ -363,7 +373,10 @@
       const RegionState *ArgState = State->get<TrackedRegionMap>(ArgRegion);
       if (ArgState && ArgState->isMoved()) {
         if (!isInMoveSafeContext(LC)) {
-          N = reportBug(ArgRegion, Call, C, /*isCopy=*/true);
+          if(CtorDec->isMoveConstructor())
+            N = reportBug(ArgRegion, Call, C, MK_Move);
+          else
+            N = reportBug(ArgRegion, Call, C, MK_Copy);
           State = State->set<TrackedRegionMap>(ArgRegion,
                                                RegionState::getReported());
         }
@@ -378,8 +391,11 @@
     return;
   // In case of destructor call we do not track the object anymore.
   const MemRegion *ThisRegion = IC->getCXXThisVal().getAsRegion();
+  if (!ThisRegion)
+    return;
+
   if (dyn_cast_or_null<CXXDestructorDecl>(Call.getDecl())) {
-    State = removeFromState(State, IC->getCXXThisVal().getAsRegion());
+    State = removeFromState(State, ThisRegion);
     C.addTransition(State);
     return;
   }
@@ -400,7 +416,10 @@
           State->get<TrackedRegionMap>(IC->getArgSVal(0).getAsRegion());
       if (ArgState && ArgState->isMoved() && !isInMoveSafeContext(LC)) {
         const MemRegion *ArgRegion = IC->getArgSVal(0).getAsRegion();
-        N = reportBug(ArgRegion, Call, C, /*isCopy=*/true);
+        if(MethodDecl->isMoveAssignmentOperator())
+          N = reportBug(ArgRegion, Call, C, MK_Move);
+        else
+          N = reportBug(ArgRegion, Call, C, MK_Copy);
         State =
             State->set<TrackedRegionMap>(ArgRegion, RegionState::getReported());
       }
@@ -410,28 +429,35 @@
   }
 
   // The remaining part is check only for method call on a moved-from object.
+
+  // We want to investigate the whole object, not only sub-object of a parent
+  // class in which the encountered method defined.
+  while (const CXXBaseObjectRegion *BR =
+             dyn_cast<CXXBaseObjectRegion>(ThisRegion))
+    ThisRegion = BR->getSuperRegion();
+
   if (isMoveSafeMethod(MethodDecl))
     return;
 
   if (isStateResetMethod(MethodDecl)) {
-    State = State->remove<TrackedRegionMap>(ThisRegion);
+    State = removeFromState(State, ThisRegion);
     C.addTransition(State);
     return;
   }
 
-  // If it is already reported then we dont report the bug again.
+  // If it is already reported then we don't report the bug again.
   const RegionState *ThisState = State->get<TrackedRegionMap>(ThisRegion);
   if (!(ThisState && ThisState->isMoved()))
     return;
 
-  // Dont report it in case if any base region is already reported
+  // Don't report it in case if any base region is already reported
   if (isAnyBaseRegionReported(State, ThisRegion))
     return;
 
   if (isInMoveSafeContext(LC))
     return;
 
-  N = reportBug(ThisRegion, Call, C);
+  N = reportBug(ThisRegion, Call, C, MK_FunCall);
   State = State->set<TrackedRegionMap>(ThisRegion, RegionState::getReported());
   C.addTransition(State, N);
 }
@@ -476,6 +502,25 @@
   return State;
 }
 
+void MisusedMovedObjectChecker::printState(raw_ostream &Out,
+                                           ProgramStateRef State,
+                                           const char *NL,
+                                           const char *Sep) const {
+
+  TrackedRegionMapTy RS = State->get<TrackedRegionMap>();
+
+  if (!RS.isEmpty()) {
+    Out << Sep << "Moved-from objects :" << NL;
+    for (auto I: RS) {
+      I.first->dumpToStream(Out);
+      if (I.second.isMoved())
+        Out << ": moved";
+      else
+        Out << ": moved and reported";
+      Out << NL;
+    }
+  }
+}
 void ento::registerMisusedMovedObjectChecker(CheckerManager &mgr) {
   mgr.registerChecker<MisusedMovedObjectChecker>();
 }
diff --git a/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp b/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
new file mode 100644
index 0000000..0b4ecb4
--- /dev/null
+++ b/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
@@ -0,0 +1,140 @@
+//==- NonnullGlobalConstantsChecker.cpp ---------------------------*- C++ -*--//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This checker adds an assumption that constant globals of certain types* are
+//  non-null, as otherwise they generally do not convey any useful information.
+//  The assumption is useful, as many framework use e. g. global const strings,
+//  and the analyzer might not be able to infer the global value if the
+//  definition is in a separate translation unit.
+//  The following types (and their typedef aliases) are considered to be
+//  non-null:
+//   - `char* const`
+//   - `const CFStringRef` from CoreFoundation
+//   - `NSString* const` from Foundation
+//   - `CFBooleanRef` from Foundation
+//
+//===----------------------------------------------------------------------===//
+
+#include "ClangSACheckers.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+class NonnullGlobalConstantsChecker : public Checker<check::Location> {
+  mutable IdentifierInfo *NSStringII = nullptr;
+  mutable IdentifierInfo *CFStringRefII = nullptr;
+  mutable IdentifierInfo *CFBooleanRefII = nullptr;
+
+public:
+  NonnullGlobalConstantsChecker() {}
+
+  void checkLocation(SVal l, bool isLoad, const Stmt *S,
+                     CheckerContext &C) const;
+
+private:
+  void initIdentifierInfo(ASTContext &Ctx) const;
+
+  bool isGlobalConstString(SVal V) const;
+
+  bool isNonnullType(QualType Ty) const;
+};
+
+} // namespace
+
+/// Lazily initialize cache for required identifier informations.
+void NonnullGlobalConstantsChecker::initIdentifierInfo(ASTContext &Ctx) const {
+  if (NSStringII)
+    return;
+
+  NSStringII = &Ctx.Idents.get("NSString");
+  CFStringRefII = &Ctx.Idents.get("CFStringRef");
+  CFBooleanRefII = &Ctx.Idents.get("CFBooleanRef");
+}
+
+/// Add an assumption that const string-like globals are non-null.
+void NonnullGlobalConstantsChecker::checkLocation(SVal location, bool isLoad,
+                                                 const Stmt *S,
+                                                 CheckerContext &C) const {
+  initIdentifierInfo(C.getASTContext());
+  if (!isLoad || !location.isValid())
+    return;
+
+  ProgramStateRef State = C.getState();
+  SVal V = State->getSVal(location.castAs<Loc>());
+
+  if (isGlobalConstString(location)) {
+    Optional<DefinedOrUnknownSVal> Constr = V.getAs<DefinedOrUnknownSVal>();
+
+    if (Constr) {
+
+      // Assume that the variable is non-null.
+      ProgramStateRef OutputState = State->assume(*Constr, true);
+      C.addTransition(OutputState);
+    }
+  }
+}
+
+/// \param V loaded lvalue.
+/// \return whether {@code val} is a string-like const global.
+bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V) const {
+  Optional<loc::MemRegionVal> RegionVal = V.getAs<loc::MemRegionVal>();
+  if (!RegionVal)
+    return false;
+  auto *Region = dyn_cast<VarRegion>(RegionVal->getAsRegion());
+  if (!Region)
+    return false;
+  const VarDecl *Decl = Region->getDecl();
+
+  if (!Decl->hasGlobalStorage())
+    return false;
+
+  QualType Ty = Decl->getType();
+  bool HasConst = Ty.isConstQualified();
+  if (isNonnullType(Ty) && HasConst)
+    return true;
+
+  // Look through the typedefs.
+  while (auto *T = dyn_cast<TypedefType>(Ty)) {
+    Ty = T->getDecl()->getUnderlyingType();
+
+    // It is sufficient for any intermediate typedef
+    // to be classified const.
+    HasConst = HasConst || Ty.isConstQualified();
+    if (isNonnullType(Ty) && HasConst)
+      return true;
+  }
+  return false;
+}
+
+/// \return whether {@code type} is extremely unlikely to be null
+bool NonnullGlobalConstantsChecker::isNonnullType(QualType Ty) const {
+
+  if (Ty->isPointerType() && Ty->getPointeeType()->isCharType())
+    return true;
+
+  if (auto *T = dyn_cast<ObjCObjectPointerType>(Ty)) {
+    return T->getInterfaceDecl() &&
+      T->getInterfaceDecl()->getIdentifier() == NSStringII;
+  } else if (auto *T = dyn_cast<TypedefType>(Ty)) {
+    IdentifierInfo* II = T->getDecl()->getIdentifier();
+    return II == CFStringRefII || II == CFBooleanRefII;
+  }
+  return false;
+}
+
+void ento::registerNonnullGlobalConstantsChecker(CheckerManager &Mgr) {
+  Mgr.registerChecker<NonnullGlobalConstantsChecker>();
+}
diff --git a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
index b10ec84..e4737fc 100644
--- a/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/ObjCContainersASTChecker.cpp
@@ -13,7 +13,7 @@
 //===----------------------------------------------------------------------===//
 #include "ClangSACheckers.h"
 #include "clang/AST/StmtVisitor.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
diff --git a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
index 0e3a649..dab29be 100644
--- a/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/PthreadLockChecker.cpp
@@ -81,6 +81,8 @@
 public:
   void checkPostStmt(const CallExpr *CE, CheckerContext &C) const;
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
+  void printState(raw_ostream &Out, ProgramStateRef State,
+                  const char *NL, const char *Sep) const override;
 
   void AcquireLock(CheckerContext &C, const CallExpr *CE, SVal lock,
                    bool isTryLock, enum LockingSemantics semantics) const;
@@ -184,6 +186,39 @@
   return state;
 }
 
+void PthreadLockChecker::printState(raw_ostream &Out, ProgramStateRef State,
+                                    const char *NL, const char *Sep) const {
+  LockMapTy LM = State->get<LockMap>();
+  if (!LM.isEmpty()) {
+    Out << Sep << "Mutex states:" << NL;
+    for (auto I : LM) {
+      I.first->dumpToStream(Out);
+      if (I.second.isLocked())
+        Out << ": locked";
+      else if (I.second.isUnlocked())
+        Out << ": unlocked";
+      else if (I.second.isDestroyed())
+        Out << ": destroyed";
+      else if (I.second.isUntouchedAndPossiblyDestroyed())
+        Out << ": not tracked, possibly destroyed";
+      else if (I.second.isUnlockedAndPossiblyDestroyed())
+        Out << ": unlocked, possibly destroyed";
+      Out << NL;
+    }
+  }
+
+  LockSetTy LS = State->get<LockSet>();
+  if (!LS.isEmpty()) {
+    Out << Sep << "Mutex lock order:" << NL;
+    for (auto I: LS) {
+      I->dumpToStream(Out);
+      Out << NL;
+    }
+  }
+
+  // TODO: Dump destroyed mutex symbols?
+}
+
 void PthreadLockChecker::AcquireLock(CheckerContext &C, const CallExpr *CE,
                                      SVal lock, bool isTryLock,
                                      enum LockingSemantics semantics) const {
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 21ccf21..4db83af 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -462,6 +462,7 @@
   ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }
 
   friend class RetainSummaryManager;
+  friend class RetainCountChecker;
 };
 } // end anonymous namespace
 
@@ -1061,6 +1062,7 @@
 
     // Inspect the result type.
     QualType RetTy = FT->getReturnType();
+    std::string RetTyName = RetTy.getAsString();
 
     // FIXME: This should all be refactored into a chain of "summary lookup"
     //  filters.
@@ -1080,12 +1082,14 @@
       AllowAnnotations = false;
     } else if (FName == "CFPlugInInstanceCreate") {
       S = getPersistentSummary(RetEffect::MakeNoRet());
-    } else if (FName == "IOBSDNameMatching" ||
+    } else if (FName == "IORegistryEntrySearchCFProperty"
+        || (RetTyName == "CFMutableDictionaryRef" && (
+               FName == "IOBSDNameMatching" ||
                FName == "IOServiceMatching" ||
                FName == "IOServiceNameMatching" ||
-               FName == "IORegistryEntrySearchCFProperty" ||
                FName == "IORegistryEntryIDMatching" ||
-               FName == "IOOpenFirmwarePathMatching") {
+               FName == "IOOpenFirmwarePathMatching"
+            ))) {
       // Part of <rdar://problem/6961230>. (IOKit)
       // This should be addressed using a API table.
       S = getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF),
@@ -1166,6 +1170,11 @@
       if (cocoa::isRefType(RetTy, "CF", FName)) {
         if (isRetain(FD, FName)) {
           S = getUnarySummary(FT, cfretain);
+          // CFRetain isn't supposed to be annotated. However, this may as well
+          // be a user-made "safe" CFRetain function that is incorrectly
+          // annotated as cf_returns_retained due to lack of better options.
+          // We want to ignore such annotation.
+          AllowAnnotations = false;
         } else if (isAutorelease(FD, FName)) {
           S = getUnarySummary(FT, cfautorelease);
           // The headers use cf_consumed, but we can fully model CFAutorelease
@@ -1210,7 +1219,8 @@
 
     // Check for release functions, the only kind of functions that we care
     // about that don't return a pointer type.
-    if (FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) {
+    if (FName.size() >= 2 &&
+        FName[0] == 'C' && (FName[1] == 'F' || FName[1] == 'G')) {
       // Test for 'CGCF'.
       FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);
 
@@ -1319,6 +1329,13 @@
   return hasRCAnnotation(FD, "rc_ownership_trusted_implementation");
 }
 
+static bool isGeneralizedObjectRef(QualType Ty) {
+  if (Ty.getAsString().substr(0, 4) == "isl_")
+    return true;
+  else
+    return false;
+}
+
 //===----------------------------------------------------------------------===//
 // Summary creation for Selectors.
 //===----------------------------------------------------------------------===//
@@ -1340,6 +1357,8 @@
 
   if (D->hasAttr<CFReturnsRetainedAttr>())
     return RetEffect::MakeOwned(RetEffect::CF);
+  else if (hasRCAnnotation(D, "rc_ownership_returns_retained"))
+    return RetEffect::MakeOwned(RetEffect::Generalized);
 
   if (D->hasAttr<CFReturnsNotRetainedAttr>())
     return RetEffect::MakeNotOwned(RetEffect::CF);
@@ -1363,9 +1382,11 @@
     const ParmVarDecl *pd = *pi;
     if (pd->hasAttr<NSConsumedAttr>())
       Template->addArg(AF, parm_idx, DecRefMsg);
-    else if (pd->hasAttr<CFConsumedAttr>())
+    else if (pd->hasAttr<CFConsumedAttr>() ||
+             hasRCAnnotation(pd, "rc_ownership_consumed"))
       Template->addArg(AF, parm_idx, DecRef);
-    else if (pd->hasAttr<CFReturnsRetainedAttr>()) {
+    else if (pd->hasAttr<CFReturnsRetainedAttr>() ||
+             hasRCAnnotation(pd, "rc_ownership_returns_retained")) {
       QualType PointeeTy = pd->getType()->getPointeeType();
       if (!PointeeTy.isNull())
         if (coreFoundation::isCFObjectRef(PointeeTy))
@@ -1844,6 +1865,15 @@
 
   class CFRefLeakReport : public CFRefReport {
     const MemRegion* AllocBinding;
+    const Stmt *AllocStmt;
+
+    // Finds the function declaration where a leak warning for the parameter 'sym' should be raised.
+    void deriveParamLocation(CheckerContext &Ctx, SymbolRef sym);
+    // Finds the location where a leak warning for 'sym' should be raised.
+    void deriveAllocLocation(CheckerContext &Ctx, SymbolRef sym);
+    // Produces description of a leak warning which is printed on the console.
+    void createDescription(CheckerContext &Ctx, bool GCEnabled, bool IncludeAllocationLine);
+
   public:
     CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts, bool GCEnabled,
                     const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
@@ -1999,17 +2029,15 @@
       }
 
       if (CurrV.getObjKind() == RetEffect::CF) {
-        if (Sym->getType().isNull()) {
-          os << " returns a Core Foundation object with a ";
-        } else {
-          os << " returns a Core Foundation object of type "
-             << Sym->getType().getAsString() << " with a ";
-        }
-      }
-      else {
+        os << " returns a Core Foundation object of type "
+           << Sym->getType().getAsString() << " with a ";
+      } else if (CurrV.getObjKind() == RetEffect::Generalized) {
+        os << " returns an object of type " << Sym->getType().getAsString()
+           << " with a ";
+      } else {
         assert (CurrV.getObjKind() == RetEffect::ObjC);
         QualType T = Sym->getType();
-        if (T.isNull() || !isa<ObjCObjectPointerType>(T)) {
+        if (!isa<ObjCObjectPointerType>(T)) {
           os << " returns an Objective-C object with a ";
         } else {
           const ObjCObjectPointerType *PT = cast<ObjCObjectPointerType>(T);
@@ -2425,13 +2453,25 @@
   return llvm::make_unique<PathDiagnosticEventPiece>(L, os.str());
 }
 
-CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
-                                 bool GCEnabled, const SummaryLogTy &Log,
-                                 ExplodedNode *n, SymbolRef sym,
-                                 CheckerContext &Ctx,
-                                 bool IncludeAllocationLine)
-  : CFRefReport(D, LOpts, GCEnabled, Log, n, sym, false) {
+void CFRefLeakReport::deriveParamLocation(CheckerContext &Ctx, SymbolRef sym) {
+  const SourceManager& SMgr = Ctx.getSourceManager();
 
+  if (!sym->getOriginRegion())
+    return;
+
+  auto *Region = dyn_cast<DeclRegion>(sym->getOriginRegion());
+  if (Region) {
+    const Decl *PDecl = Region->getDecl();
+    if (PDecl && isa<ParmVarDecl>(PDecl)) {
+      PathDiagnosticLocation ParamLocation = PathDiagnosticLocation::create(PDecl, SMgr);
+      Location = ParamLocation;
+      UniqueingLocation = ParamLocation;
+      UniqueingDecl = Ctx.getLocationContext()->getDecl();
+    }
+  }
+}
+
+void CFRefLeakReport::deriveAllocLocation(CheckerContext &Ctx,SymbolRef sym) {
   // Most bug reports are cached at the location where they occurred.
   // With leaks, we want to unique them by the location where they were
   // allocated, and only report a single path.  To do this, we need to find
@@ -2455,8 +2495,12 @@
   // FIXME: This will crash the analyzer if an allocation comes from an
   // implicit call (ex: a destructor call).
   // (Currently there are no such allocations in Cocoa, though.)
-  const Stmt *AllocStmt = PathDiagnosticLocation::getStmt(AllocNode);
-  assert(AllocStmt && "Cannot find allocation statement");
+  AllocStmt = PathDiagnosticLocation::getStmt(AllocNode);
+
+  if (!AllocStmt) {
+    AllocBinding = nullptr;
+    return;
+  }
 
   PathDiagnosticLocation AllocLocation =
     PathDiagnosticLocation::createBegin(AllocStmt, SMgr,
@@ -2467,8 +2511,10 @@
   // leaks should be uniqued on the allocation site.
   UniqueingLocation = AllocLocation;
   UniqueingDecl = AllocNode->getLocationContext()->getDecl();
+}
 
-  // Fill in the description of the bug.
+void CFRefLeakReport::createDescription(CheckerContext &Ctx, bool GCEnabled, bool IncludeAllocationLine) {
+  assert(Location.isValid() && UniqueingDecl && UniqueingLocation.isValid());
   Description.clear();
   llvm::raw_string_ostream os(Description);
   os << "Potential leak ";
@@ -2483,6 +2529,20 @@
       os << " (allocated on line " << SL.getSpellingLineNumber() << ")";
     }
   }
+}
+
+CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
+                                 bool GCEnabled, const SummaryLogTy &Log,
+                                 ExplodedNode *n, SymbolRef sym,
+                                 CheckerContext &Ctx,
+                                 bool IncludeAllocationLine)
+  : CFRefReport(D, LOpts, GCEnabled, Log, n, sym, false) {
+
+  deriveAllocLocation(Ctx, sym);
+  if (!AllocBinding)
+    deriveParamLocation(Ctx, sym);
+
+  createDescription(Ctx, GCEnabled, IncludeAllocationLine);
 
   addVisitor(llvm::make_unique<CFRefLeakReportVisitor>(sym, GCEnabled, Log));
 }
@@ -2496,6 +2556,7 @@
   : public Checker< check::Bind,
                     check::DeadSymbols,
                     check::EndAnalysis,
+                    check::BeginFunction,
                     check::EndFunction,
                     check::PostStmt<BlockExpr>,
                     check::PostStmt<CastExpr>,
@@ -2680,6 +2741,7 @@
                                 SymbolRef Sym, ProgramStateRef state) const;
 
   void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
+  void checkBeginFunction(CheckerContext &C) const;
   void checkEndFunction(CheckerContext &C) const;
 
   ProgramStateRef updateSymbol(ProgramStateRef state, SymbolRef sym,
@@ -3901,6 +3963,36 @@
   return N;
 }
 
+void RetainCountChecker::checkBeginFunction(CheckerContext &Ctx) const {
+  if (!Ctx.inTopFrame())
+    return;
+
+  const LocationContext *LCtx = Ctx.getLocationContext();
+  const FunctionDecl *FD = dyn_cast<FunctionDecl>(LCtx->getDecl());
+
+  if (!FD || isTrustedReferenceCountImplementation(FD))
+    return;
+
+  ProgramStateRef state = Ctx.getState();
+
+  const RetainSummary *FunctionSummary = getSummaryManager(Ctx).getFunctionSummary(FD);
+  ArgEffects CalleeSideArgEffects = FunctionSummary->getArgEffects();
+
+  for (unsigned idx = 0, e = FD->getNumParams(); idx != e; ++idx) {
+    const ParmVarDecl *Param = FD->getParamDecl(idx);
+    SymbolRef Sym = state->getSVal(state->getRegion(Param, LCtx)).getAsSymbol();
+
+    QualType Ty = Param->getType();
+    const ArgEffect *AE = CalleeSideArgEffects.lookup(idx);
+    if (AE && *AE == DecRef && isGeneralizedObjectRef(Ty))
+      state = setRefBinding(state, Sym, RefVal::makeOwned(RetEffect::ObjKind::Generalized, Ty));
+    else if (isGeneralizedObjectRef(Ty))
+      state = setRefBinding(state, Sym, RefVal::makeNotOwned(RetEffect::ObjKind::Generalized, Ty));
+  }
+
+  Ctx.addTransition(state);
+}
+
 void RetainCountChecker::checkEndFunction(CheckerContext &Ctx) const {
   ProgramStateRef state = Ctx.getState();
   RefBindingsTy B = state->get<RefBindings>();
diff --git a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
index f3c2ffc..172ce34 100644
--- a/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
@@ -59,6 +59,11 @@
   return StOutBound && !StInBound;
 }
 
+static bool isShiftOverflow(const BinaryOperator *B, CheckerContext &C) {
+  return C.isGreaterOrEqual(
+      B->getRHS(), C.getASTContext().getIntWidth(B->getLHS()->getType()));
+}
+
 void UndefResultChecker::checkPostStmt(const BinaryOperator *B,
                                        CheckerContext &C) const {
   ProgramStateRef state = C.getState();
@@ -97,18 +102,50 @@
     }
 
     if (Ex) {
-      OS << "The " << (isLeft ? "left" : "right")
-         << " operand of '"
+      OS << "The " << (isLeft ? "left" : "right") << " operand of '"
          << BinaryOperator::getOpcodeStr(B->getOpcode())
          << "' is a garbage value";
       if (isArrayIndexOutOfBounds(C, Ex))
         OS << " due to array index out of bounds";
-    }
-    else {
+    } else {
       // Neither operand was undefined, but the result is undefined.
-      OS << "The result of the '"
-         << BinaryOperator::getOpcodeStr(B->getOpcode())
-         << "' expression is undefined";
+      if ((B->getOpcode() == BinaryOperatorKind::BO_Shl ||
+           B->getOpcode() == BinaryOperatorKind::BO_Shr) &&
+          C.isNegative(B->getRHS())) {
+        OS << "The result of the "
+           << ((B->getOpcode() == BinaryOperatorKind::BO_Shl) ? "left"
+                                                              : "right")
+           << " shift is undefined because the right operand is negative";
+      } else if ((B->getOpcode() == BinaryOperatorKind::BO_Shl ||
+                  B->getOpcode() == BinaryOperatorKind::BO_Shr) &&
+                 isShiftOverflow(B, C)) {
+
+        OS << "The result of the "
+           << ((B->getOpcode() == BinaryOperatorKind::BO_Shl) ? "left"
+                                                              : "right")
+           << " shift is undefined due to shifting by ";
+
+        SValBuilder &SB = C.getSValBuilder();
+        const llvm::APSInt *I =
+            SB.getKnownValue(C.getState(), C.getSVal(B->getRHS()));
+        if (!I)
+          OS << "a value that is";
+        else if (I->isUnsigned())
+          OS << '\'' << I->getZExtValue() << "\', which is";
+        else
+          OS << '\'' << I->getSExtValue() << "\', which is";
+
+        OS << " greater or equal to the width of type '"
+           << B->getLHS()->getType().getAsString() << "'.";
+      } else if (B->getOpcode() == BinaryOperatorKind::BO_Shl &&
+                 C.isNegative(B->getLHS())) {
+        OS << "The result of the left shift is undefined because the left "
+              "operand is negative";
+      } else {
+        OS << "The result of the '"
+           << BinaryOperator::getOpcodeStr(B->getOpcode())
+           << "' expression is undefined";
+      }
     }
     auto report = llvm::make_unique<BugReport>(*BT, OS.str(), N);
     if (Ex) {
diff --git a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
index ccd8e9a..6f21e86 100644
--- a/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/UnreachableCodeChecker.cpp
@@ -112,7 +112,7 @@
       continue;
 
     // Check for false positives
-    if (CB->size() > 0 && isInvalidPath(CB, *PM))
+    if (isInvalidPath(CB, *PM))
       continue;
 
     // It is good practice to always have a "default" label in a "switch", even
diff --git a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
index b47762b..c5010f5 100644
--- a/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/VirtualCallChecker.cpp
@@ -14,279 +14,272 @@
 
 #include "ClangSACheckers.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/StmtVisitor.h"
 #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
 #include "clang/StaticAnalyzer/Core/Checker.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/SaveAndRestore.h"
-#include "llvm/Support/raw_ostream.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
 
 using namespace clang;
 using namespace ento;
 
 namespace {
+enum class ObjectState : bool { CtorCalled, DtorCalled };
+} // end namespace
+  // FIXME: Ascending over StackFrameContext maybe another method.
 
-class WalkAST : public StmtVisitor<WalkAST> {
-  const CheckerBase *Checker;
-  BugReporter &BR;
-  AnalysisDeclContext *AC;
-
-  /// The root constructor or destructor whose callees are being analyzed.
-  const CXXMethodDecl *RootMethod = nullptr;
-
-  /// Whether the checker should walk into bodies of called functions.
-  /// Controlled by the "Interprocedural" analyzer-config option.
-  bool IsInterprocedural = false;
-
-  /// Whether the checker should only warn for calls to pure virtual functions
-  /// (which is undefined behavior) or for all virtual functions (which may
-  /// may result in unexpected behavior).
-  bool ReportPureOnly = false;
-
-  typedef const CallExpr * WorkListUnit;
-  typedef SmallVector<WorkListUnit, 20> DFSWorkList;
-
-  /// A vector representing the worklist which has a chain of CallExprs.
-  DFSWorkList WList;
-
-  // PreVisited : A CallExpr to this FunctionDecl is in the worklist, but the
-  // body has not been visited yet.
-  // PostVisited : A CallExpr to this FunctionDecl is in the worklist, and the
-  // body has been visited.
-  enum Kind { NotVisited,
-              PreVisited,  /**< A CallExpr to this FunctionDecl is in the
-                                worklist, but the body has not yet been
-                                visited. */
-              PostVisited  /**< A CallExpr to this FunctionDecl is in the
-                                worklist, and the body has been visited. */
-  };
-
-  /// A DenseMap that records visited states of FunctionDecls.
-  llvm::DenseMap<const FunctionDecl *, Kind> VisitedFunctions;
-
-  /// The CallExpr whose body is currently being visited.  This is used for
-  /// generating bug reports.  This is null while visiting the body of a
-  /// constructor or destructor.
-  const CallExpr *visitingCallExpr;
-
-public:
-  WalkAST(const CheckerBase *checker, BugReporter &br, AnalysisDeclContext *ac,
-          const CXXMethodDecl *rootMethod, bool isInterprocedural,
-          bool reportPureOnly)
-      : Checker(checker), BR(br), AC(ac), RootMethod(rootMethod),
-        IsInterprocedural(isInterprocedural), ReportPureOnly(reportPureOnly),
-        visitingCallExpr(nullptr) {
-    // Walking should always start from either a constructor or a destructor.
-    assert(isa<CXXConstructorDecl>(rootMethod) ||
-           isa<CXXDestructorDecl>(rootMethod));
+namespace llvm {
+template <> struct FoldingSetTrait<ObjectState> {
+  static inline void Profile(ObjectState X, FoldingSetNodeID &ID) {
+    ID.AddInteger(static_cast<int>(X));
   }
-
-  bool hasWork() const { return !WList.empty(); }
-
-  /// This method adds a CallExpr to the worklist and marks the callee as
-  /// being PreVisited.
-  void Enqueue(WorkListUnit WLUnit) {
-    const FunctionDecl *FD = WLUnit->getDirectCallee();
-    if (!FD || !FD->getBody())
-      return;
-    Kind &K = VisitedFunctions[FD];
-    if (K != NotVisited)
-      return;
-    K = PreVisited;
-    WList.push_back(WLUnit);
-  }
-
-  /// This method returns an item from the worklist without removing it.
-  WorkListUnit Dequeue() {
-    assert(!WList.empty());
-    return WList.back();
-  }
-
-  void Execute() {
-    while (hasWork()) {
-      WorkListUnit WLUnit = Dequeue();
-      const FunctionDecl *FD = WLUnit->getDirectCallee();
-      assert(FD && FD->getBody());
-
-      if (VisitedFunctions[FD] == PreVisited) {
-        // If the callee is PreVisited, walk its body.
-        // Visit the body.
-        SaveAndRestore<const CallExpr *> SaveCall(visitingCallExpr, WLUnit);
-        Visit(FD->getBody());
-
-        // Mark the function as being PostVisited to indicate we have
-        // scanned the body.
-        VisitedFunctions[FD] = PostVisited;
-        continue;
-      }
-
-      // Otherwise, the callee is PostVisited.
-      // Remove it from the worklist.
-      assert(VisitedFunctions[FD] == PostVisited);
-      WList.pop_back();
-    }
-  }
-
-  // Stmt visitor methods.
-  void VisitCallExpr(CallExpr *CE);
-  void VisitCXXMemberCallExpr(CallExpr *CE);
-  void VisitStmt(Stmt *S) { VisitChildren(S); }
-  void VisitChildren(Stmt *S);
-
-  void ReportVirtualCall(const CallExpr *CE, bool isPure);
-
 };
-} // end anonymous namespace
-
-//===----------------------------------------------------------------------===//
-// AST walking.
-//===----------------------------------------------------------------------===//
-
-void WalkAST::VisitChildren(Stmt *S) {
-  for (Stmt *Child : S->children())
-    if (Child)
-      Visit(Child);
-}
-
-void WalkAST::VisitCallExpr(CallExpr *CE) {
-  VisitChildren(CE);
-  if (IsInterprocedural)
-    Enqueue(CE);
-}
-
-void WalkAST::VisitCXXMemberCallExpr(CallExpr *CE) {
-  VisitChildren(CE);
-  bool callIsNonVirtual = false;
-
-  // Several situations to elide for checking.
-  if (MemberExpr *CME = dyn_cast<MemberExpr>(CE->getCallee())) {
-    // If the member access is fully qualified (i.e., X::F), then treat
-    // this as a non-virtual call and do not warn.
-    if (CME->getQualifier())
-      callIsNonVirtual = true;
-
-    if (Expr *base = CME->getBase()->IgnoreImpCasts()) {
-      // Elide analyzing the call entirely if the base pointer is not 'this'.
-      if (!isa<CXXThisExpr>(base))
-        return;
-
-      // If the most derived class is marked final, we know that now subclass
-      // can override this member.
-      if (base->getBestDynamicClassType()->hasAttr<FinalAttr>())
-        callIsNonVirtual = true;
-    }
-  }
-
-  // Get the callee.
-  const CXXMethodDecl *MD =
-      dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee());
-  if (MD && MD->isVirtual() && !callIsNonVirtual && !MD->hasAttr<FinalAttr>() &&
-      !MD->getParent()->hasAttr<FinalAttr>())
-    ReportVirtualCall(CE, MD->isPure());
-
-  if (IsInterprocedural)
-    Enqueue(CE);
-}
-
-void WalkAST::ReportVirtualCall(const CallExpr *CE, bool isPure) {
-  if (ReportPureOnly && !isPure)
-    return;
-
-  SmallString<100> buf;
-  llvm::raw_svector_ostream os(buf);
-
-  // FIXME: The interprocedural diagnostic experience here is not good.
-  // Ultimately this checker should be re-written to be path sensitive.
-  // For now, only diagnose intraprocedurally, by default.
-  if (IsInterprocedural) {
-    os << "Call Path : ";
-    // Name of current visiting CallExpr.
-    os << *CE->getDirectCallee();
-
-    // Name of the CallExpr whose body is current being walked.
-    if (visitingCallExpr)
-      os << " <-- " << *visitingCallExpr->getDirectCallee();
-    // Names of FunctionDecls in worklist with state PostVisited.
-    for (SmallVectorImpl<const CallExpr *>::iterator I = WList.end(),
-         E = WList.begin(); I != E; --I) {
-      const FunctionDecl *FD = (*(I-1))->getDirectCallee();
-      assert(FD);
-      if (VisitedFunctions[FD] == PostVisited)
-        os << " <-- " << *FD;
-    }
-
-    os << "\n";
-  }
-
-  PathDiagnosticLocation CELoc =
-    PathDiagnosticLocation::createBegin(CE, BR.getSourceManager(), AC);
-  SourceRange R = CE->getCallee()->getSourceRange();
-
-  os << "Call to ";
-  if (isPure)
-    os << "pure ";
-
-  os << "virtual function during ";
-
-  if (isa<CXXConstructorDecl>(RootMethod))
-    os << "construction ";
-  else
-    os << "destruction ";
-
-  if (isPure)
-    os << "has undefined behavior";
-  else
-    os << "will not dispatch to derived class";
-
-  BR.EmitBasicReport(AC->getDecl(), Checker,
-                     "Call to virtual function during construction or "
-                     "destruction",
-                     "C++ Object Lifecycle", os.str(), CELoc, R);
-}
-
-//===----------------------------------------------------------------------===//
-// VirtualCallChecker
-//===----------------------------------------------------------------------===//
+} // end namespace llvm
 
 namespace {
-class VirtualCallChecker : public Checker<check::ASTDecl<CXXRecordDecl> > {
+class VirtualCallChecker
+    : public Checker<check::BeginFunction, check::EndFunction, check::PreCall> {
+  mutable std::unique_ptr<BugType> BT;
+
 public:
-  DefaultBool isInterprocedural;
-  DefaultBool isPureOnly;
+  // The flag to determine if pure virtual functions should be issued only.
+  DefaultBool IsPureOnly;
 
-  void checkASTDecl(const CXXRecordDecl *RD, AnalysisManager& mgr,
-                    BugReporter &BR) const {
-    AnalysisDeclContext *ADC = mgr.getAnalysisDeclContext(RD);
+  void checkBeginFunction(CheckerContext &C) const;
+  void checkEndFunction(CheckerContext &C) const;
+  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
 
-    // Check the constructors.
-    for (const auto *I : RD->ctors()) {
-      if (!I->isCopyOrMoveConstructor())
-        if (Stmt *Body = I->getBody()) {
-          WalkAST walker(this, BR, ADC, I, isInterprocedural, isPureOnly);
-          walker.Visit(Body);
-          walker.Execute();
-        }
+private:
+  void registerCtorDtorCallInState(bool IsBeginFunction,
+                                   CheckerContext &C) const;
+  void reportBug(StringRef Msg, bool PureError, const MemRegion *Reg,
+                 CheckerContext &C) const;
+
+  class VirtualBugVisitor : public BugReporterVisitorImpl<VirtualBugVisitor> {
+  private:
+    const MemRegion *ObjectRegion;
+    bool Found;
+
+  public:
+    VirtualBugVisitor(const MemRegion *R) : ObjectRegion(R), Found(false) {}
+
+    void Profile(llvm::FoldingSetNodeID &ID) const override {
+      static int X = 0;
+      ID.AddPointer(&X);
+      ID.AddPointer(ObjectRegion);
     }
 
-    // Check the destructor.
-    if (CXXDestructorDecl *DD = RD->getDestructor())
-      if (Stmt *Body = DD->getBody()) {
-        WalkAST walker(this, BR, ADC, DD, isInterprocedural, isPureOnly);
-        walker.Visit(Body);
-        walker.Execute();
-      }
-  }
+    std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *N,
+                                                   const ExplodedNode *PrevN,
+                                                   BugReporterContext &BRC,
+                                                   BugReport &BR) override;
+  };
 };
+} // end namespace
+
+// GDM (generic data map) to the memregion of this for the ctor and dtor.
+REGISTER_MAP_WITH_PROGRAMSTATE(CtorDtorMap, const MemRegion *, ObjectState)
+
+std::shared_ptr<PathDiagnosticPiece>
+VirtualCallChecker::VirtualBugVisitor::VisitNode(const ExplodedNode *N,
+                                                 const ExplodedNode *PrevN,
+                                                 BugReporterContext &BRC,
+                                                 BugReport &BR) {
+  // We need the last ctor/dtor which call the virtual function.
+  // The visitor walks the ExplodedGraph backwards.
+  if (Found)
+    return nullptr;
+
+  ProgramStateRef State = N->getState();
+  const LocationContext *LCtx = N->getLocationContext();
+  const CXXConstructorDecl *CD =
+      dyn_cast_or_null<CXXConstructorDecl>(LCtx->getDecl());
+  const CXXDestructorDecl *DD =
+      dyn_cast_or_null<CXXDestructorDecl>(LCtx->getDecl());
+
+  if (!CD && !DD)
+    return nullptr;
+
+  ProgramStateManager &PSM = State->getStateManager();
+  auto &SVB = PSM.getSValBuilder();
+  const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl());
+  if (!MD)
+    return nullptr;
+  auto ThiSVal =
+      State->getSVal(SVB.getCXXThis(MD, LCtx->getCurrentStackFrame()));
+  const MemRegion *Reg = ThiSVal.castAs<loc::MemRegionVal>().getRegion();
+  if (!Reg)
+    return nullptr;
+  if (Reg != ObjectRegion)
+    return nullptr;
+
+  const Stmt *S = PathDiagnosticLocation::getStmt(N);
+  if (!S)
+    return nullptr;
+  Found = true;
+
+  std::string InfoText;
+  if (CD)
+    InfoText = "This constructor of an object of type '" +
+               CD->getNameAsString() +
+               "' has not returned when the virtual method was called";
+  else
+    InfoText = "This destructor of an object of type '" +
+               DD->getNameAsString() +
+               "' has not returned when the virtual method was called";
+
+  // Generate the extra diagnostic.
+  PathDiagnosticLocation Pos(S, BRC.getSourceManager(),
+                             N->getLocationContext());
+  return std::make_shared<PathDiagnosticEventPiece>(Pos, InfoText, true);
+}
+
+// The function to check if a callexpr is a virtual function.
+static bool isVirtualCall(const CallExpr *CE) {
+  bool CallIsNonVirtual = false;
+
+  if (const MemberExpr *CME = dyn_cast<MemberExpr>(CE->getCallee())) {
+    // The member access is fully qualified (i.e., X::F).
+    // Treat this as a non-virtual call and do not warn.
+    if (CME->getQualifier())
+      CallIsNonVirtual = true;
+
+    if (const Expr *Base = CME->getBase()) {
+      // The most derived class is marked final.
+      if (Base->getBestDynamicClassType()->hasAttr<FinalAttr>())
+        CallIsNonVirtual = true;
+    }
+  }
+
+  const CXXMethodDecl *MD =
+      dyn_cast_or_null<CXXMethodDecl>(CE->getDirectCallee());
+  if (MD && MD->isVirtual() && !CallIsNonVirtual && !MD->hasAttr<FinalAttr>() &&
+      !MD->getParent()->hasAttr<FinalAttr>())
+    return true;
+  return false;
+}
+
+// The BeginFunction callback when enter a constructor or a destructor.
+void VirtualCallChecker::checkBeginFunction(CheckerContext &C) const {
+  registerCtorDtorCallInState(true, C);
+}
+
+// The EndFunction callback when leave a constructor or a destructor.
+void VirtualCallChecker::checkEndFunction(CheckerContext &C) const {
+  registerCtorDtorCallInState(false, C);
+}
+
+void VirtualCallChecker::checkPreCall(const CallEvent &Call,
+                                      CheckerContext &C) const {
+  const auto MC = dyn_cast<CXXMemberCall>(&Call);
+  if (!MC)
+    return;
+
+  const CXXMethodDecl *MD = dyn_cast_or_null<CXXMethodDecl>(Call.getDecl());
+  if (!MD)
+    return;
+  ProgramStateRef State = C.getState();
+  const CallExpr *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
+
+  if (IsPureOnly && !MD->isPure())
+    return;
+  if (!isVirtualCall(CE))
+    return;
+
+  const MemRegion *Reg = MC->getCXXThisVal().getAsRegion();
+  const ObjectState *ObState = State->get<CtorDtorMap>(Reg);
+  if (!ObState)
+    return;
+  // Check if a virtual method is called.
+  // The GDM of constructor and destructor should be true.
+  if (*ObState == ObjectState::CtorCalled) {
+    if (IsPureOnly && MD->isPure())
+      reportBug("Call to pure virtual function during construction", true, Reg,
+                C);
+    else if (!MD->isPure())
+      reportBug("Call to virtual function during construction", false, Reg, C);
+    else
+      reportBug("Call to pure virtual function during construction", false, Reg,
+                C);
+  }
+
+  if (*ObState == ObjectState::DtorCalled) {
+    if (IsPureOnly && MD->isPure())
+      reportBug("Call to pure virtual function during destruction", true, Reg,
+                C);
+    else if (!MD->isPure())
+      reportBug("Call to virtual function during destruction", false, Reg, C);
+    else
+      reportBug("Call to pure virtual function during construction", false, Reg,
+                C);
+  }
+}
+
+void VirtualCallChecker::registerCtorDtorCallInState(bool IsBeginFunction,
+                                                     CheckerContext &C) const {
+  const auto *LCtx = C.getLocationContext();
+  const auto *MD = dyn_cast_or_null<CXXMethodDecl>(LCtx->getDecl());
+  if (!MD)
+    return;
+
+  ProgramStateRef State = C.getState();
+  auto &SVB = C.getSValBuilder();
+
+  // Enter a constructor, set the corresponding memregion be true.
+  if (isa<CXXConstructorDecl>(MD)) {
+    auto ThiSVal =
+        State->getSVal(SVB.getCXXThis(MD, LCtx->getCurrentStackFrame()));
+    const MemRegion *Reg = ThiSVal.getAsRegion();
+    if (IsBeginFunction)
+      State = State->set<CtorDtorMap>(Reg, ObjectState::CtorCalled);
+    else
+      State = State->remove<CtorDtorMap>(Reg);
+
+    C.addTransition(State);
+    return;
+  }
+
+  // Enter a Destructor, set the corresponding memregion be true.
+  if (isa<CXXDestructorDecl>(MD)) {
+    auto ThiSVal =
+        State->getSVal(SVB.getCXXThis(MD, LCtx->getCurrentStackFrame()));
+    const MemRegion *Reg = ThiSVal.getAsRegion();
+    if (IsBeginFunction)
+      State = State->set<CtorDtorMap>(Reg, ObjectState::DtorCalled);
+    else
+      State = State->remove<CtorDtorMap>(Reg);
+
+    C.addTransition(State);
+    return;
+  }
+}
+
+void VirtualCallChecker::reportBug(StringRef Msg, bool IsSink,
+                                   const MemRegion *Reg,
+                                   CheckerContext &C) const {
+  ExplodedNode *N;
+  if (IsSink)
+    N = C.generateErrorNode();
+  else
+    N = C.generateNonFatalErrorNode();
+
+  if (!N)
+    return;
+  if (!BT)
+    BT.reset(new BugType(
+        this, "Call to virtual function during construction or destruction",
+        "C++ Object Lifecycle"));
+
+  auto Reporter = llvm::make_unique<BugReport>(*BT, Msg, N);
+  Reporter->addVisitor(llvm::make_unique<VirtualBugVisitor>(Reg));
+  C.emitReport(std::move(Reporter));
 }
 
 void ento::registerVirtualCallChecker(CheckerManager &mgr) {
   VirtualCallChecker *checker = mgr.registerChecker<VirtualCallChecker>();
-  checker->isInterprocedural =
-      mgr.getAnalyzerOptions().getBooleanOption("Interprocedural", false,
-                                                checker);
 
-  checker->isPureOnly =
-      mgr.getAnalyzerOptions().getBooleanOption("PureOnly", false,
-                                                checker);
+  checker->IsPureOnly =
+      mgr.getAnalyzerOptions().getBooleanOption("PureOnly", false, checker);
 }
diff --git a/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
index 83e6766..1cc08f0 100644
--- a/lib/StaticAnalyzer/Core/AnalysisManager.cpp
+++ b/lib/StaticAnalyzer/Core/AnalysisManager.cpp
@@ -14,30 +14,25 @@
 
 void AnalysisManager::anchor() { }
 
-AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags,
-                                 const LangOptions &lang,
-                                 const PathDiagnosticConsumers &PDC,
-                                 StoreManagerCreator storemgr,
-                                 ConstraintManagerCreator constraintmgr,
-                                 CheckerManager *checkerMgr,
-                                 AnalyzerOptions &Options,
-                                 CodeInjector *injector)
-  : AnaCtxMgr(Options.UnoptimizedCFG,
-              Options.includeImplicitDtorsInCFG(),
-              /*AddInitializers=*/true,
-              Options.includeTemporaryDtorsInCFG(),
-	      Options.includeLifetimeInCFG(),
-              Options.shouldSynthesizeBodies(),
-              Options.shouldConditionalizeStaticInitializers(),
-              /*addCXXNewAllocator=*/true,
-              injector),
-    Ctx(ctx),
-    Diags(diags),
-    LangOpts(lang),
-    PathConsumers(PDC),
-    CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
-    CheckerMgr(checkerMgr),
-    options(Options) {
+AnalysisManager::AnalysisManager(
+    ASTContext &ASTCtx, DiagnosticsEngine &diags, const LangOptions &lang,
+    const PathDiagnosticConsumers &PDC, StoreManagerCreator storemgr,
+    ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr,
+    AnalyzerOptions &Options, CodeInjector *injector)
+    : AnaCtxMgr(ASTCtx, Options.UnoptimizedCFG,
+                Options.includeImplicitDtorsInCFG(),
+                /*AddInitializers=*/true, Options.includeTemporaryDtorsInCFG(),
+                Options.includeLifetimeInCFG(),
+                // Adding LoopExit elements to the CFG is a requirement for loop
+                // unrolling.
+                Options.includeLoopExitInCFG() || Options.shouldUnrollLoops(),
+                Options.shouldSynthesizeBodies(),
+                Options.shouldConditionalizeStaticInitializers(),
+                /*addCXXNewAllocator=*/true,
+                injector),
+      Ctx(ASTCtx), Diags(diags), LangOpts(lang), PathConsumers(PDC),
+      CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr),
+      CheckerMgr(checkerMgr), options(Options) {
   AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd();
 }
 
diff --git a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
index 6f48fcb..48e3e22 100644
--- a/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
+++ b/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
@@ -183,6 +183,11 @@
                           /* Default = */ false);
 }
 
+bool AnalyzerOptions::includeLoopExitInCFG() {
+  return getBooleanOption(IncludeLoopExitInCFG, "cfg-loopexit",
+          /* Default = */ false);
+}
+
 bool AnalyzerOptions::mayInlineCXXStandardLibrary() {
   return getBooleanOption(InlineCXXStandardLibrary,
                           "c++-stdlib-inlining",
@@ -375,6 +380,12 @@
   return WidenLoops.getValue();
 }
 
+bool AnalyzerOptions::shouldUnrollLoops() {
+  if (!UnrollLoops.hasValue())
+    UnrollLoops = getBooleanOption("unroll-loops", /*Default=*/false);
+  return UnrollLoops.getValue();
+}
+
 bool AnalyzerOptions::shouldDisplayNotesAsEvents() {
   if (!DisplayNotesAsEvents.hasValue())
     DisplayNotesAsEvents =
diff --git a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index ebbace4..ec7a7e9 100644
--- a/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -225,6 +225,8 @@
       // test these conditions symbolically.
 
       // FIXME: Expand these checks to include all undefined behavior.
+      if (V1.isSigned() && V1.isNegative())
+        return nullptr;
 
       if (V2.isSigned() && V2.isNegative())
         return nullptr;
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index d8fca00..4a5d25f 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -3310,6 +3310,78 @@
   return nullptr;
 }
 
+// Returns true if by simply looking at the block, we can be sure that it
+// results in a sink during analysis. This is useful to know when the analysis
+// was interrupted, and we try to figure out if it would sink eventually.
+// There may be many more reasons why a sink would appear during analysis
+// (eg. checkers may generate sinks arbitrarily), but here we only consider
+// sinks that would be obvious by looking at the CFG.
+static bool isImmediateSinkBlock(const CFGBlock *Blk) {
+  if (Blk->hasNoReturnElement())
+    return true;
+
+  // FIXME: Throw-expressions are currently generating sinks during analysis:
+  // they're not supported yet, and also often used for actually terminating
+  // the program. So we should treat them as sinks in this analysis as well,
+  // at least for now, but once we have better support for exceptions,
+  // we'd need to carefully handle the case when the throw is being
+  // immediately caught.
+  if (std::any_of(Blk->begin(), Blk->end(), [](const CFGElement &Elm) {
+        if (Optional<CFGStmt> StmtElm = Elm.getAs<CFGStmt>())
+          if (isa<CXXThrowExpr>(StmtElm->getStmt()))
+            return true;
+        return false;
+      }))
+    return true;
+
+  return false;
+}
+
+// Returns true if by looking at the CFG surrounding the node's program
+// point, we can be sure that any analysis starting from this point would
+// eventually end with a sink. We scan the child CFG blocks in a depth-first
+// manner and see if all paths eventually end up in an immediate sink block.
+static bool isInevitablySinking(const ExplodedNode *N) {
+  const CFG &Cfg = N->getCFG();
+
+  const CFGBlock *StartBlk = findBlockForNode(N);
+  if (!StartBlk)
+    return false;
+  if (isImmediateSinkBlock(StartBlk))
+    return true;
+
+  llvm::SmallVector<const CFGBlock *, 32> DFSWorkList;
+  llvm::SmallPtrSet<const CFGBlock *, 32> Visited;
+
+  DFSWorkList.push_back(StartBlk);
+  while (!DFSWorkList.empty()) {
+    const CFGBlock *Blk = DFSWorkList.back();
+    DFSWorkList.pop_back();
+    Visited.insert(Blk);
+
+    for (const auto &Succ : Blk->succs()) {
+      if (const CFGBlock *SuccBlk = Succ.getReachableBlock()) {
+        if (SuccBlk == &Cfg.getExit()) {
+          // If at least one path reaches the CFG exit, it means that control is
+          // returned to the caller. For now, say that we are not sure what
+          // happens next. If necessary, this can be improved to analyze
+          // the parent StackFrameContext's call site in a similar manner.
+          return false;
+        }
+
+        if (!isImmediateSinkBlock(SuccBlk) && !Visited.count(SuccBlk)) {
+          // If the block has reachable child blocks that aren't no-return,
+          // add them to the worklist.
+          DFSWorkList.push_back(SuccBlk);
+        }
+      }
+    }
+  }
+
+  // Nothing reached the exit. It can only mean one thing: there's no return.
+  return true;
+}
+
 static BugReport *
 FindReportInEquivalenceClass(BugReportEquivClass& EQ,
                              SmallVectorImpl<BugReport*> &bugReports) {
@@ -3360,15 +3432,10 @@
 
     // See if we are in a no-return CFG block. If so, treat this similarly
     // to being post-dominated by a sink. This works better when the analysis
-    // is incomplete and we have never reached a no-return function
-    // we're post-dominated by.
-    // This is not quite enough to handle the incomplete analysis case.
-    // We may be post-dominated in subsequent blocks, or even
-    // inter-procedurally. However, it is not clear if more complicated
-    // cases are generally worth suppressing.
-    if (const CFGBlock *B = findBlockForNode(errorNode))
-      if (B->hasNoReturnElement())
-        continue;
+    // is incomplete and we have never reached the no-return function call(s)
+    // that we'd inevitably bump into on this path.
+    if (isInevitablySinking(errorNode))
+      continue;
 
     // At this point we know that 'N' is not a sink and it has at least one
     // successor.  Use a DFS worklist to find a non-sink end-of-path node.
diff --git a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
index d00182a..f651596 100644
--- a/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -11,7 +11,7 @@
 //  enhance the diagnostics reported for a bug.
 //
 //===----------------------------------------------------------------------===//
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/Analysis/CFGStmtMap.h"
@@ -42,48 +42,80 @@
   return false;
 }
 
+/// Given that expression S represents a pointer that would be dereferenced,
+/// try to find a sub-expression from which the pointer came from.
+/// This is used for tracking down origins of a null or undefined value:
+/// "this is null because that is null because that is null" etc.
+/// We wipe away field and element offsets because they merely add offsets.
+/// We also wipe away all casts except lvalue-to-rvalue casts, because the
+/// latter represent an actual pointer dereference; however, we remove
+/// the final lvalue-to-rvalue cast before returning from this function
+/// because it demonstrates more clearly from where the pointer rvalue was
+/// loaded. Examples:
+///   x->y.z      ==>  x (lvalue)
+///   foo()->y.z  ==>  foo() (rvalue)
 const Expr *bugreporter::getDerefExpr(const Stmt *S) {
-  // Pattern match for a few useful cases:
-  //   a[0], p->f, *p
   const Expr *E = dyn_cast<Expr>(S);
   if (!E)
     return nullptr;
-  E = E->IgnoreParenCasts();
 
   while (true) {
-    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E)) {
-      assert(B->isAssignmentOp());
-      E = B->getLHS()->IgnoreParenCasts();
-      continue;
-    }
-    else if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) {
-      if (U->getOpcode() == UO_Deref)
-        return U->getSubExpr()->IgnoreParenCasts();
-    }
-    else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
-      if (ME->isImplicitAccess()) {
-        return ME;
-      } else if (ME->isArrow() || isDeclRefExprToReference(ME->getBase())) {
-        return ME->getBase()->IgnoreParenCasts();
+    if (const CastExpr *CE = dyn_cast<CastExpr>(E)) {
+      if (CE->getCastKind() == CK_LValueToRValue) {
+        // This cast represents the load we're looking for.
+        break;
+      }
+      E = CE->getSubExpr();
+    } else if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E)) {
+      // Pointer arithmetic: '*(x + 2)' -> 'x') etc.
+      if (B->getType()->isPointerType()) {
+        if (B->getLHS()->getType()->isPointerType()) {
+          E = B->getLHS();
+        } else if (B->getRHS()->getType()->isPointerType()) {
+          E = B->getRHS();
+        } else {
+          break;
+        }
       } else {
-        // If we have a member expr with a dot, the base must have been
-        // dereferenced.
-        return getDerefExpr(ME->getBase());
+        // Probably more arithmetic can be pattern-matched here,
+        // but for now give up.
+        break;
+      }
+    } else if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) {
+      if (U->getOpcode() == UO_Deref || U->getOpcode() == UO_AddrOf ||
+          (U->isIncrementDecrementOp() && U->getType()->isPointerType())) {
+        // Operators '*' and '&' don't actually mean anything.
+        // We look at casts instead.
+        E = U->getSubExpr();
+      } else {
+        // Probably more arithmetic can be pattern-matched here,
+        // but for now give up.
+        break;
       }
     }
-    else if (const ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
-      return IvarRef->getBase()->IgnoreParenCasts();
+    // Pattern match for a few useful cases: a[0], p->f, *p etc.
+    else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
+      E = ME->getBase();
+    } else if (const ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
+      E = IvarRef->getBase();
+    } else if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(E)) {
+      E = AE->getBase();
+    } else if (const ParenExpr *PE = dyn_cast<ParenExpr>(E)) {
+      E = PE->getSubExpr();
+    } else {
+      // Other arbitrary stuff.
+      break;
     }
-    else if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(E)) {
-      return getDerefExpr(AE->getBase());
-    }
-    else if (isa<DeclRefExpr>(E)) {
-      return E;
-    }
-    break;
   }
 
-  return nullptr;
+  // Special case: remove the final lvalue-to-rvalue cast, but do not recurse
+  // deeper into the sub-expression. This way we return the lvalue from which
+  // our pointer rvalue was loaded.
+  if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
+    if (CE->getCastKind() == CK_LValueToRValue)
+      E = CE->getSubExpr();
+
+  return E;
 }
 
 const Stmt *bugreporter::GetDenomExpr(const ExplodedNode *N) {
diff --git a/lib/StaticAnalyzer/Core/CMakeLists.txt b/lib/StaticAnalyzer/Core/CMakeLists.txt
index 85878f5..5ac4f94 100644
--- a/lib/StaticAnalyzer/Core/CMakeLists.txt
+++ b/lib/StaticAnalyzer/Core/CMakeLists.txt
@@ -35,6 +35,7 @@
   ExprEngineObjC.cpp
   FunctionSummary.cpp
   HTMLDiagnostics.cpp
+  LoopUnrolling.cpp
   LoopWidening.cpp
   MemRegion.cpp
   PathDiagnostic.cpp
@@ -54,6 +55,7 @@
 
   LINK_LIBS
   clangAST
+  clangASTMatchers
   clangAnalysis
   clangBasic
   clangLex
diff --git a/lib/StaticAnalyzer/Core/CallEvent.cpp b/lib/StaticAnalyzer/Core/CallEvent.cpp
index 1858bfd..776369b 100644
--- a/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -21,6 +21,9 @@
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Debug.h"
+
+#define DEBUG_TYPE "static-analyzer-call-event"
 
 using namespace clang;
 using namespace ento;
@@ -97,9 +100,6 @@
   for (CallEvent::param_type_iterator I = param_type_begin(),
                                       E = param_type_end();
        I != E && Idx < NumOfArgs; ++I, ++Idx) {
-    if (NumOfArgs <= Idx)
-      break;
-
     // If the parameter is 0, it's harmless.
     if (getArgSVal(Idx).isZeroConstant())
       continue;
@@ -211,7 +211,9 @@
 }
 
 bool CallEvent::isCalled(const CallDescription &CD) const {
-  assert(getKind() != CE_ObjCMessage && "Obj-C methods are not supported");
+  // FIXME: Add ObjC Message support.
+  if (getKind() == CE_ObjCMessage)
+    return false;
   if (!CD.IsLookupDone) {
     CD.IsLookupDone = true;
     CD.II = &getState()->getStateManager().getContext().Idents.get(CD.FuncName);
@@ -346,6 +348,30 @@
   return D->parameters();
 }
 
+RuntimeDefinition AnyFunctionCall::getRuntimeDefinition() const {
+  const FunctionDecl *FD = getDecl();
+  // Note that the AnalysisDeclContext will have the FunctionDecl with
+  // the definition (if one exists).
+  if (FD) {
+    AnalysisDeclContext *AD =
+      getLocationContext()->getAnalysisDeclContext()->
+      getManager()->getContext(FD);
+    bool IsAutosynthesized;
+    Stmt* Body = AD->getBody(IsAutosynthesized);
+    DEBUG({
+        if (IsAutosynthesized)
+          llvm::dbgs() << "Using autosynthesized body for " << FD->getName()
+                       << "\n";
+    });
+    if (Body) {
+      const Decl* Decl = AD->getDecl();
+      return RuntimeDefinition(Decl);
+    }
+  }
+
+  return RuntimeDefinition();
+}
+
 void AnyFunctionCall::getInitialStackFrameContents(
                                         const StackFrameContext *CalleeCtx,
                                         BindingsTy &Bindings) const {
diff --git a/lib/StaticAnalyzer/Core/CheckerContext.cpp b/lib/StaticAnalyzer/Core/CheckerContext.cpp
index 548b06e..61cbf38 100644
--- a/lib/StaticAnalyzer/Core/CheckerContext.cpp
+++ b/lib/StaticAnalyzer/Core/CheckerContext.cpp
@@ -99,3 +99,35 @@
   return Lexer::getSpelling(Loc, buf, getSourceManager(), getLangOpts());
 }
 
+/// Evaluate comparison and return true if it's known that condition is true
+static bool evalComparison(SVal LHSVal, BinaryOperatorKind ComparisonOp,
+                           SVal RHSVal, ProgramStateRef State) {
+  if (LHSVal.isUnknownOrUndef())
+    return false;
+  ProgramStateManager &Mgr = State->getStateManager();
+  if (!LHSVal.getAs<NonLoc>()) {
+    LHSVal = Mgr.getStoreManager().getBinding(State->getStore(),
+                                              LHSVal.castAs<Loc>());
+    if (LHSVal.isUnknownOrUndef() || !LHSVal.getAs<NonLoc>())
+      return false;
+  }
+
+  SValBuilder &Bldr = Mgr.getSValBuilder();
+  SVal Eval = Bldr.evalBinOp(State, ComparisonOp, LHSVal, RHSVal,
+                             Bldr.getConditionType());
+  if (Eval.isUnknownOrUndef())
+    return false;
+  ProgramStateRef StTrue, StFalse;
+  std::tie(StTrue, StFalse) = State->assume(Eval.castAs<DefinedSVal>());
+  return StTrue && !StFalse;
+}
+
+bool CheckerContext::isGreaterOrEqual(const Expr *E, unsigned long long Val) {
+  DefinedSVal V = getSValBuilder().makeIntVal(Val, getASTContext().LongLongTy);
+  return evalComparison(getSVal(E), BO_GE, V, getState());
+}
+
+bool CheckerContext::isNegative(const Expr *E) {
+  DefinedSVal V = getSValBuilder().makeIntVal(0, false);
+  return evalComparison(getSVal(E), BO_LT, V, getState());
+}
diff --git a/lib/StaticAnalyzer/Core/CoreEngine.cpp b/lib/StaticAnalyzer/Core/CoreEngine.cpp
index 4e2866c..e2e9ddf 100644
--- a/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -274,7 +274,8 @@
       assert(Loc.getAs<PostStmt>() ||
              Loc.getAs<PostInitializer>() ||
              Loc.getAs<PostImplicitCall>() ||
-             Loc.getAs<CallExitEnd>());
+             Loc.getAs<CallExitEnd>() ||
+             Loc.getAs<LoopExit>());
       HandlePostStmt(WU.getBlock(), WU.getIndex(), Pred);
       break;
   }
@@ -566,7 +567,8 @@
 
   // Do not create extra nodes. Move to the next CFG element.
   if (N->getLocation().getAs<PostInitializer>() ||
-      N->getLocation().getAs<PostImplicitCall>()) {
+      N->getLocation().getAs<PostImplicitCall>()||
+      N->getLocation().getAs<LoopExit>()) {
     WList->enqueue(N, Block, Idx+1);
     return;
   }
diff --git a/lib/StaticAnalyzer/Core/Environment.cpp b/lib/StaticAnalyzer/Core/Environment.cpp
index e2cb52c..c6acb9d 100644
--- a/lib/StaticAnalyzer/Core/Environment.cpp
+++ b/lib/StaticAnalyzer/Core/Environment.cpp
@@ -13,7 +13,7 @@
 
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/CFG.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
 #include "llvm/Support/raw_ostream.h"
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index eee5400..0126e03 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -17,6 +17,7 @@
 #include "PrettyStackTraceLocationContext.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/ParentMap.h"
+#include "clang/Analysis/CFGStmtMap.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Basic/Builtins.h"
@@ -27,6 +28,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/SaveAndRestore.h"
 #include "llvm/Support/raw_ostream.h"
@@ -362,6 +364,9 @@
     case CFGElement::TemporaryDtor:
       ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred);
       return;
+    case CFGElement::LoopExit:
+      ProcessLoopExit(E.castAs<CFGLoopExit>().getLoopStmt(), Pred);
+      return;
     case CFGElement::LifetimeEnds:
       return;
   }
@@ -507,6 +512,24 @@
   Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
 }
 
+void ExprEngine::ProcessLoopExit(const Stmt* S, ExplodedNode *Pred) {
+  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+                                S->getLocStart(),
+                                "Error evaluating end of the loop");
+  ExplodedNodeSet Dst;
+  Dst.Add(Pred);
+  NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+  ProgramStateRef NewState = Pred->getState();
+
+  if(AMgr.options.shouldUnrollLoops())
+    NewState = processLoopEnd(S, NewState);
+
+  LoopExit PP(S, Pred->getLocationContext());
+  Bldr.generateNode(PP, NewState, Pred);
+  // Enqueue the new nodes onto the work list.
+  Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
+}
+
 void ExprEngine::ProcessInitializer(const CFGInitializer Init,
                                     ExplodedNode *Pred) {
   const CXXCtorInitializer *BMI = Init.getInitializer();
@@ -804,6 +827,21 @@
   }
 }
 
+namespace {
+class CollectReachableSymbolsCallback final : public SymbolVisitor {
+  InvalidatedSymbols Symbols;
+
+public:
+  explicit CollectReachableSymbolsCallback(ProgramStateRef State) {}
+  const InvalidatedSymbols &getSymbols() const { return Symbols; }
+
+  bool VisitSymbol(SymbolRef Sym) override {
+    Symbols.insert(Sym);
+    return true;
+  }
+};
+} // end anonymous namespace
+
 void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
                        ExplodedNodeSet &DstTop) {
   PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
@@ -1080,8 +1118,29 @@
         SVal result = svalBuilder.conjureSymbolVal(nullptr, Ex, LCtx,
                                                    resultType,
                                                    currBldrCtx->blockCount());
-        ProgramStateRef state = N->getState()->BindExpr(Ex, LCtx, result);
-        Bldr2.generateNode(S, N, state);
+        ProgramStateRef State = N->getState()->BindExpr(Ex, LCtx, result);
+
+        // Escape pointers passed into the list, unless it's an ObjC boxed
+        // expression which is not a boxable C structure.
+        if (!(isa<ObjCBoxedExpr>(Ex) &&
+              !cast<ObjCBoxedExpr>(Ex)->getSubExpr()
+                                      ->getType()->isRecordType()))
+          for (auto Child : Ex->children()) {
+            assert(Child);
+
+            SVal Val = State->getSVal(Child, LCtx);
+
+            CollectReachableSymbolsCallback Scanner =
+                State->scanReachableSymbols<CollectReachableSymbolsCallback>(
+                    Val);
+            const InvalidatedSymbols &EscapedSymbols = Scanner.getSymbols();
+
+            State = getCheckerManager().runCheckersForPointerEscape(
+                State, EscapedSymbols,
+                /*CallEvent*/ nullptr, PSK_EscapeOther, nullptr);
+          }
+
+        Bldr2.generateNode(S, N, State);
       }
 
       getCheckerManager().runCheckersForPostStmt(Dst, Tmp, S, *this);
@@ -1497,6 +1556,25 @@
                                          NodeBuilderWithSinks &nodeBuilder,
                                          ExplodedNode *Pred) {
   PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
+  // If we reach a loop which has a known bound (and meets
+  // other constraints) then consider completely unrolling it.
+  if(AMgr.options.shouldUnrollLoops()) {
+    unsigned maxBlockVisitOnPath = AMgr.options.maxBlockVisitOnPath;
+    const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminator();
+    if (Term) {
+      ProgramStateRef NewState = updateLoopStack(Term, AMgr.getASTContext(),
+                                                 Pred, maxBlockVisitOnPath);
+      if (NewState != Pred->getState()) {
+        ExplodedNode *UpdatedNode = nodeBuilder.generateNode(NewState, Pred);
+        if (!UpdatedNode)
+          return;
+        Pred = UpdatedNode;
+      }
+    }
+    // Is we are inside an unrolled loop then no need the check the counters.
+    if(isUnrolledState(Pred->getState()))
+      return;
+  }
 
   // If this block is terminated by a loop and it has already been visited the
   // maximum number of times, widen the loop.
@@ -2195,21 +2273,6 @@
   getCheckerManager().runCheckersForPostStmt(Dst, AfterInvalidateSet, AE, *this);
 }
 
-namespace {
-class CollectReachableSymbolsCallback final : public SymbolVisitor {
-  InvalidatedSymbols Symbols;
-
-public:
-  CollectReachableSymbolsCallback(ProgramStateRef State) {}
-  const InvalidatedSymbols &getSymbols() const { return Symbols; }
-
-  bool VisitSymbol(SymbolRef Sym) override {
-    Symbols.insert(Sym);
-    return true;
-  }
-};
-} // end anonymous namespace
-
 // A value escapes in three possible cases:
 // (1) We are binding to something that is not a memory region.
 // (2) We are binding to a MemrRegion that does not have stack storage.
@@ -2666,6 +2729,12 @@
         Out << "Epsilon Point";
         break;
 
+      case ProgramPoint::LoopExitKind: {
+        LoopExit LE = Loc.castAs<LoopExit>();
+        Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();
+        break;
+      }
+
       case ProgramPoint::PreImplicitCallKind: {
         ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>();
         Out << "PreCall: ";
diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
index 6f1e839..01c6af7 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -92,12 +92,10 @@
       // Process non-assignments except commas or short-circuited
       // logical expressions (LAnd and LOr).
       SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType());
-      if (Result.isUnknown()) {
-        Bldr.generateNode(B, *it, state);
-        continue;
+      if (!Result.isUnknown()) {
+        state = state->BindExpr(B, LCtx, Result);
       }
 
-      state = state->BindExpr(B, LCtx, Result);
       Bldr.generateNode(B, *it, state);
       continue;
     }
@@ -628,6 +626,16 @@
   StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx);
   ProgramStateRef state = Pred->getState();
 
+  if (B->getType()->isVectorType()) {
+    // FIXME: We do not model vector arithmetic yet. When adding support for
+    // that, note that the CFG-based reasoning below does not apply, because
+    // logical operators on vectors are not short-circuit. Currently they are
+    // modeled as short-circuit in Clang CFG but this is incorrect.
+    // Do not set the value for the expression. It'd be UnknownVal by default.
+    Bldr.generateNode(B, Pred, state);
+    return;
+  }
+
   ExplodedNode *N = Pred;
   while (!N->getLocation().getAs<BlockEntrance>()) {
     ProgramPoint P = N->getLocation();
diff --git a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index f0f6dd2..9b820e8 100644
--- a/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -44,8 +44,12 @@
   bool createdDir, noDir;
   const Preprocessor &PP;
   AnalyzerOptions &AnalyzerOpts;
+  const bool SupportsCrossFileDiagnostics;
 public:
-  HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts, const std::string& prefix, const Preprocessor &pp);
+  HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts,
+                  const std::string& prefix,
+                  const Preprocessor &pp,
+                  bool supportsMultipleFiles);
 
   ~HTMLDiagnostics() override { FlushDiagnostics(nullptr); }
 
@@ -56,6 +60,10 @@
     return "HTMLDiagnostics";
   }
 
+  bool supportsCrossFileDiagnostics() const override {
+    return SupportsCrossFileDiagnostics;
+  }
+
   unsigned ProcessMacroPiece(raw_ostream &os,
                              const PathDiagnosticMacroPiece& P,
                              unsigned num);
@@ -69,21 +77,47 @@
 
   void ReportDiag(const PathDiagnostic& D,
                   FilesMade *filesMade);
+
+  // Generate the full HTML report
+  std::string GenerateHTML(const PathDiagnostic& D, Rewriter &R,
+                           const SourceManager& SMgr, const PathPieces& path,
+                           const char *declName);
+
+  // Add HTML header/footers to file specified by FID
+  void FinalizeHTML(const PathDiagnostic& D, Rewriter &R,
+                    const SourceManager& SMgr, const PathPieces& path,
+                    FileID FID, const FileEntry *Entry, const char *declName);
+
+  // Rewrite the file specified by FID with HTML formatting.
+  void RewriteFile(Rewriter &R, const SourceManager& SMgr,
+                   const PathPieces& path, FileID FID);
 };
 
 } // end anonymous namespace
 
 HTMLDiagnostics::HTMLDiagnostics(AnalyzerOptions &AnalyzerOpts,
                                  const std::string& prefix,
-                                 const Preprocessor &pp)
-    : Directory(prefix), createdDir(false), noDir(false), PP(pp), AnalyzerOpts(AnalyzerOpts) {
-}
+                                 const Preprocessor &pp,
+                                 bool supportsMultipleFiles)
+    : Directory(prefix),
+      createdDir(false),
+      noDir(false),
+      PP(pp),
+      AnalyzerOpts(AnalyzerOpts),
+      SupportsCrossFileDiagnostics(supportsMultipleFiles) {}
 
 void ento::createHTMLDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
                                         PathDiagnosticConsumers &C,
                                         const std::string& prefix,
                                         const Preprocessor &PP) {
-  C.push_back(new HTMLDiagnostics(AnalyzerOpts, prefix, PP));
+  C.push_back(new HTMLDiagnostics(AnalyzerOpts, prefix, PP, true));
+}
+
+void ento::createHTMLSingleFileDiagnosticConsumer(AnalyzerOptions &AnalyzerOpts,
+                                                  PathDiagnosticConsumers &C,
+                                                  const std::string& prefix,
+                                                  const Preprocessor &PP) {
+  C.push_back(new HTMLDiagnostics(AnalyzerOpts, prefix, PP, false));
 }
 
 //===----------------------------------------------------------------------===//
@@ -121,24 +155,24 @@
   // First flatten out the entire path to make it easier to use.
   PathPieces path = D.path.flatten(/*ShouldFlattenMacros=*/false);
 
-  // The path as already been prechecked that all parts of the path are
-  // from the same file and that it is non-empty.
-  const SourceManager &SMgr = path.front()->getLocation().getManager();
+  // The path as already been prechecked that the path is non-empty.
   assert(!path.empty());
-  FileID FID =
-    path.front()->getLocation().asLocation().getExpansionLoc().getFileID();
-  assert(FID.isValid());
+  const SourceManager &SMgr = path.front()->getLocation().getManager();
 
   // Create a new rewriter to generate HTML.
   Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOpts());
 
+  // The file for the first path element is considered the main report file, it
+  // will usually be equivalent to SMgr.getMainFileID(); however, it might be a
+  // header when -analyzer-opt-analyze-headers is used.
+  FileID ReportFile = path.front()->getLocation().asLocation().getExpansionLoc().getFileID();
+
   // Get the function/method name
   SmallString<128> declName("unknown");
   int offsetDecl = 0;
   if (const Decl *DeclWithIssue = D.getDeclWithIssue()) {
-      if (const NamedDecl *ND = dyn_cast<NamedDecl>(DeclWithIssue)) {
+      if (const NamedDecl *ND = dyn_cast<NamedDecl>(DeclWithIssue))
           declName = ND->getDeclName().getAsString();
-      }
 
       if (const Stmt *Body = DeclWithIssue->getBody()) {
           // Retrieve the relative position of the declaration which will be used
@@ -151,49 +185,144 @@
       }
   }
 
-  // Process the path.
-  // Maintain the counts of extra note pieces separately.
-  unsigned TotalPieces = path.size();
-  unsigned TotalNotePieces =
-      std::count_if(path.begin(), path.end(),
-                    [](const std::shared_ptr<PathDiagnosticPiece> &p) {
-                      return isa<PathDiagnosticNotePiece>(*p);
-                    });
+  std::string report = GenerateHTML(D, R, SMgr, path, declName.c_str());
+  if (report.empty()) {
+    llvm::errs() << "warning: no diagnostics generated for main file.\n";
+    return;
+  }
 
-  unsigned TotalRegularPieces = TotalPieces - TotalNotePieces;
-  unsigned NumRegularPieces = TotalRegularPieces;
-  unsigned NumNotePieces = TotalNotePieces;
+  // Create a path for the target HTML file.
+  int FD;
+  SmallString<128> Model, ResultPath;
 
-  for (auto I = path.rbegin(), E = path.rend(); I != E; ++I) {
-    if (isa<PathDiagnosticNotePiece>(I->get())) {
-      // This adds diagnostic bubbles, but not navigation.
-      // Navigation through note pieces would be added later,
-      // as a separate pass through the piece list.
-      HandlePiece(R, FID, **I, NumNotePieces, TotalNotePieces);
-      --NumNotePieces;
-    } else {
-      HandlePiece(R, FID, **I, NumRegularPieces, TotalRegularPieces);
-      --NumRegularPieces;
+  if (!AnalyzerOpts.shouldWriteStableReportFilename()) {
+      llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
+      if (std::error_code EC =
+          llvm::sys::fs::make_absolute(Model)) {
+          llvm::errs() << "warning: could not make '" << Model
+                       << "' absolute: " << EC.message() << '\n';
+        return;
+      }
+      if (std::error_code EC =
+          llvm::sys::fs::createUniqueFile(Model, FD, ResultPath)) {
+          llvm::errs() << "warning: could not create file in '" << Directory
+                       << "': " << EC.message() << '\n';
+          return;
+      }
+
+  } else {
+      int i = 1;
+      std::error_code EC;
+      do {
+          // Find a filename which is not already used
+          const FileEntry* Entry = SMgr.getFileEntryForID(ReportFile);
+          std::stringstream filename;
+          Model = "";
+          filename << "report-"
+                   << llvm::sys::path::filename(Entry->getName()).str()
+                   << "-" << declName.c_str()
+                   << "-" << offsetDecl
+                   << "-" << i << ".html";
+          llvm::sys::path::append(Model, Directory,
+                                  filename.str());
+          EC = llvm::sys::fs::openFileForWrite(Model,
+                                               FD,
+                                               llvm::sys::fs::F_RW |
+                                               llvm::sys::fs::F_Excl);
+          if (EC && EC != llvm::errc::file_exists) {
+              llvm::errs() << "warning: could not create file '" << Model
+                           << "': " << EC.message() << '\n';
+              return;
+          }
+          i++;
+      } while (EC);
+  }
+
+  llvm::raw_fd_ostream os(FD, true);
+
+  if (filesMade)
+    filesMade->addDiagnostic(D, getName(),
+                             llvm::sys::path::filename(ResultPath));
+
+  // Emit the HTML to disk.
+  os << report;
+}
+
+std::string HTMLDiagnostics::GenerateHTML(const PathDiagnostic& D, Rewriter &R,
+    const SourceManager& SMgr, const PathPieces& path, const char *declName) {
+
+  // Rewrite source files as HTML for every new file the path crosses
+  std::vector<FileID> FileIDs;
+  for (auto I : path) {
+    FileID FID = I->getLocation().asLocation().getExpansionLoc().getFileID();
+    if (std::find(FileIDs.begin(), FileIDs.end(), FID) != FileIDs.end())
+      continue;
+
+    FileIDs.push_back(FID);
+    RewriteFile(R, SMgr, path, FID);
+  }
+
+  if (SupportsCrossFileDiagnostics && FileIDs.size() > 1) {
+    // Prefix file names, anchor tags, and nav cursors to every file
+    for (auto I = FileIDs.begin(), E = FileIDs.end(); I != E; I++) {
+      std::string s;
+      llvm::raw_string_ostream os(s);
+
+      if (I != FileIDs.begin())
+        os << "<hr class=divider>\n";
+
+      os << "<div id=File" << I->getHashValue() << ">\n";
+
+      // Left nav arrow
+      if (I != FileIDs.begin())
+        os << "<div class=FileNav><a href=\"#File" << (I - 1)->getHashValue()
+           << "\">&#x2190;</a></div>";
+
+      os << "<h4 class=FileName>" << SMgr.getFileEntryForID(*I)->getName()
+         << "</h4>\n";
+
+      // Right nav arrow
+      if (I + 1 != E)
+        os << "<div class=FileNav><a href=\"#File" << (I + 1)->getHashValue()
+           << "\">&#x2192;</a></div>";
+
+      os << "</div>\n";
+
+      R.InsertTextBefore(SMgr.getLocForStartOfFile(*I), os.str());
+    }
+
+    // Append files to the main report file in the order they appear in the path
+    for (auto I : llvm::make_range(FileIDs.begin() + 1, FileIDs.end())) {
+      std::string s;
+      llvm::raw_string_ostream os(s);
+
+      const RewriteBuffer *Buf = R.getRewriteBufferFor(I);
+      for (auto BI : *Buf)
+        os << BI;
+
+      R.InsertTextAfter(SMgr.getLocForEndOfFile(FileIDs[0]), os.str());
     }
   }
 
-  // Add line numbers, header, footer, etc.
+  const RewriteBuffer *Buf = R.getRewriteBufferFor(FileIDs[0]);
+  if (!Buf)
+    return "";
 
-  // unsigned FID = R.getSourceMgr().getMainFileID();
-  html::EscapeText(R, FID);
-  html::AddLineNumbers(R, FID);
+  // Add CSS, header, and footer.
+  const FileEntry* Entry = SMgr.getFileEntryForID(FileIDs[0]);
+  FinalizeHTML(D, R, SMgr, path, FileIDs[0], Entry, declName);
 
-  // If we have a preprocessor, relex the file and syntax highlight.
-  // We might not have a preprocessor if we come from a deserialized AST file,
-  // for example.
+  std::string file;
+  llvm::raw_string_ostream os(file);
+  for (auto BI : *Buf)
+    os << BI;
 
-  html::SyntaxHighlight(R, FID, PP);
-  html::HighlightMacros(R, FID, PP);
+  return os.str();
+}
 
-  // Get the full directory name of the analyzed file.
-
-  const FileEntry* Entry = SMgr.getFileEntryForID(FID);
-
+void HTMLDiagnostics::FinalizeHTML(const PathDiagnostic& D, Rewriter &R,
+    const SourceManager& SMgr, const PathPieces& path, FileID FID,
+    const FileEntry *Entry, const char *declName) {
   // This is a cludge; basically we want to append either the full
   // working directory if we have no directory information.  This is
   // a work in progress.
@@ -306,73 +435,48 @@
     R.InsertTextBefore(SMgr.getLocForStartOfFile(FID), os.str());
   }
 
-  // Add CSS, header, and footer.
-
   html::AddHeaderFooterInternalBuiltinCSS(R, FID, Entry->getName());
+}
 
-  // Get the rewrite buffer.
-  const RewriteBuffer *Buf = R.getRewriteBufferFor(FID);
+void HTMLDiagnostics::RewriteFile(Rewriter &R, const SourceManager& SMgr,
+    const PathPieces& path, FileID FID) {
+  // Process the path.
+  // Maintain the counts of extra note pieces separately.
+  unsigned TotalPieces = path.size();
+  unsigned TotalNotePieces =
+      std::count_if(path.begin(), path.end(),
+                    [](const std::shared_ptr<PathDiagnosticPiece> &p) {
+                      return isa<PathDiagnosticNotePiece>(*p);
+                    });
 
-  if (!Buf) {
-    llvm::errs() << "warning: no diagnostics generated for main file.\n";
-    return;
+  unsigned TotalRegularPieces = TotalPieces - TotalNotePieces;
+  unsigned NumRegularPieces = TotalRegularPieces;
+  unsigned NumNotePieces = TotalNotePieces;
+
+  for (auto I = path.rbegin(), E = path.rend(); I != E; ++I) {
+    if (isa<PathDiagnosticNotePiece>(I->get())) {
+      // This adds diagnostic bubbles, but not navigation.
+      // Navigation through note pieces would be added later,
+      // as a separate pass through the piece list.
+      HandlePiece(R, FID, **I, NumNotePieces, TotalNotePieces);
+      --NumNotePieces;
+    } else {
+      HandlePiece(R, FID, **I, NumRegularPieces, TotalRegularPieces);
+      --NumRegularPieces;
+    }
   }
 
-  // Create a path for the target HTML file.
-  int FD;
-  SmallString<128> Model, ResultPath;
+  // Add line numbers, header, footer, etc.
 
-  if (!AnalyzerOpts.shouldWriteStableReportFilename()) {
-      llvm::sys::path::append(Model, Directory, "report-%%%%%%.html");
-      if (std::error_code EC =
-          llvm::sys::fs::make_absolute(Model)) {
-          llvm::errs() << "warning: could not make '" << Model
-                       << "' absolute: " << EC.message() << '\n';
-        return;
-      }
-      if (std::error_code EC =
-          llvm::sys::fs::createUniqueFile(Model, FD, ResultPath)) {
-          llvm::errs() << "warning: could not create file in '" << Directory
-                       << "': " << EC.message() << '\n';
-          return;
-      }
+  html::EscapeText(R, FID);
+  html::AddLineNumbers(R, FID);
 
-  } else {
-      int i = 1;
-      std::error_code EC;
-      do {
-          // Find a filename which is not already used
-          std::stringstream filename;
-          Model = "";
-          filename << "report-"
-                   << llvm::sys::path::filename(Entry->getName()).str()
-                   << "-" << declName.c_str()
-                   << "-" << offsetDecl
-                   << "-" << i << ".html";
-          llvm::sys::path::append(Model, Directory,
-                                  filename.str());
-          EC = llvm::sys::fs::openFileForWrite(Model,
-                                               FD,
-                                               llvm::sys::fs::F_RW |
-                                               llvm::sys::fs::F_Excl);
-          if (EC && EC != llvm::errc::file_exists) {
-              llvm::errs() << "warning: could not create file '" << Model
-                           << "': " << EC.message() << '\n';
-              return;
-          }
-          i++;
-      } while (EC);
-  }
+  // If we have a preprocessor, relex the file and syntax highlight.
+  // We might not have a preprocessor if we come from a deserialized AST file,
+  // for example.
 
-  llvm::raw_fd_ostream os(FD, true);
-
-  if (filesMade)
-    filesMade->addDiagnostic(D, getName(),
-                             llvm::sys::path::filename(ResultPath));
-
-  // Emit the HTML to disk.
-  for (RewriteBuffer::iterator I = Buf->begin(), E = Buf->end(); I!=E; ++I)
-      os << *I;
+  html::SyntaxHighlight(R, FID, PP);
+  html::HighlightMacros(R, FID, PP);
 }
 
 void HTMLDiagnostics::HandlePiece(Rewriter& R, FileID BugFileID,
diff --git a/lib/StaticAnalyzer/Core/IssueHash.cpp b/lib/StaticAnalyzer/Core/IssueHash.cpp
index abdea88..274ebe7 100644
--- a/lib/StaticAnalyzer/Core/IssueHash.cpp
+++ b/lib/StaticAnalyzer/Core/IssueHash.cpp
@@ -33,6 +33,13 @@
     return "";
   std::string Signature;
 
+  // When a flow sensitive bug happens in templated code we should not generate
+  // distinct hash value for every instantiation. Use the signature from the
+  // primary template.
+  if (const FunctionDecl *InstantiatedFrom =
+          Target->getTemplateInstantiationPattern())
+    Target = InstantiatedFrom;
+
   if (!isa<CXXConstructorDecl>(Target) && !isa<CXXDestructorDecl>(Target) &&
       !isa<CXXConversionDecl>(Target))
     Signature.append(Target->getReturnType().getAsString()).append(" ");
diff --git a/lib/StaticAnalyzer/Core/LoopUnrolling.cpp b/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
new file mode 100644
index 0000000..a8c4b05
--- /dev/null
+++ b/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
@@ -0,0 +1,294 @@
+//===--- LoopUnrolling.cpp - Unroll loops -----------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// This file contains functions which are used to decide if a loop worth to be
+/// unrolled. Moreover, these functions manages the stack of loop which is
+/// tracked by the ProgramState.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h"
+
+using namespace clang;
+using namespace ento;
+using namespace clang::ast_matchers;
+
+static const int MAXIMUM_STEP_UNROLLED = 128;
+
+struct LoopState {
+private:
+  enum Kind { Normal, Unrolled } K;
+  const Stmt *LoopStmt;
+  const LocationContext *LCtx;
+  unsigned maxStep;
+  LoopState(Kind InK, const Stmt *S, const LocationContext *L, unsigned N)
+      : K(InK), LoopStmt(S), LCtx(L), maxStep(N) {}
+
+public:
+  static LoopState getNormal(const Stmt *S, const LocationContext *L,
+                             unsigned N) {
+    return LoopState(Normal, S, L, N);
+  }
+  static LoopState getUnrolled(const Stmt *S, const LocationContext *L,
+                               unsigned N) {
+    return LoopState(Unrolled, S, L, N);
+  }
+  bool isUnrolled() const { return K == Unrolled; }
+  unsigned getMaxStep() const { return maxStep; }
+  const Stmt *getLoopStmt() const { return LoopStmt; }
+  const LocationContext *getLocationContext() const { return LCtx; }
+  bool operator==(const LoopState &X) const {
+    return K == X.K && LoopStmt == X.LoopStmt;
+  }
+  void Profile(llvm::FoldingSetNodeID &ID) const {
+    ID.AddInteger(K);
+    ID.AddPointer(LoopStmt);
+    ID.AddPointer(LCtx);
+    ID.AddInteger(maxStep);
+  }
+};
+
+// The tracked stack of loops. The stack indicates that which loops the
+// simulated element contained by. The loops are marked depending if we decided
+// to unroll them.
+// TODO: The loop stack should not need to be in the program state since it is
+// lexical in nature. Instead, the stack of loops should be tracked in the
+// LocationContext.
+REGISTER_LIST_WITH_PROGRAMSTATE(LoopStack, LoopState)
+
+namespace clang {
+namespace ento {
+
+static bool isLoopStmt(const Stmt *S) {
+  return S && (isa<ForStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S));
+}
+
+ProgramStateRef processLoopEnd(const Stmt *LoopStmt, ProgramStateRef State) {
+  auto LS = State->get<LoopStack>();
+  if (!LS.isEmpty() && LS.getHead().getLoopStmt() == LoopStmt)
+    State = State->set<LoopStack>(LS.getTail());
+  return State;
+}
+
+static internal::Matcher<Stmt> simpleCondition(StringRef BindName) {
+  return binaryOperator(anyOf(hasOperatorName("<"), hasOperatorName(">"),
+                              hasOperatorName("<="), hasOperatorName(">="),
+                              hasOperatorName("!=")),
+                        hasEitherOperand(ignoringParenImpCasts(declRefExpr(
+                            to(varDecl(hasType(isInteger())).bind(BindName))))),
+                        hasEitherOperand(ignoringParenImpCasts(
+                            integerLiteral().bind("boundNum"))))
+      .bind("conditionOperator");
+}
+
+static internal::Matcher<Stmt>
+changeIntBoundNode(internal::Matcher<Decl> VarNodeMatcher) {
+  return anyOf(
+      unaryOperator(anyOf(hasOperatorName("--"), hasOperatorName("++")),
+                    hasUnaryOperand(ignoringParenImpCasts(
+                        declRefExpr(to(varDecl(VarNodeMatcher)))))),
+      binaryOperator(anyOf(hasOperatorName("="), hasOperatorName("+="),
+                           hasOperatorName("/="), hasOperatorName("*="),
+                           hasOperatorName("-=")),
+                     hasLHS(ignoringParenImpCasts(
+                         declRefExpr(to(varDecl(VarNodeMatcher)))))));
+}
+
+static internal::Matcher<Stmt>
+callByRef(internal::Matcher<Decl> VarNodeMatcher) {
+  return callExpr(forEachArgumentWithParam(
+      declRefExpr(to(varDecl(VarNodeMatcher))),
+      parmVarDecl(hasType(references(qualType(unless(isConstQualified())))))));
+}
+
+static internal::Matcher<Stmt>
+assignedToRef(internal::Matcher<Decl> VarNodeMatcher) {
+  return declStmt(hasDescendant(varDecl(
+      allOf(hasType(referenceType()),
+            hasInitializer(anyOf(
+                initListExpr(has(declRefExpr(to(varDecl(VarNodeMatcher))))),
+                declRefExpr(to(varDecl(VarNodeMatcher)))))))));
+}
+
+static internal::Matcher<Stmt>
+getAddrTo(internal::Matcher<Decl> VarNodeMatcher) {
+  return unaryOperator(
+      hasOperatorName("&"),
+      hasUnaryOperand(declRefExpr(hasDeclaration(VarNodeMatcher))));
+}
+
+static internal::Matcher<Stmt> hasSuspiciousStmt(StringRef NodeName) {
+  return hasDescendant(stmt(
+      anyOf(gotoStmt(), switchStmt(), returnStmt(),
+            // Escaping and not known mutation of the loop counter is handled
+            // by exclusion of assigning and address-of operators and
+            // pass-by-ref function calls on the loop counter from the body.
+            changeIntBoundNode(equalsBoundNode(NodeName)),
+            callByRef(equalsBoundNode(NodeName)),
+            getAddrTo(equalsBoundNode(NodeName)),
+            assignedToRef(equalsBoundNode(NodeName)))));
+}
+
+static internal::Matcher<Stmt> forLoopMatcher() {
+  return forStmt(
+             hasCondition(simpleCondition("initVarName")),
+             // Initialization should match the form: 'int i = 6' or 'i = 42'.
+             hasLoopInit(anyOf(
+                 declStmt(hasSingleDecl(varDecl(
+                     allOf(hasInitializer(integerLiteral().bind("initNum")),
+                           equalsBoundNode("initVarName"))))),
+                 binaryOperator(hasLHS(declRefExpr(to(
+                                    varDecl(equalsBoundNode("initVarName"))))),
+                                hasRHS(integerLiteral().bind("initNum"))))),
+             // Incrementation should be a simple increment or decrement
+             // operator call.
+             hasIncrement(unaryOperator(
+                 anyOf(hasOperatorName("++"), hasOperatorName("--")),
+                 hasUnaryOperand(declRefExpr(
+                     to(varDecl(allOf(equalsBoundNode("initVarName"),
+                                      hasType(isInteger())))))))),
+             unless(hasBody(hasSuspiciousStmt("initVarName")))).bind("forLoop");
+}
+
+static bool isPossiblyEscaped(const VarDecl *VD, ExplodedNode *N) {
+  // Global variables assumed as escaped variables.
+  if (VD->hasGlobalStorage())
+    return true;
+
+  while (!N->pred_empty()) {
+    const Stmt *S = PathDiagnosticLocation::getStmt(N);
+    if (!S) {
+      N = N->getFirstPred();
+      continue;
+    }
+
+    if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) {
+      for (const Decl *D : DS->decls()) {
+        // Once we reach the declaration of the VD we can return.
+        if (D->getCanonicalDecl() == VD)
+          return false;
+      }
+    }
+    // Check the usage of the pass-by-ref function calls and adress-of operator
+    // on VD and reference initialized by VD.
+    ASTContext &ASTCtx =
+        N->getLocationContext()->getAnalysisDeclContext()->getASTContext();
+    auto Match =
+        match(stmt(anyOf(callByRef(equalsNode(VD)), getAddrTo(equalsNode(VD)),
+                         assignedToRef(equalsNode(VD)))),
+              *S, ASTCtx);
+    if (!Match.empty())
+      return true;
+
+    N = N->getFirstPred();
+  }
+  llvm_unreachable("Reached root without finding the declaration of VD");
+}
+
+bool shouldCompletelyUnroll(const Stmt *LoopStmt, ASTContext &ASTCtx,
+                            ExplodedNode *Pred, unsigned &maxStep) {
+
+  if (!isLoopStmt(LoopStmt))
+    return false;
+
+  // TODO: Match the cases where the bound is not a concrete literal but an
+  // integer with known value
+  auto Matches = match(forLoopMatcher(), *LoopStmt, ASTCtx);
+  if (Matches.empty())
+    return false;
+
+  auto CounterVar = Matches[0].getNodeAs<VarDecl>("initVarName");
+  llvm::APInt BoundNum =
+      Matches[0].getNodeAs<IntegerLiteral>("boundNum")->getValue();
+  llvm::APInt InitNum =
+      Matches[0].getNodeAs<IntegerLiteral>("initNum")->getValue();
+  auto CondOp = Matches[0].getNodeAs<BinaryOperator>("conditionOperator");
+  if (InitNum.getBitWidth() != BoundNum.getBitWidth()) {
+    InitNum = InitNum.zextOrSelf(BoundNum.getBitWidth());
+    BoundNum = BoundNum.zextOrSelf(InitNum.getBitWidth());
+  }
+
+  if (CondOp->getOpcode() == BO_GE || CondOp->getOpcode() == BO_LE)
+    maxStep = (BoundNum - InitNum + 1).abs().getZExtValue();
+  else
+    maxStep = (BoundNum - InitNum).abs().getZExtValue();
+
+  // Check if the counter of the loop is not escaped before.
+  return !isPossiblyEscaped(CounterVar->getCanonicalDecl(), Pred);
+}
+
+bool madeNewBranch(ExplodedNode *N, const Stmt *LoopStmt) {
+  const Stmt *S = nullptr;
+  while (!N->pred_empty()) {
+    if (N->succ_size() > 1)
+      return true;
+
+    ProgramPoint P = N->getLocation();
+    if (Optional<BlockEntrance> BE = P.getAs<BlockEntrance>())
+      S = BE->getBlock()->getTerminator();
+
+    if (S == LoopStmt)
+      return false;
+
+    N = N->getFirstPred();
+  }
+
+  llvm_unreachable("Reached root without encountering the previous step");
+}
+
+// updateLoopStack is called on every basic block, therefore it needs to be fast
+ProgramStateRef updateLoopStack(const Stmt *LoopStmt, ASTContext &ASTCtx,
+                                ExplodedNode *Pred, unsigned maxVisitOnPath) {
+  auto State = Pred->getState();
+  auto LCtx = Pred->getLocationContext();
+
+  if (!isLoopStmt(LoopStmt))
+    return State;
+
+  auto LS = State->get<LoopStack>();
+  if (!LS.isEmpty() && LoopStmt == LS.getHead().getLoopStmt() &&
+      LCtx == LS.getHead().getLocationContext()) {
+    if (LS.getHead().isUnrolled() && madeNewBranch(Pred, LoopStmt)) {
+      State = State->set<LoopStack>(LS.getTail());
+      State = State->add<LoopStack>(
+          LoopState::getNormal(LoopStmt, LCtx, maxVisitOnPath));
+    }
+    return State;
+  }
+  unsigned maxStep;
+  if (!shouldCompletelyUnroll(LoopStmt, ASTCtx, Pred, maxStep)) {
+    State = State->add<LoopStack>(
+        LoopState::getNormal(LoopStmt, LCtx, maxVisitOnPath));
+    return State;
+  }
+
+  unsigned outerStep = (LS.isEmpty() ? 1 : LS.getHead().getMaxStep());
+
+  unsigned innerMaxStep = maxStep * outerStep;
+  if (innerMaxStep > MAXIMUM_STEP_UNROLLED)
+    State = State->add<LoopStack>(
+        LoopState::getNormal(LoopStmt, LCtx, maxVisitOnPath));
+  else
+    State = State->add<LoopStack>(
+        LoopState::getUnrolled(LoopStmt, LCtx, innerMaxStep));
+  return State;
+}
+
+bool isUnrolledState(ProgramStateRef State) {
+  auto LS = State->get<LoopStack>();
+  if (LS.isEmpty() || !LS.getHead().isUnrolled())
+    return false;
+  return true;
+}
+}
+}
diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp
index 7bc186d..640e63d 100644
--- a/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -18,7 +18,7 @@
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/RecordLayout.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Analysis/Support/BumpVector.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
index d91786f..9077556 100644
--- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
+++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
@@ -578,8 +578,10 @@
   }
   case CFGElement::TemporaryDtor:
   case CFGElement::NewAllocator:
-  case CFGElement::LifetimeEnds:
     llvm_unreachable("not yet implemented!");
+  case CFGElement::LifetimeEnds:
+  case CFGElement::LoopExit:
+    llvm_unreachable("CFGElement kind should not be on callsite!");
   }
 
   llvm_unreachable("Unknown CFGElement kind");
diff --git a/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h b/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h
index e7cc23c..4bb6948 100644
--- a/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h
+++ b/lib/StaticAnalyzer/Core/PrettyStackTraceLocationContext.h
@@ -10,7 +10,7 @@
 #ifndef LLVM_CLANG_LIB_STATICANALYZER_CORE_PRETTYSTACKTRACELOCATIONCONTEXT_H
 #define LLVM_CLANG_LIB_STATICANALYZER_CORE_PRETTYSTACKTRACELOCATIONCONTEXT_H
 
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 
 namespace clang {
 namespace ento {
diff --git a/lib/StaticAnalyzer/Core/ProgramState.cpp b/lib/StaticAnalyzer/Core/ProgramState.cpp
index 3215c3c..5b6b733 100644
--- a/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -260,7 +260,9 @@
   // be a constant value, use that value instead to lessen the burden
   // on later analysis stages (so we have less symbolic values to reason
   // about).
-  if (!T.isNull()) {
+  // We only go into this branch if we can convert the APSInt value we have
+  // to the type of T, which is not always the case (e.g. for void).
+  if (!T.isNull() && (T->isIntegralOrEnumerationType() || Loc::isLocType(T))) {
     if (SymbolRef sym = V.getAsSymbol()) {
       if (const llvm::APSInt *Int = getStateManager()
                                     .getConstraintManager()
diff --git a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
index e0ad2d8..0f1f173 100644
--- a/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
+++ b/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp
@@ -460,6 +460,53 @@
   return Changed ? State->set<ConstraintRange>(CR) : State;
 }
 
+/// Return a range set subtracting zero from \p Domain.
+static RangeSet assumeNonZero(
+    BasicValueFactory &BV,
+    RangeSet::Factory &F,
+    SymbolRef Sym,
+    RangeSet Domain) {
+  APSIntType IntType = BV.getAPSIntType(Sym->getType());
+  return Domain.Intersect(BV, F, ++IntType.getZeroValue(),
+      --IntType.getZeroValue());
+}
+
+/// \brief Apply implicit constraints for bitwise OR- and AND-.
+/// For unsigned types, bitwise OR with a constant always returns
+/// a value greater-or-equal than the constant, and bitwise AND
+/// returns a value less-or-equal then the constant.
+///
+/// Pattern matches the expression \p Sym against those rule,
+/// and applies the required constraints.
+/// \p Input Previously established expression range set
+static RangeSet applyBitwiseConstraints(
+    BasicValueFactory &BV,
+    RangeSet::Factory &F,
+    RangeSet Input,
+    const SymIntExpr* SIE) {
+  QualType T = SIE->getType();
+  bool IsUnsigned = T->isUnsignedIntegerType();
+  const llvm::APSInt &RHS = SIE->getRHS();
+  const llvm::APSInt &Zero = BV.getAPSIntType(T).getZeroValue();
+  BinaryOperator::Opcode Operator = SIE->getOpcode();
+
+  // For unsigned types, the output of bitwise-or is bigger-or-equal than RHS.
+  if (Operator == BO_Or && IsUnsigned)
+    return Input.Intersect(BV, F, RHS, BV.getMaxValue(T));
+
+  // Bitwise-or with a non-zero constant is always non-zero.
+  if (Operator == BO_Or && RHS != Zero)
+    return assumeNonZero(BV, F, SIE, Input);
+
+  // For unsigned types, or positive RHS,
+  // bitwise-and output is always smaller-or-equal than RHS (assuming two's
+  // complement representation of signed types).
+  if (Operator == BO_And && (IsUnsigned || RHS >= Zero))
+    return Input.Intersect(BV, F, BV.getMinValue(T), RHS);
+
+  return Input;
+}
+
 RangeSet RangeConstraintManager::getRange(ProgramStateRef State,
                                           SymbolRef Sym) {
   if (ConstraintRangeTy::data_type *V = State->get<ConstraintRange>(Sym))
@@ -472,12 +519,13 @@
 
   RangeSet Result(F, BV.getMinValue(T), BV.getMaxValue(T));
 
-  // Special case: references are known to be non-zero.
-  if (T->isReferenceType()) {
-    APSIntType IntType = BV.getAPSIntType(T);
-    Result = Result.Intersect(BV, F, ++IntType.getZeroValue(),
-                              --IntType.getZeroValue());
-  }
+  // References are known to be non-zero.
+  if (T->isReferenceType())
+    return assumeNonZero(BV, F, Sym, Result);
+
+  // Known constraints on ranges of bitwise expressions.
+  if (const SymIntExpr* SIE = dyn_cast<SymIntExpr>(Sym))
+    return applyBitwiseConstraints(BV, F, Result, SIE);
 
   return Result;
 }
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp
index 11902f6..693a617 100644
--- a/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -18,7 +18,7 @@
 #include "clang/AST/Attr.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
-#include "clang/Analysis/AnalysisContext.h"
+#include "clang/Analysis/AnalysisDeclContext.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
@@ -1393,16 +1393,19 @@
     return UnknownVal();
   }
 
-  if (isa<AllocaRegion>(MR) ||
-      isa<SymbolicRegion>(MR) ||
-      isa<CodeTextRegion>(MR)) {
+  if (!isa<TypedValueRegion>(MR)) {
     if (T.isNull()) {
       if (const TypedRegion *TR = dyn_cast<TypedRegion>(MR))
-        T = TR->getLocationType();
-      else {
-        const SymbolicRegion *SR = cast<SymbolicRegion>(MR);
-        T = SR->getSymbol()->getType();
-      }
+        T = TR->getLocationType()->getPointeeType();
+      else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
+        T = SR->getSymbol()->getType()->getPointeeType();
+      else if (isa<AllocaRegion>(MR))
+        T = Ctx.VoidTy;
+    }
+    assert(!T.isNull() && "Unable to auto-detect binding type!");
+    if (T->isVoidType()) {
+      // When trying to dereference a void pointer, read the first byte.
+      T = Ctx.CharTy;
     }
     MR = GetElementZeroRegion(cast<SubRegion>(MR), T);
   }
@@ -2085,15 +2088,12 @@
   if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(AT))
     Size = CAT->getSize().getZExtValue();
 
-  // Check if the init expr is a string literal.
+  // Check if the init expr is a literal. If so, bind the rvalue instead.
+  // FIXME: It's not responsibility of the Store to transform this lvalue
+  // to rvalue. ExprEngine or maybe even CFG should do this before binding.
   if (Optional<loc::MemRegionVal> MRV = Init.getAs<loc::MemRegionVal>()) {
-    const StringRegion *S = cast<StringRegion>(MRV->getRegion());
-
-    // Treat the string as a lazy compound value.
-    StoreRef store(B.asStore(), *this);
-    nonloc::LazyCompoundVal LCV = svalBuilder.makeLazyCompoundVal(store, S)
-        .castAs<nonloc::LazyCompoundVal>();
-    return bindAggregate(B, R, LCV);
+    SVal V = getBinding(B.asStore(), *MRV, R->getValueType());
+    return bindAggregate(B, R, V);
   }
 
   // Handle lazy compound values.
diff --git a/lib/StaticAnalyzer/Core/SVals.cpp b/lib/StaticAnalyzer/Core/SVals.cpp
index 9f2af3f..a834214 100644
--- a/lib/StaticAnalyzer/Core/SVals.cpp
+++ b/lib/StaticAnalyzer/Core/SVals.cpp
@@ -113,12 +113,12 @@
 /// Casts are ignored during lookup.
 /// \param IncludeBaseRegions The boolean that controls whether the search
 /// should continue to the base regions if the region is not symbolic.
-SymbolRef SVal::getAsSymbol(bool IncludeBaseRegion) const {
+SymbolRef SVal::getAsSymbol(bool IncludeBaseRegions) const {
   // FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
   if (Optional<nonloc::SymbolVal> X = getAs<nonloc::SymbolVal>())
     return X->getSymbol();
 
-  return getAsLocSymbol(IncludeBaseRegion);
+  return getAsLocSymbol(IncludeBaseRegions);
 }
 
 /// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
diff --git a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
index f09f969..a5b5744 100644
--- a/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ b/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -360,10 +360,18 @@
       Loc lhsL = lhs.castAs<nonloc::LocAsInteger>().getLoc();
       switch (rhs.getSubKind()) {
         case nonloc::LocAsIntegerKind:
+          // FIXME: at the moment the implementation
+          // of modeling "pointers as integers" is not complete.
+          if (!BinaryOperator::isComparisonOp(op))
+            return UnknownVal();
           return evalBinOpLL(state, op, lhsL,
                              rhs.castAs<nonloc::LocAsInteger>().getLoc(),
                              resultTy);
         case nonloc::ConcreteIntKind: {
+          // FIXME: at the moment the implementation
+          // of modeling "pointers as integers" is not complete.
+          if (!BinaryOperator::isComparisonOp(op))
+            return UnknownVal();
           // Transform the integer into a location and compare.
           // FIXME: This only makes sense for comparisons. If we want to, say,
           // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,
@@ -718,9 +726,11 @@
     if (Optional<loc::ConcreteInt> rInt = rhs.getAs<loc::ConcreteInt>()) {
       // If one of the operands is a symbol and the other is a constant,
       // build an expression for use by the constraint manager.
-      if (SymbolRef lSym = lhs.getAsLocSymbol(true))
-        return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
-
+      if (SymbolRef lSym = lhs.getAsLocSymbol(true)) {
+        if (BinaryOperator::isComparisonOp(op))
+          return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
+        return UnknownVal();
+      }
       // Special case comparisons to NULL.
       // This must come after the test if the LHS is a symbol, which is used to
       // build constraints. The address of any non-symbolic region is guaranteed
@@ -912,6 +922,10 @@
   if (rhs.isZeroConstant())
     return lhs;
 
+  // Perserve the null pointer so that it can be found by the DerefChecker.
+  if (lhs.isZeroConstant())
+    return lhs;
+
   // We are dealing with pointer arithmetic.
 
   // Handle pointer arithmetic on constant values.
@@ -927,6 +941,8 @@
 
       // Offset the increment by the pointer size.
       llvm::APSInt Multiplicand(rightI.getBitWidth(), /* isUnsigned */ true);
+      QualType pointeeType = resultTy->getPointeeType();
+      Multiplicand = getContext().getTypeSizeInChars(pointeeType).getQuantity();
       rightI *= Multiplicand;
 
       // Compute the adjusted pointer.
@@ -1016,7 +1032,8 @@
               SVB.getKnownValue(State, nonloc::SymbolVal(S)))
         return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
                                             : (SVal)SVB.makeIntVal(*I);
-      return nonloc::SymbolVal(S);
+      return Loc::isLocType(S->getType()) ? (SVal)SVB.makeLoc(S) 
+                                          : nonloc::SymbolVal(S);
     }
 
     // TODO: Support SymbolCast. Support IntSymExpr when/if we actually
diff --git a/lib/StaticAnalyzer/Core/Store.cpp b/lib/StaticAnalyzer/Core/Store.cpp
index 1af49f6..173fdd8 100644
--- a/lib/StaticAnalyzer/Core/Store.cpp
+++ b/lib/StaticAnalyzer/Core/Store.cpp
@@ -440,7 +440,10 @@
   //  value. See also the similar FIXME in getLValueFieldOrIvar().
   if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>())
     return Base;
-
+  
+  if (Base.getAs<loc::GotoLabel>())
+    return UnknownVal();
+  
   const SubRegion *BaseRegion =
       Base.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>();
 
diff --git a/lib/StaticAnalyzer/Core/SymbolManager.cpp b/lib/StaticAnalyzer/Core/SymbolManager.cpp
index 4be8566..f2d5ee8 100644
--- a/lib/StaticAnalyzer/Core/SymbolManager.cpp
+++ b/lib/StaticAnalyzer/Core/SymbolManager.cpp
@@ -31,14 +31,20 @@
   os << '(';
   getLHS()->dumpToStream(os);
   os << ") "
-     << BinaryOperator::getOpcodeStr(getOpcode()) << ' '
-     << getRHS().getZExtValue();
+     << BinaryOperator::getOpcodeStr(getOpcode()) << ' ';
+  if (getRHS().isUnsigned())
+    os << getRHS().getZExtValue();
+  else
+    os << getRHS().getSExtValue();
   if (getRHS().isUnsigned())
     os << 'U';
 }
 
 void IntSymExpr::dumpToStream(raw_ostream &os) const {
-  os << getLHS().getZExtValue();
+  if (getLHS().isUnsigned())
+    os << getLHS().getZExtValue();
+  else
+    os << getLHS().getSExtValue();
   if (getLHS().isUnsigned())
     os << 'U';
   os << ' '
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..ebf6abc
--- /dev/null
+++ b/lib/Tooling/Refactor/ASTSlice.cpp
@@ -0,0 +1,636 @@
+//===--- 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;
+  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;
+    }
+  }
+
+  // Look through the implicit casts in the parents.
+  unsigned ParentIndex = Index + 1;
+  for (; ParentIndex <= NodeTree.size() && isa<ImplicitCastExpr>(Parent);
+       ++ParentIndex) {
+    const Stmt *NewParent = NodeTree[ParentIndex + 1].getStmtOrNull();
+    if (!NewParent)
+      break;
+    Parent = NewParent;
+  }
+  Next = std::make_pair(Parent, ParentIndex);
+
+  // 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..fcdb9e6
--- /dev/null
+++ b/lib/Tooling/Refactor/ExtractRepeatedExpressionIntoVariable.cpp
@@ -0,0 +1,298 @@
+//===--- 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) {
+  RefactoringResult Result(std::vector<RefactoringReplacement>{});
+  std::vector<RefactoringReplacement> &Replacements = Result.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);
+  Result.AssociatedSymbols.push_back(
+      llvm::make_unique<RefactoringResultAssociatedSymbol>(SymbolName(Name)));
+  RefactoringResultAssociatedSymbol *CreatedSymbol =
+      Result.AssociatedSymbols.back().get();
+
+  // 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);
+  // 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(Name);
+  OS << " = ";
+  PrintingPolicy ExprPP = Context.getPrintingPolicy();
+  ExprPP.SuppressStrongLifetime = true;
+  ExprPP.SuppressImplicitBase = true;
+  E->printPretty(OS, /*Helper=*/nullptr, ExprPP);
+  OS << ";\n";
+  Replacements.push_back(RefactoringReplacement(
+      SourceRange(InsertionLoc, InsertionLoc), OS.str(), CreatedSymbol,
+      RefactoringReplacement::AssociatedSymbolLocation(
+          llvm::makeArrayRef(NameOffset), /*IsDeclaration=*/true)));
+
+  // Replace the duplicates with a reference to the variable.
+  for (const Expr *E : DuplicateExpressions) {
+    Replacements.push_back(RefactoringReplacement(
+        SourceRange(SM.getSpellingLoc(E->getLocStart()),
+                    getPreciseTokenLocEnd(SM.getSpellingLoc(E->getLocEnd()), SM,
+                                          Context.getLangOpts())),
+        Name, CreatedSymbol,
+        /*NameOffset=*/llvm::makeArrayRef(unsigned(0))));
+  }
+
+  return std::move(Result);
+}
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..87e4f8d
--- /dev/null
+++ b/lib/Tooling/Refactor/SymbolOccurrenceFinder.cpp
@@ -0,0 +1,422 @@
+//===--- 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;
+  }
+
+  bool VisitOffsetOfExpr(const OffsetOfExpr *S) {
+    for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
+      const OffsetOfNode &Component = S->getComponent(I);
+      if (Component.getKind() == OffsetOfNode::Field)
+        checkDecl(Component.getField(), Component.getLocEnd());
+      // FIXME: Try to resolve dependent field references.
+    }
+    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..4bb2359
--- /dev/null
+++ b/lib/Tooling/Refactor/USRFinder.cpp
@@ -0,0 +1,718 @@
+//===--- 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());
+  }
+
+  bool VisitOffsetOfExpr(const OffsetOfExpr *S) {
+    for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) {
+      const OffsetOfNode &Component = S->getComponent(I);
+      if (Component.getKind() == OffsetOfNode::Field) {
+        if (!checkOccurrence(Component.getField(), Component.getLocEnd()))
+          return false;
+      }
+      // FIXME: Try to resolve dependent field references.
+    }
+    return true;
+  }
+
+  // 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..f44d377 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 fuzzer 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..f66038b
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.apinotes
@@ -0,0 +1,42 @@
+Name: SimpleKit
+Tags:
+- Name: RenamedAgainInAPINotesA
+  SwiftName: SuccessfullyRenamedA
+- Name: RenamedAgainInAPINotesB
+  SwiftName: SuccessfullyRenamedB
+Functions:
+- Name: getCFOwnedToUnowned
+  RetainCountConvention: CFReturnsNotRetained
+- Name: getCFUnownedToOwned
+  RetainCountConvention: CFReturnsRetained
+- Name: getCFOwnedToNone
+  RetainCountConvention: none
+- Name: getObjCOwnedToUnowned
+  RetainCountConvention: NSReturnsNotRetained
+- Name: getObjCUnownedToOwned
+  RetainCountConvention: NSReturnsRetained
+- Name: indirectGetCFOwnedToUnowned
+  Parameters:
+  - Position: 0
+    RetainCountConvention: CFReturnsNotRetained
+- Name: indirectGetCFUnownedToOwned
+  Parameters:
+  - Position: 0
+    RetainCountConvention: CFReturnsRetained
+- Name: indirectGetCFOwnedToNone
+  Parameters:
+  - Position: 0
+    RetainCountConvention: none
+- Name: indirectGetCFNoneToOwned
+  Parameters:
+  - Position: 0
+    RetainCountConvention: CFReturnsNotRetained
+Classes:
+- Name: MethodTest
+  Methods:
+  - Selector: getOwnedToUnowned
+    MethodKind: Instance
+    RetainCountConvention: NSReturnsNotRetained
+  - Selector: getUnownedToOwned
+    MethodKind: Instance
+    RetainCountConvention: NSReturnsRetained
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..e11adb7
--- /dev/null
+++ b/test/APINotes/Inputs/Frameworks/SimpleKit.framework/Headers/SimpleKit.h
@@ -0,0 +1,23 @@
+struct RenamedAgainInAPINotesA {
+  int field;
+} __attribute__((swift_name("bad")));
+
+struct __attribute__((swift_name("bad"))) RenamedAgainInAPINotesB {
+  int field;
+};
+
+void *getCFOwnedToUnowned(void) __attribute__((cf_returns_retained));
+void *getCFUnownedToOwned(void) __attribute__((cf_returns_not_retained));
+void *getCFOwnedToNone(void) __attribute__((cf_returns_retained));
+id getObjCOwnedToUnowned(void) __attribute__((ns_returns_retained));
+id getObjCUnownedToOwned(void) __attribute__((ns_returns_not_retained));
+
+int indirectGetCFOwnedToUnowned(void **out __attribute__((cf_returns_retained)));
+int indirectGetCFUnownedToOwned(void **out __attribute__((cf_returns_not_retained)));
+int indirectGetCFOwnedToNone(void **out __attribute__((cf_returns_retained)));
+int indirectGetCFNoneToOwned(void **out);
+
+@interface MethodTest
+- (id)getOwnedToUnowned __attribute__((ns_returns_retained));
+- (id)getUnownedToOwned __attribute__((ns_returns_not_retained));
+@end
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..d6e6cfb
--- /dev/null
+++ b/test/APINotes/Inputs/roundtrip.apinotes
@@ -0,0 +1,197 @@
+---
+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
+        RetainCountConvention: NSReturnsNotRetained
+        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:            CFURLCopyResourcePropertiesForKeys
+    Parameters:      
+      - Position:        0
+      - Position:        1
+      - Position:        2
+        RetainCountConvention: CFReturnsRetained
+    RetainCountConvention: CFReturnsRetained
+    Availability:    available
+    AvailabilityMsg: ''
+    SwiftName:       ''
+  - 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/retain-count-convention.m b/test/APINotes/retain-count-convention.m
new file mode 100644
index 0000000..46fb90c
--- /dev/null
+++ b/test/APINotes/retain-count-convention.m
@@ -0,0 +1,20 @@
+// 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 -F %S/Inputs/Frameworks %s
+// RUN: %clang_cc1 -ast-print %t/ModulesCache/SimpleKit.pcm | FileCheck %s
+
+#import <SimpleKit/SimpleKit.h>
+
+// CHECK: void *getCFOwnedToUnowned() __attribute__((cf_returns_not_retained));
+// CHECK: void *getCFUnownedToOwned() __attribute__((cf_returns_retained));
+// CHECK: void *getCFOwnedToNone();
+// CHECK: id getObjCOwnedToUnowned() __attribute__((ns_returns_not_retained));
+// CHECK: id getObjCUnownedToOwned() __attribute__((ns_returns_retained));
+// CHECK: int indirectGetCFOwnedToUnowned(void * _Nullable *out __attribute__((cf_returns_not_retained)));
+// CHECK: int indirectGetCFUnownedToOwned(void * _Nullable *out __attribute__((cf_returns_retained)));
+// CHECK: int indirectGetCFOwnedToNone(void * _Nullable *out);
+// CHECK: int indirectGetCFNoneToOwned(void **out __attribute__((cf_returns_not_retained)));
+
+// CHECK-LABEL: @interface MethodTest
+// CHECK: - (id)getOwnedToUnowned __attribute__((ns_returns_not_retained));
+// CHECK: - (id)getUnownedToOwned __attribute__((ns_returns_retained));
+// CHECK: @end
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..f14d18f
--- /dev/null
+++ b/test/APINotes/yaml-roundtrip.c
@@ -0,0 +1,4 @@
+# RUN: %clang -cc1apinotes -yaml-to-binary -o %t.apinotesc %S/Inputs/roundtrip.apinotes
+# RUN: %clang -cc1apinotes -binary-to-yaml -o %t.apinotes %t.apinotesc
+# RUN: diff %S/Inputs/roundtrip.apinotes %t.apinotes
+
diff --git a/test/Analysis/DeleteWithNonVirtualDtor.cpp b/test/Analysis/DeleteWithNonVirtualDtor.cpp
new file mode 100644
index 0000000..a9b8a11
--- /dev/null
+++ b/test/Analysis/DeleteWithNonVirtualDtor.cpp
@@ -0,0 +1,187 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=alpha.cplusplus.DeleteWithNonVirtualDtor -std=c++11 -verify -analyzer-output=text %s
+
+struct Virtual {
+  virtual ~Virtual() {}
+};
+
+struct VDerived : public Virtual {};
+
+struct NonVirtual {
+  ~NonVirtual() {}
+};
+
+struct NVDerived : public NonVirtual {};
+struct NVDoubleDerived : public NVDerived {};
+
+struct Base {
+  virtual void destroy() = 0;
+};
+
+class PrivateDtor final : public Base {
+public:
+  void destroy() { delete this; }
+private:
+  ~PrivateDtor() {}
+};
+
+struct ImplicitNV {
+  virtual void f();
+};
+
+struct ImplicitNVDerived : public ImplicitNV {};
+
+NVDerived *get();
+
+NonVirtual *create() {
+  NonVirtual *x = new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
+  return x;
+}
+
+void sink(NonVirtual *x) {
+  delete x; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void sinkCast(NonVirtual *y) {
+  delete reinterpret_cast<NVDerived*>(y);
+}
+
+void sinkParamCast(NVDerived *z) {
+  delete z;
+}
+
+void singleDerived() {
+  NonVirtual *sd;
+  sd = new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
+  delete sd; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void singleDerivedArr() {
+  NonVirtual *sda = new NVDerived[5]; // expected-note{{Conversion from derived to base happened here}}
+  delete[] sda; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void doubleDerived() {
+  NonVirtual *dd = new NVDoubleDerived(); // expected-note{{Conversion from derived to base happened here}}
+  delete (dd); // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void assignThroughFunction() {
+  NonVirtual *atf = get(); // expected-note{{Conversion from derived to base happened here}}
+  delete atf; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void assignThroughFunction2() {
+  NonVirtual *atf2;
+  atf2 = get(); // expected-note{{Conversion from derived to base happened here}}
+  delete atf2; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void createThroughFunction() {
+  NonVirtual *ctf = create(); // expected-note{{Calling 'create'}}
+  // expected-note@-1{{Returning from 'create'}}
+  delete ctf; // expected-warning {{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void deleteThroughFunction() {
+  NonVirtual *dtf = new NVDerived(); // expected-note{{Conversion from derived to base happened here}}
+  sink(dtf); // expected-note{{Calling 'sink'}}
+}
+
+void singleCastCStyle() {
+  NVDerived *sccs = new NVDerived();
+  NonVirtual *sccs2 = (NonVirtual*)sccs; // expected-note{{Conversion from derived to base happened here}}
+  delete sccs2; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void doubleCastCStyle() {
+  NonVirtual *dccs = new NVDerived();
+  NVDerived *dccs2 = (NVDerived*)dccs;
+  dccs = (NonVirtual*)dccs2; // expected-note{{Conversion from derived to base happened here}}
+  delete dccs; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void singleCast() {
+  NVDerived *sc = new NVDerived();
+  NonVirtual *sc2 = reinterpret_cast<NonVirtual*>(sc); // expected-note{{Conversion from derived to base happened here}}
+  delete sc2; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void doubleCast() {
+  NonVirtual *dd = new NVDerived();
+  NVDerived *dd2 = reinterpret_cast<NVDerived*>(dd);
+  dd = reinterpret_cast<NonVirtual*>(dd2); // expected-note {{Conversion from derived to base happened here}}
+  delete dd; // expected-warning {{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void implicitNV() {
+  ImplicitNV *invd = new ImplicitNVDerived(); // expected-note{{Conversion from derived to base happened here}}
+  delete invd; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void doubleDecl() {
+  ImplicitNV *dd1, *dd2;
+  dd1 = new ImplicitNVDerived(); // expected-note{{Conversion from derived to base happened here}}
+  delete dd1; // expected-warning{{Destruction of a polymorphic object with no virtual destructor}}
+  // expected-note@-1{{Destruction of a polymorphic object with no virtual destructor}}
+}
+
+void virtualBase() {
+  Virtual *vb = new VDerived();
+  delete vb; // no-warning
+}
+
+void notDerived() {
+  NonVirtual *nd = new NonVirtual();
+  delete nd; // no-warning
+}
+
+void notDerivedArr() {
+  NonVirtual *nda = new NonVirtual[3];
+  delete[] nda; // no-warning
+}
+
+void cast() {
+  NonVirtual *c = new NVDerived();
+  delete reinterpret_cast<NVDerived*>(c); // no-warning
+}
+
+void deleteThroughFunction2() {
+  NonVirtual *dtf2 = new NVDerived();
+  sinkCast(dtf2); // no-warning
+}
+
+void deleteThroughFunction3() {
+  NVDerived *dtf3;
+  dtf3 = new NVDerived();
+  sinkParamCast(dtf3); // no-warning
+}
+
+void stackVar() {
+  NonVirtual sv2;
+  delete &sv2; // no-warning
+}
+
+// Deleting a polymorphic object with a non-virtual dtor
+// is not a problem if it is referenced by its precise type.
+
+void preciseType() {
+  NVDerived *pt = new NVDerived();
+  delete pt; // no-warning
+}
+
+void privateDtor() {
+  Base *pd = new PrivateDtor();
+  pd->destroy(); // no-warning
+}
diff --git a/test/Analysis/MisusedMovedObject.cpp b/test/Analysis/MisusedMovedObject.cpp
index 44e055f..132a65d 100644
--- a/test/Analysis/MisusedMovedObject.cpp
+++ b/test/Analysis/MisusedMovedObject.cpp
@@ -38,6 +38,7 @@
   B() = default;
   B(const B &) = default;
   B(B &&) = default;
+  B& operator=(const B &q) = default;
   void operator=(B &&b) {
     return;
   }
@@ -70,6 +71,12 @@
   A(A &&other, char *k) {
     moveconstruct(std::move(other));
   }
+  void operator=(const A &other) {
+    i = other.i;
+    d = other.d;
+    b = other.b;
+    return;
+  }
   void operator=(A &&other) {
     moveconstruct(std::move(other));
     return;
@@ -105,17 +112,42 @@
 }
 
 void simpleMoveCtorTest() {
-  A a;
-  A b;
-  b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
-  a.foo();          // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+  {
+    A a;
+    A b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    a.foo();            // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+  }
+  {
+    A a;
+    A b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    b = a;              // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}}
+  }
+  {
+    A a;
+    A b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    b = std::move(a);   // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}}
+  }
 }
 
 void simpleMoveAssignementTest() {
-  A a;
-  A b;
-  b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
-  a.foo();          // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+  {
+    A a;
+    A b;
+    b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    a.foo();          // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
+  }
+  {
+    A a;
+    A b;
+    b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
+    A c(a);           // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}}
+  }
+  {
+    A a;
+    A b;
+    b = std::move(a);  // expected-note {{'a' became 'moved-from' here}}
+    A c(std::move(a)); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}}
+  }
 }
 
 void moveInInitListTest() {
@@ -270,7 +302,7 @@
   {
     A a;
     for (int i = 0; i < bignum(); i++) { // expected-note {{Loop condition is true.  Entering loop body}} expected-note {{Loop condition is true.  Entering loop body}}
-      constCopyOrMoveCall(std::move(a)); // expected-warning {{Copying a 'moved-from' object 'a'}} expected-note {{Copying a 'moved-from' object 'a'}}
+      constCopyOrMoveCall(std::move(a)); // expected-warning {{Moving a 'moved-from' object 'a'}} expected-note {{Moving a 'moved-from' object 'a'}}
       // expected-note@-1 {{'a' became 'moved-from' here}}
     }
   }
@@ -332,6 +364,8 @@
     A b = std::move(a);
     a.reset(); // no-warning
     a.foo();   // no-warning
+    // Test if resets the state of subregions as well.
+    a.b.foo(); // no-warning
   }
   {
     A a;
@@ -344,6 +378,7 @@
     A b = std::move(a);
     a.clear(); // no-warning
     a.foo();   // no-warning
+    a.b.foo(); // no-warning
   }
 }
 
@@ -444,7 +479,7 @@
   // Same thing, but with a switch statement.
   {
     A a, b;
-    switch (i) { // expected-note {{Control jumps to 'case 1:'  at line 448}}
+    switch (i) { // expected-note {{Control jumps to 'case 1:'  at line 483}}
     case 1:
       b = std::move(a); // no-warning
       break;            // expected-note {{Execution jumps to the end of the function}}
@@ -456,7 +491,7 @@
   // However, if there's a fallthrough, we do warn.
   {
     A a, b;
-    switch (i) { // expected-note {{Control jumps to 'case 1:'  at line 460}}
+    switch (i) { // expected-note {{Control jumps to 'case 1:'  at line 495}}
     case 1:
       b = std::move(a); // expected-note {{'a' became 'moved-from' here}}
     case 2:
@@ -598,6 +633,7 @@
   }
 }
 
+class C : public A {};
 void subRegionMoveTest() {
   {
     A a;
@@ -616,4 +652,24 @@
     a.foo();             // expected-warning {{Method call on a 'moved-from' object 'a'}} expected-note {{Method call on a 'moved-from' object 'a'}}
     a.b.foo();           // no-warning
   }
+  {
+    C c;
+    C c1 = std::move(c); // expected-note {{'c' became 'moved-from' here}}
+    c.foo();             // expected-warning {{Method call on a 'moved-from' object 'c'}} expected-note {{Method call on a 'moved-from' object 'c'}}
+    c.b.foo();           // no-warning
+  }
+}
+
+void resetSuperClass() {
+  C c;
+  C c1 = std::move(c);
+  c.clear();
+  C c2 = c; // no-warning
+}
+
+void reportSuperClass() {
+  C c;
+  C c1 = std::move(c); // expected-note {{'c' became 'moved-from' here}}
+  c.foo();             // expected-warning {{Method call on a 'moved-from' object 'c'}} expected-note {{Method call on a 'moved-from' object 'c'}}
+  C c2 = c;            // no-warning
 }
diff --git a/test/Analysis/analyzer-config.c b/test/Analysis/analyzer-config.c
index 0d8d34f..4daea89 100644
--- a/test/Analysis/analyzer-config.c
+++ b/test/Analysis/analyzer-config.c
@@ -14,6 +14,7 @@
 // CHECK-NEXT: cfg-conditional-static-initializers = true
 // CHECK-NEXT: cfg-implicit-dtors = true
 // CHECK-NEXT: cfg-lifetime = false
+// CHECK-NEXT: cfg-loopexit = false
 // CHECK-NEXT: cfg-temporary-dtors = false
 // CHECK-NEXT: faux-bodies = true
 // CHECK-NEXT: graph-trim-interval = 1000
@@ -27,6 +28,7 @@
 // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
 // CHECK-NEXT: mode = deep
 // CHECK-NEXT: region-store-small-struct-limit = 2
+// CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 17
+// CHECK-NEXT: num-entries = 19
diff --git a/test/Analysis/analyzer-config.cpp b/test/Analysis/analyzer-config.cpp
index 4166a73..a08e85e 100644
--- a/test/Analysis/analyzer-config.cpp
+++ b/test/Analysis/analyzer-config.cpp
@@ -25,6 +25,7 @@
 // CHECK-NEXT: cfg-conditional-static-initializers = true
 // CHECK-NEXT: cfg-implicit-dtors = true
 // CHECK-NEXT: cfg-lifetime = false
+// CHECK-NEXT: cfg-loopexit = false
 // CHECK-NEXT: cfg-temporary-dtors = false
 // CHECK-NEXT: faux-bodies = true
 // CHECK-NEXT: graph-trim-interval = 1000
@@ -38,6 +39,7 @@
 // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
 // CHECK-NEXT: mode = deep
 // CHECK-NEXT: region-store-small-struct-limit = 2
+// CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 22
+// CHECK-NEXT: num-entries = 24
diff --git a/test/Analysis/bitwise-ops.c b/test/Analysis/bitwise-ops.c
index 407aa19..fe54658 100644
--- a/test/Analysis/bitwise-ops.c
+++ b/test/Analysis/bitwise-ops.c
@@ -22,11 +22,32 @@
   case 1:
     return 0ULL << 63; // no-warning
   case 2:
-    return 0ULL << 64; // expected-warning{{The result of the '<<' expression is undefined}}
+    return 0ULL << 64; // expected-warning{{The result of the left shift is undefined due to shifting by '64', which is greater or equal to the width of type 'unsigned long long'}}
   case 3:
-    return 0ULL << 65; // expected-warning{{The result of the '<<' expression is undefined}}
+    return 0ULL << 65; // expected-warning{{The result of the left shift is undefined due to shifting by '65', which is greater or equal to the width of type 'unsigned long long'}}
 
   default:
     return 0;
   }
-}
\ No newline at end of file
+}
+
+int testOverflowShift(int a) {
+  if (a == 323) {
+    return 1 << a; // expected-warning{{The result of the left shift is undefined due to shifting by '323', which is greater or equal to the width of type 'int'}}
+  }
+  return 0;
+}
+
+int testNegativeShift(int a) {
+  if (a == -5) {
+    return 1 << a; // expected-warning{{The result of the left shift is undefined because the right operand is negative}}
+  }
+  return 0;
+}
+
+int testNegativeLeftShift(int a) {
+  if (a == -3) {
+    return a << 1; // expected-warning{{The result of the left shift is undefined because the left operand is negative}}
+  }
+  return 0;
+}
diff --git a/test/Analysis/block-in-critical-section.cpp b/test/Analysis/block-in-critical-section.cpp
index c65cc61..fcf6188 100644
--- a/test/Analysis/block-in-critical-section.cpp
+++ b/test/Analysis/block-in-critical-section.cpp
@@ -7,6 +7,20 @@
   void lock() {}
   void unlock() {}
 };
+template<typename T>
+struct lock_guard {
+  lock_guard<T>(std::mutex) {}
+  ~lock_guard<T>() {}
+};
+template<typename T>
+struct unique_lock {
+  unique_lock<T>(std::mutex) {}
+  ~unique_lock<T>() {}
+};
+template<typename T>
+struct not_real_lock {
+  not_real_lock<T>(std::mutex) {}
+};
 }
 
 void getc() {}
@@ -110,3 +124,31 @@
   m.lock();
   sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
 }
+
+void testBlockInCriticalSectionLockGuard() {
+  std::mutex g_mutex;
+  std::not_real_lock<std::mutex> not_real_lock(g_mutex);
+  sleep(1); // no-warning
+
+  std::lock_guard<std::mutex> lock(g_mutex);
+  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+}
+
+void testBlockInCriticalSectionLockGuardNested() {
+  testBlockInCriticalSectionLockGuard();
+  sleep(1); // no-warning
+}
+
+void testBlockInCriticalSectionUniqueLock() {
+  std::mutex g_mutex;
+  std::not_real_lock<std::mutex> not_real_lock(g_mutex);
+  sleep(1); // no-warning
+
+  std::unique_lock<std::mutex> lock(g_mutex);
+  sleep(1); // expected-warning {{Call to blocking function 'sleep' inside of critical section}}
+}
+
+void testBlockInCriticalSectionUniqueLockNested() {
+  testBlockInCriticalSectionUniqueLock();
+  sleep(1); // no-warning
+}
diff --git a/test/Analysis/block-in-critical-section.m b/test/Analysis/block-in-critical-section.m
new file mode 100644
index 0000000..73d5847
--- /dev/null
+++ b/test/Analysis/block-in-critical-section.m
@@ -0,0 +1,10 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.BlockInCriticalSection -verify -Wno-objc-root-class %s
+// expected-no-diagnostics
+
+@interface SomeClass
+-(void)someMethod;
+@end
+
+void shouldNotCrash(SomeClass *o) {
+  [o someMethod];
+}
diff --git a/test/Analysis/bstring.cpp b/test/Analysis/bstring.cpp
index a6d7b40..fea76cc 100644
--- a/test/Analysis/bstring.cpp
+++ b/test/Analysis/bstring.cpp
@@ -1,8 +1,35 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
 
 #include "Inputs/system-header-simulator-cxx.h"
 #include "Inputs/system-header-simulator-for-malloc.h"
 
+// This provides us with four possible mempcpy() definitions.
+// See also comments in bstring.c.
+
+#ifdef USE_BUILTINS
+#define BUILTIN(f) __builtin_##f
+#else /* USE_BUILTINS */
+#define BUILTIN(f) f
+#endif /* USE_BUILTINS */
+
+#ifdef VARIANT
+
+#define __mempcpy_chk BUILTIN(__mempcpy_chk)
+void *__mempcpy_chk(void *__restrict__ s1, const void *__restrict__ s2,
+                    size_t n, size_t destlen);
+
+#define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1)
+
+#else /* VARIANT */
+
+#define mempcpy BUILTIN(mempcpy)
+void *mempcpy(void *__restrict__ s1, const void *__restrict__ s2, size_t n);
+
+#endif /* VARIANT */
+
 void clang_analyzer_eval(int);
 
 int *testStdCopyInvalidatesBuffer(std::vector<int> v) {
@@ -36,3 +63,17 @@
 
   return buf;
 }
+
+namespace pr34460 {
+short a;
+class b {
+  int c;
+  long g;
+  void d() {
+    int e = c;
+    f += e;
+    mempcpy(f, &a, g);
+  }
+  unsigned *f;
+};
+}
diff --git a/test/Analysis/bug_hash_test.cpp b/test/Analysis/bug_hash_test.cpp
index 0efcb5f..f397d18 100644
--- a/test/Analysis/bug_hash_test.cpp
+++ b/test/Analysis/bug_hash_test.cpp
@@ -1,1345 +1,122 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
-// RUN: FileCheck --input-file=%t.plist %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,debug.ExprInspection %s -verify
 
-int function(int p) {
-  return 5;
+constexpr int clang_analyzer_hashDump(int) { return 5; }
+
+void function(int) {
+  clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void function(int)$27$clang_analyzer_hashDump(5);$Category}}
 }
 
 namespace {
-int variadicParam(int p, ...) {
-  return 5;
+void variadicParam(int, ...) {
+  clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void (anonymous namespace)::variadicParam(int, ...)$27$clang_analyzer_hashDump(5);$Category}}
 }
-}
+} // namespace
 
-constexpr int f() { return 5; }
+constexpr int f() {
+  return clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$int f()$34$returnclang_analyzer_hashDump(5);$Category}}
+}
 
 namespace AA {
-  class X {
-    int priv;
-    X() : priv(5) { priv = 0; }
+class X {
+  X() {
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$AA::X::X()$29$clang_analyzer_hashDump(5);$Category}}
+  }
 
-    static int static_method() {
-      return 5;
-    }
+  static void static_method() {
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void AA::X::static_method()$29$clang_analyzer_hashDump(5);$Category}}
+    variadicParam(5);
+  }
 
-    int method() && {
-      class Y {
-        inline int method() const & {
-          return 5;
-        }
-      };
+  void method() && {
+    struct Y {
+      inline void method() const & {
+        clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void AA::X::method()::Y::method() const &$33$clang_analyzer_hashDump(5);$Category}}
+      }
+    };
 
-      return 5;
-    }
+    Y y;
+    y.method();
 
-    int OutOfLine();
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void AA::X::method() &&$29$clang_analyzer_hashDump(5);$Category}}
+  }
 
-    X& operator=(int a) {
-      return *this;
-    }
+  void OutOfLine();
 
-    operator int() {
-      return 0;
-    }
+  X &operator=(int) {
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$class AA::X & AA::X::operator=(int)$29$clang_analyzer_hashDump(5);$Category}}
+    return *this;
+  }
 
-    explicit operator float() {
-      return 0;
-    }
-  };
-}
+  operator int() {
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$AA::X::operator int()$29$clang_analyzer_hashDump(5);$Category}}
+    return 0;
+  }
 
-int AA::X::OutOfLine() {
-  return 5;
+  explicit operator float() {
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$AA::X::operator float()$29$clang_analyzer_hashDump(5);$Category}}
+    return 0;
+  }
+};
+} // namespace AA
+
+void AA::X::OutOfLine() {
+  clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void AA::X::OutOfLine()$27$clang_analyzer_hashDump(5);$Category}}
 }
 
 void testLambda() {
-  [] () {
-    return;
+  []() {
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void testLambda()::(anonymous class)::operator()() const$29$clang_analyzer_hashDump(5);$Category}}
   }();
 }
 
-// CHECK: <key>diagnostics</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>5</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>5</integer>
-// CHECK-NEXT:           <key>col</key><integer>8</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>5</integer>
-// CHECK-NEXT:           <key>col</key><integer>10</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>5</integer>
-// CHECK-NEXT:           <key>col</key><integer>10</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>5</integer>
-// CHECK-NEXT:      <key>col</key><integer>10</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>5</integer>
-// CHECK-NEXT:         <key>col</key><integer>10</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>5</integer>
-// CHECK-NEXT:         <key>col</key><integer>10</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int function(int)$10$return5;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int function(int)$10$return5;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$int function(int)$10$return5;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>e7be204e83f8e5ad3c870ec011d5131d</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>function</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>5</integer>
-// CHECK-NEXT:   <key>col</key><integer>10</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>10</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>10</integer>
-// CHECK-NEXT:           <key>col</key><integer>8</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>10</integer>
-// CHECK-NEXT:           <key>col</key><integer>10</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>10</integer>
-// CHECK-NEXT:           <key>col</key><integer>10</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>10</integer>
-// CHECK-NEXT:      <key>col</key><integer>10</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>10</integer>
-// CHECK-NEXT:         <key>col</key><integer>10</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>10</integer>
-// CHECK-NEXT:         <key>col</key><integer>10</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int (anonymous namespace)::variadicParam(int, ...)$10$return5;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int (anonymous namespace)::variadicParam(int, ...)$10$return5;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$int (anonymous namespace)::variadicParam(int, ...)$10$return5;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>bc5dc0507ee90f1d14259057d25fb2b9</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>variadicParam</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>10</integer>
-// CHECK-NEXT:   <key>col</key><integer>10</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>14</integer>
-// CHECK-NEXT:           <key>col</key><integer>21</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>14</integer>
-// CHECK-NEXT:           <key>col</key><integer>26</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>14</integer>
-// CHECK-NEXT:           <key>col</key><integer>28</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>14</integer>
-// CHECK-NEXT:           <key>col</key><integer>28</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>14</integer>
-// CHECK-NEXT:      <key>col</key><integer>28</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>14</integer>
-// CHECK-NEXT:         <key>col</key><integer>28</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>14</integer>
-// CHECK-NEXT:         <key>col</key><integer>28</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int f()$28$constexprintf(){return5;}$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int f()$28$constexprintf(){return5;}$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$int f()$28$constexprintf(){return5;}$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>f5471f52854dc14167fe96db50c4ba5f</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>f</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>14</integer>
-// CHECK-NEXT:   <key>col</key><integer>28</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>19</integer>
-// CHECK-NEXT:      <key>col</key><integer>16</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>16</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>16</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::X()$16$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::X()$16$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$AA::X::X()$16$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>d23266517ac17d5ec5e2fbbdb1922af1</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>19</integer>
-// CHECK-NEXT:   <key>col</key><integer>16</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>16</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>16</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>21</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>24</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>19</integer>
-// CHECK-NEXT:      <key>col</key><integer>21</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>21</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>24</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>7bfcc45512a6a3f61dda6e3ecebc7384</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>19</integer>
-// CHECK-NEXT:   <key>col</key><integer>21</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>16</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>16</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>21</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>24</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>21</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>24</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>26</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>26</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>19</integer>
-// CHECK-NEXT:      <key>col</key><integer>26</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>21</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>28</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$AA::X::X()$21$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>95dbfbcdd1dd6401d262994c45d088be</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>19</integer>
-// CHECK-NEXT:   <key>col</key><integer>26</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>16</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>16</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>21</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>24</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>21</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>24</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>28</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>28</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>19</integer>
-// CHECK-NEXT:      <key>col</key><integer>28</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>28</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>28</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::X()$28$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::X()$28$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$AA::X::X()$28$X():priv(5){priv=0;}$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>064a01551caa8eca3202f1fd55b9c692</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>0</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>19</integer>
-// CHECK-NEXT:   <key>col</key><integer>28</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>22</integer>
-// CHECK-NEXT:           <key>col</key><integer>7</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>22</integer>
-// CHECK-NEXT:           <key>col</key><integer>12</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>22</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>22</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>22</integer>
-// CHECK-NEXT:      <key>col</key><integer>14</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>22</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>22</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int AA::X::static_method()$14$return5;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int AA::X::static_method()$14$return5;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$int AA::X::static_method()$14$return5;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>651fcca72f8ad65771702903ecd5f68a</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>C++ method</string>
-// CHECK-NEXT:  <key>issue_context</key><string>static_method</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>22</integer>
-// CHECK-NEXT:   <key>col</key><integer>14</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>32</integer>
-// CHECK-NEXT:           <key>col</key><integer>7</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>32</integer>
-// CHECK-NEXT:           <key>col</key><integer>12</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>32</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>32</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>32</integer>
-// CHECK-NEXT:      <key>col</key><integer>14</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>32</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>32</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int AA::X::method() &amp;&amp;$14$return5;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int AA::X::method() &amp;&amp;$14$return5;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$int AA::X::method() &amp;&amp;$14$return5;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>c8ac8f24467234bea1f34adf5ad5007b</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>C++ method</string>
-// CHECK-NEXT:  <key>issue_context</key><string>method</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>7</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>32</integer>
-// CHECK-NEXT:   <key>col</key><integer>14</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>38</integer>
-// CHECK-NEXT:           <key>col</key><integer>7</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>38</integer>
-// CHECK-NEXT:           <key>col</key><integer>12</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>38</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>38</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>38</integer>
-// CHECK-NEXT:      <key>col</key><integer>14</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>38</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>38</integer>
-// CHECK-NEXT:         <key>col</key><integer>18</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$class AA::X &amp; AA::X::operator=(int)$14$return*this;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$class AA::X &amp; AA::X::operator=(int)$14$return*this;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$class AA::X &amp; AA::X::operator=(int)$14$return*this;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>b47cf7973c9b459d9c99c483e722db8e</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>C++ method</string>
-// CHECK-NEXT:  <key>issue_context</key><string>operator=</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>38</integer>
-// CHECK-NEXT:   <key>col</key><integer>14</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>42</integer>
-// CHECK-NEXT:           <key>col</key><integer>7</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>42</integer>
-// CHECK-NEXT:           <key>col</key><integer>12</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>42</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>42</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>42</integer>
-// CHECK-NEXT:      <key>col</key><integer>14</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>42</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>42</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::operator int()$14$return0;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::operator int()$14$return0;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$AA::X::operator int()$14$return0;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>0cbb0e1e5b03ba5b4f7f8f17504de671</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>42</integer>
-// CHECK-NEXT:   <key>col</key><integer>14</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>46</integer>
-// CHECK-NEXT:           <key>col</key><integer>7</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>46</integer>
-// CHECK-NEXT:           <key>col</key><integer>12</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>46</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>46</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>46</integer>
-// CHECK-NEXT:      <key>col</key><integer>14</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>46</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>46</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::operator float()$14$return0;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$AA::X::operator float()$14$return0;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$AA::X::operator float()$14$return0;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>df306826bf89e50c1b55e1d379a761b3</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>46</integer>
-// CHECK-NEXT:   <key>col</key><integer>14</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>52</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>52</integer>
-// CHECK-NEXT:           <key>col</key><integer>8</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>52</integer>
-// CHECK-NEXT:           <key>col</key><integer>10</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>52</integer>
-// CHECK-NEXT:           <key>col</key><integer>10</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>52</integer>
-// CHECK-NEXT:      <key>col</key><integer>10</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>52</integer>
-// CHECK-NEXT:         <key>col</key><integer>10</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>52</integer>
-// CHECK-NEXT:         <key>col</key><integer>10</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int AA::X::OutOfLine()$10$return5;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$int AA::X::OutOfLine()$10$return5;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$int AA::X::OutOfLine()$10$return5;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>9dd7b17a6f62ed8c95b37a38cf71f3a9</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>C++ method</string>
-// CHECK-NEXT:  <key>issue_context</key><string>OutOfLine</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>52</integer>
-// CHECK-NEXT:   <key>col</key><integer>10</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>56</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>56</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>58</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>6ad4400e40885a78a0f57f585421a515</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>testLambda</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>56</integer>
-// CHECK-NEXT:   <key>col</key><integer>3</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>56</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>56</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>58</integer>
-// CHECK-NEXT:         <key>col</key><integer>5</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$void testLambda()$3$[](){$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>6ad4400e40885a78a0f57f585421a515</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>testLambda</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>56</integer>
-// CHECK-NEXT:   <key>col</key><integer>3</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>56</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>56</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>58</integer>
-// CHECK-NEXT:           <key>col</key><integer>4</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>58</integer>
-// CHECK-NEXT:           <key>col</key><integer>4</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>58</integer>
-// CHECK-NEXT:      <key>col</key><integer>4</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>58</integer>
-// CHECK-NEXT:         <key>col</key><integer>4</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>58</integer>
-// CHECK-NEXT:         <key>col</key><integer>5</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testLambda()$4$}();$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testLambda()$4$}();$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$void testLambda()$4$}();$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>378e6de75fb41b05bcef3950ad5ffa5e</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>testLambda</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>3</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>58</integer>
-// CHECK-NEXT:   <key>col</key><integer>4</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT: </array>
+template <typename T>
+void f(T) {
+  clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void f(T)$27$clang_analyzer_hashDump(5);$Category}}
+}
+
+template <typename T>
+struct TX {
+  void f(T) {
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TX::f(T)$29$clang_analyzer_hashDump(5);$Category}}
+  }
+};
+
+template <>
+void f<long>(long) {
+  clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void f(long)$27$clang_analyzer_hashDump(5);$Category}}
+}
+
+template <>
+struct TX<long> {
+  void f(long) {
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TX<long>::f(long)$29$clang_analyzer_hashDump(5);$Category}}
+  }
+};
+
+template <typename T>
+struct TTX {
+  template<typename S>
+  void f(T, S) {
+    clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$void TTX::f(T, S)$29$clang_analyzer_hashDump(5);$Category}}
+  }
+};
+
+void g() {
+  // TX<int> and TX<double> is instantiated from the same code with the same
+  // source locations. The same error happining in both of the instantiations
+  // should share the common hash. This means we should not include the
+  // template argument for these types in the function signature.
+  // Note that, we still want the hash to be different for explicit
+  // specializations.
+  TX<int> x;
+  TX<double> y;
+  TX<long> xl;
+  x.f(1);
+  xl.f(1);
+  f(5);
+  f(3.0);
+  y.f(2);
+  TTX<int> z;
+  z.f<int>(5, 5);
+  f(5l);
+}
diff --git a/test/Analysis/bug_hash_test.m b/test/Analysis/bug_hash_test.m
index 1e99d3c..fbb70e5 100644
--- a/test/Analysis/bug_hash_test.m
+++ b/test/Analysis/bug_hash_test.m
@@ -1,5 +1,6 @@
-// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,debug.DumpBugHash -analyzer-output=plist %s -o %t.plist
-// RUN: FileCheck --input-file=%t.plist %s
+// RUN: %clang_analyze_cc1 -fblocks -analyzer-checker=core,debug.ExprInspection %s -verify
+
+void clang_analyzer_hashDump(int);
 
 @protocol NSObject
 + (id)alloc;
@@ -15,1178 +16,21 @@
 @end
 
 @implementation NSObject
++ (id)alloc {
+  return 0;
+}
+- (id)init {
+  return self;
+}
 - (void)method:(int)arg param:(int)arg2 {
-  arg = 5;
-  return;
+  clang_analyzer_hashDump(5); // expected-warning {{debug.ExprInspection$NSObject::method:param:$27$clang_analyzer_hashDump(5);$Category}}
 }
 @end
 
 
 void testBlocks() {
   int x = 5;
-  ^{ int y = 1 + x; }();
+  ^{
+    clang_analyzer_hashDump(x); // expected-warning {{debug.ExprInspection$$29$clang_analyzer_hashDump(x);$Category}}
+  }();
 }
-
-// CHECK: <key>diagnostics</key>
-// CHECK-NEXT: <array>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>5</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>7</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>7</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>19</integer>
-// CHECK-NEXT:      <key>col</key><integer>7</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>9</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$NSObject::method:param:$3$arg=5;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$NSObject::method:param:$3$arg=5;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$NSObject::method:param:$3$arg=5;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>f9f569e94382c1f969aabd304581b294</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>Objective-C method</string>
-// CHECK-NEXT:  <key>issue_context</key><string>method:param:</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>19</integer>
-// CHECK-NEXT:   <key>col</key><integer>7</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>5</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>9</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>19</integer>
-// CHECK-NEXT:           <key>col</key><integer>9</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>19</integer>
-// CHECK-NEXT:      <key>col</key><integer>9</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>9</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>19</integer>
-// CHECK-NEXT:         <key>col</key><integer>9</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$NSObject::method:param:$9$arg=5;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$NSObject::method:param:$9$arg=5;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$NSObject::method:param:$9$arg=5;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>ca44d6aa882ee55f76e11a80d5a66372</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>Objective-C method</string>
-// CHECK-NEXT:  <key>issue_context</key><string>method:param:</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>19</integer>
-// CHECK-NEXT:   <key>col</key><integer>9</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>26</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>26</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>26</integer>
-// CHECK-NEXT:         <key>col</key><integer>7</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testBlocks()$3$intx=5;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testBlocks()$3$intx=5;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$void testBlocks()$3$intx=5;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>84ec7c854c1c7849abfa03f7f20b4f06</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>testBlocks</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>26</integer>
-// CHECK-NEXT:   <key>col</key><integer>3</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>5</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>11</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>11</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>26</integer>
-// CHECK-NEXT:      <key>col</key><integer>11</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>26</integer>
-// CHECK-NEXT:         <key>col</key><integer>11</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>26</integer>
-// CHECK-NEXT:         <key>col</key><integer>11</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testBlocks()$11$intx=5;$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testBlocks()$11$intx=5;$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$void testBlocks()$11$intx=5;$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>f91db2d7b129ed60e7c9caf6f8a84d5c</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>testBlocks</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>26</integer>
-// CHECK-NEXT:   <key>col</key><integer>11</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>5</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>21</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>0f1e9483a8ff59e787eaac18b68068ad</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>testBlocks</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>2</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>27</integer>
-// CHECK-NEXT:   <key>col</key><integer>3</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>5</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>23</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$void testBlocks()$3$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>0f1e9483a8ff59e787eaac18b68068ad</string>
-// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
-// CHECK-NEXT:  <key>issue_context</key><string>testBlocks</string>
-// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>2</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>27</integer>
-// CHECK-NEXT:   <key>col</key><integer>3</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>5</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>23</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>Calling anonymous block</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>Calling anonymous block</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>depth</key><integer>1</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>6</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>8</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>6</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>6</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>10</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>1</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$$6$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$$6$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$$6$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>8a8e42efc427e1334b77d510d3fb6361</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>27</integer>
-// CHECK-NEXT:   <key>col</key><integer>6</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>5</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>23</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>Calling anonymous block</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>Calling anonymous block</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>depth</key><integer>1</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>6</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>8</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>6</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>8</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>14</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>14</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>1</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>6d6028808f1d47ec5b74a417e96c2a02</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>27</integer>
-// CHECK-NEXT:   <key>col</key><integer>14</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>5</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>23</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>Calling anonymous block</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>Calling anonymous block</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>depth</key><integer>1</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>16</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>16</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>16</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>14</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>18</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>1</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$$14$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>162138b23629276baad7dd3e8051fd6f</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>27</integer>
-// CHECK-NEXT:   <key>col</key><integer>16</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>path</key>
-// CHECK-NEXT:   <array>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>26</integer>
-// CHECK-NEXT:           <key>col</key><integer>5</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>3</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>23</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>0</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>Calling anonymous block</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>Calling anonymous block</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>3</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>depth</key><integer>1</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>Entered call from &apos;testBlocks&apos;</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>3</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>6</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>8</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>control</string>
-// CHECK-NEXT:     <key>edges</key>
-// CHECK-NEXT:      <array>
-// CHECK-NEXT:       <dict>
-// CHECK-NEXT:        <key>start</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>6</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>8</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:        <key>end</key>
-// CHECK-NEXT:         <array>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>18</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>27</integer>
-// CHECK-NEXT:           <key>col</key><integer>18</integer>
-// CHECK-NEXT:           <key>file</key><integer>0</integer>
-// CHECK-NEXT:          </dict>
-// CHECK-NEXT:         </array>
-// CHECK-NEXT:       </dict>
-// CHECK-NEXT:      </array>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:    <dict>
-// CHECK-NEXT:     <key>kind</key><string>event</string>
-// CHECK-NEXT:     <key>location</key>
-// CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>27</integer>
-// CHECK-NEXT:      <key>col</key><integer>18</integer>
-// CHECK-NEXT:      <key>file</key><integer>0</integer>
-// CHECK-NEXT:     </dict>
-// CHECK-NEXT:     <key>ranges</key>
-// CHECK-NEXT:     <array>
-// CHECK-NEXT:       <array>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>18</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>27</integer>
-// CHECK-NEXT:         <key>col</key><integer>18</integer>
-// CHECK-NEXT:         <key>file</key><integer>0</integer>
-// CHECK-NEXT:        </dict>
-// CHECK-NEXT:       </array>
-// CHECK-NEXT:     </array>
-// CHECK-NEXT:     <key>depth</key><integer>1</integer>
-// CHECK-NEXT:     <key>extended_message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$$18$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:     <key>message</key>
-// CHECK-NEXT:     <string>debug.DumpBugHash$$18$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:    </dict>
-// CHECK-NEXT:   </array>
-// CHECK-NEXT:   <key>description</key><string>debug.DumpBugHash$$18$^{inty=1+x;}();$debug</string>
-// CHECK-NEXT:   <key>category</key><string>debug</string>
-// CHECK-NEXT:   <key>type</key><string>Dump hash components</string>
-// CHECK-NEXT:   <key>check_name</key><string>debug.DumpBugHash</string>
-// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>b3add78bcab0ebc3da3b640081057525</string>
-// CHECK-NEXT:  <key>location</key>
-// CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>27</integer>
-// CHECK-NEXT:   <key>col</key><integer>18</integer>
-// CHECK-NEXT:   <key>file</key><integer>0</integer>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT:  </dict>
-// CHECK-NEXT: </array>
diff --git a/test/Analysis/call_once.cpp b/test/Analysis/call_once.cpp
new file mode 100644
index 0000000..db9e5cc
--- /dev/null
+++ b/test/Analysis/call_once.cpp
@@ -0,0 +1,361 @@
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBSTDCPP -verify %s
+
+// We do NOT model libcxx03 implementation, but the analyzer should still
+// not crash.
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -DEMULATE_LIBSTDCPP -verify %s
+
+void clang_analyzer_eval(bool);
+
+// Faking std::std::call_once implementation.
+namespace std {
+
+#ifndef EMULATE_LIBSTDCPP
+typedef struct once_flag_s {
+  unsigned long __state_ = 0;
+} once_flag;
+#else
+typedef struct once_flag_s {
+  int _M_once = 0;
+} once_flag;
+#endif
+
+#ifndef EMULATE_LIBCXX03
+template <class Callable, class... Args>
+void call_once(once_flag &o, Callable&& func, Args&&... args) {};
+#else
+template <class Callable, class... Args> // libcxx03 call_once
+void call_once(once_flag &o, Callable func, Args&&... args) {};
+#endif
+
+} // namespace std
+
+// Check with Lambdas.
+void test_called_warning() {
+  std::once_flag g_initialize;
+  int z;
+
+  std::call_once(g_initialize, [&] {
+    int *x = nullptr;
+#ifndef EMULATE_LIBCXX03
+    int y = *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
+#endif
+    z = 200;
+  });
+}
+
+void test_called_on_path_inside_no_warning() {
+  std::once_flag g_initialize;
+
+  int *x = nullptr;
+  int y = 100;
+  int z;
+
+  std::call_once(g_initialize, [&] {
+    z = 200;
+    x = &z;
+  });
+
+#ifndef EMULATE_LIBCXX03
+  *x = 100; // no-warning
+  clang_analyzer_eval(z == 100); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_called_on_path_no_warning() {
+  std::once_flag g_initialize;
+
+  int *x = nullptr;
+  int y = 100;
+
+  std::call_once(g_initialize, [&] {
+    x = &y;
+  });
+
+#ifndef EMULATE_LIBCXX03
+  *x = 100; // no-warning
+#else
+  *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
+#endif
+}
+
+void test_called_on_path_warning() {
+  std::once_flag g_initialize;
+
+  int y = 100;
+  int *x = &y;
+
+  std::call_once(g_initialize, [&] {
+    x = nullptr;
+  });
+
+#ifndef EMULATE_LIBCXX03
+  *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
+#endif
+}
+
+void test_called_once_warning() {
+  std::once_flag g_initialize;
+
+  int *x = nullptr;
+  int y = 100;
+
+  std::call_once(g_initialize, [&] {
+    x = nullptr;
+  });
+
+  std::call_once(g_initialize, [&] {
+    x = &y;
+  });
+
+#ifndef EMULATE_LIBCXX03
+  *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
+#endif
+}
+
+void test_called_once_no_warning() {
+  std::once_flag g_initialize;
+
+  int *x = nullptr;
+  int y = 100;
+
+  std::call_once(g_initialize, [&] {
+    x = &y;
+  });
+
+  std::call_once(g_initialize, [&] {
+    x = nullptr;
+  });
+
+#ifndef EMULATE_LIBCXX03
+  *x = 100; // no-warning
+#endif
+}
+
+static int global = 0;
+void funcPointer() {
+  global = 1;
+}
+
+void test_func_pointers() {
+  static std::once_flag flag;
+  std::call_once(flag, &funcPointer);
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(global == 1); // expected-warning{{TRUE}}
+#endif
+}
+
+template <class _Fp>
+class function; // undefined
+template <class _Rp, class... _ArgTypes>
+struct function<_Rp(_ArgTypes...)> {
+  _Rp operator()(_ArgTypes...) const {};
+  template <class _Fp>
+  function(_Fp) {};
+};
+
+// Note: currently we do not support calls to std::function,
+// but the analyzer should not crash either.
+void test_function_objects_warning() {
+  int x = 0;
+  int *y = &x;
+
+  std::once_flag flag;
+
+  function<void()> func = [&]() {
+    y = nullptr;
+  };
+
+  std::call_once(flag, func);
+
+  func();
+  int z = *y;
+}
+
+void test_param_passing_lambda() {
+  std::once_flag flag;
+  int x = 120;
+  int y = 0;
+
+  std::call_once(flag, [&](int p) {
+    y = p;
+  },
+                 x);
+
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_param_passing_lambda_false() {
+  std::once_flag flag;
+  int x = 120;
+
+  std::call_once(flag, [&](int p) {
+    x = 0;
+  },
+                 x);
+
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}
+#endif
+}
+
+void test_param_passing_stored_lambda() {
+  std::once_flag flag;
+  int x = 120;
+  int y = 0;
+
+  auto lambda = [&](int p) {
+    y = p;
+  };
+
+  std::call_once(flag, lambda, x);
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_multiparam_passing_lambda() {
+  std::once_flag flag;
+  int x = 120;
+
+  std::call_once(flag, [&](int a, int b, int c) {
+    x = a + b + c;
+  },
+                 1, 2, 3);
+
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}
+  clang_analyzer_eval(x == 6); // expected-warning{{TRUE}}
+#endif
+}
+
+static int global2 = 0;
+void test_param_passing_lambda_global() {
+  std::once_flag flag;
+  global2 = 0;
+  std::call_once(flag, [&](int a, int b, int c) {
+    global2 = a + b + c;
+  },
+                 1, 2, 3);
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(global2 == 6); // expected-warning{{TRUE}}
+#endif
+}
+
+static int global3 = 0;
+void funcptr(int a, int b, int c) {
+  global3 = a + b + c;
+}
+
+void test_param_passing_funcptr() {
+  std::once_flag flag;
+  global3 = 0;
+
+  std::call_once(flag, &funcptr, 1, 2, 3);
+
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(global3 == 6); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_blocks() {
+  global3 = 0;
+  std::once_flag flag;
+  std::call_once(flag, ^{
+    global3 = 120;
+  });
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(global3 == 120); // expected-warning{{TRUE}}
+#endif
+}
+
+int call_once() {
+  return 5;
+}
+
+void test_non_std_call_once() {
+  int x = call_once();
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(x == 5); // expected-warning{{TRUE}}
+#endif
+}
+
+namespace std {
+template <typename d, typename e>
+void call_once(d, e);
+}
+void g();
+void test_no_segfault_on_different_impl() {
+#ifndef EMULATE_LIBCXX03
+  std::call_once(g, false); // no-warning
+#endif
+}
+
+void test_lambda_refcapture() {
+  static std::once_flag flag;
+  int a = 6;
+  std::call_once(flag, [&](int &a) { a = 42; }, a);
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_lambda_refcapture2() {
+  static std::once_flag flag;
+  int a = 6;
+  std::call_once(flag, [=](int &a) { a = 42; }, a);
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
+#endif
+}
+
+void test_lambda_fail_refcapture() {
+  static std::once_flag flag;
+  int a = 6;
+  std::call_once(flag, [=](int a) { a = 42; }, a);
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(a == 42); // expected-warning{{FALSE}}
+#endif
+}
+
+void mutator(int &param) {
+  param = 42;
+}
+void test_reftypes_funcptr() {
+  static std::once_flag flag;
+  int a = 6;
+  std::call_once(flag, &mutator, a);
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
+#endif
+}
+
+void fail_mutator(int param) {
+  param = 42;
+}
+void test_mutator_noref() {
+  static std::once_flag flag;
+  int a = 6;
+  std::call_once(flag, &fail_mutator, a);
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(a == 42); // expected-warning{{FALSE}}
+#endif
+}
+
+// Function is implicitly treated as a function pointer
+// even when an ampersand is not explicitly set.
+void callbackn(int &param) {
+  param = 42;
+}
+void test_implicit_funcptr() {
+  int x = 0;
+  static std::once_flag flagn;
+
+  std::call_once(flagn, callbackn, x);
+#ifndef EMULATE_LIBCXX03
+  clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
+#endif
+}
diff --git a/test/Analysis/casts.c b/test/Analysis/casts.c
index 3ba12e4..24bba8a 100644
--- a/test/Analysis/casts.c
+++ b/test/Analysis/casts.c
@@ -123,3 +123,29 @@
   int x = (int) p;
   clang_analyzer_eval(++x < 10); // no-crash // expected-warning{{UNKNOWN}}
 }
+
+void multiDimensionalArrayPointerCasts() {
+  static int x[10][10];
+  int *y1 = &(x[3][5]);
+  char *z = ((char *) y1) + 2;
+  int *y2 = (int *)(z - 2);
+  int *y3 = ((int *)x) + 35; // This is offset for [3][5].
+
+  clang_analyzer_eval(y1 == y2); // expected-warning{{TRUE}}
+
+  // FIXME: should be FALSE (i.e. equal pointers).
+  clang_analyzer_eval(y1 - y2); // expected-warning{{UNKNOWN}}
+  // FIXME: should be TRUE (i.e. same symbol).
+  clang_analyzer_eval(*y1 == *y2); // expected-warning{{UNKNOWN}}
+
+  clang_analyzer_eval(*((char *)y1) == *((char *) y2)); // expected-warning{{TRUE}}
+
+  clang_analyzer_eval(y1 == y3); // expected-warning{{TRUE}}
+
+  // FIXME: should be FALSE (i.e. equal pointers).
+  clang_analyzer_eval(y1 - y3); // expected-warning{{UNKNOWN}}
+  // FIXME: should be TRUE (i.e. same symbol).
+  clang_analyzer_eval(*y1 == *y3); // expected-warning{{UNKNOWN}}
+
+  clang_analyzer_eval(*((char *)y1) == *((char *) y3)); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/compound-literals.c b/test/Analysis/compound-literals.c
new file mode 100644
index 0000000..a2556d2
--- /dev/null
+++ b/test/Analysis/compound-literals.c
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -triple=i386-apple-darwin10 -analyze -analyzer-checker=debug.ExprInspection -verify %s
+void clang_analyzer_eval(int);
+
+// pr28449: Used to crash.
+void foo(void) {
+  static const unsigned short array[] = (const unsigned short[]){0x0F00};
+  // FIXME: Should be true.
+  clang_analyzer_eval(array[0] == 0x0F00); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/constant-folding.c b/test/Analysis/constant-folding.c
index a6d2b74..8189868 100644
--- a/test/Analysis/constant-folding.c
+++ b/test/Analysis/constant-folding.c
@@ -76,3 +76,42 @@
   clang_analyzer_eval(b >= a); // expected-warning{{TRUE}}
   clang_analyzer_eval(a != b); // expected-warning{{TRUE}}
 }
+
+void testBitwiseRules(unsigned int a, int b) {
+  clang_analyzer_eval((a | 1) >= 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a | -1) >= -1); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a | 2) >= 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a | 5) >= 5); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a | 10) >= 10); // expected-warning{{TRUE}}
+
+  // Argument order should not influence this
+  clang_analyzer_eval((1 | a) >= 1); // expected-warning{{TRUE}}
+
+  clang_analyzer_eval((a & 1) <= 1); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a & 2) <= 2); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a & 5) <= 5); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a & 10) <= 10); // expected-warning{{TRUE}}
+  clang_analyzer_eval((a & -10) <= 10); // expected-warning{{UNKNOWN}}
+
+  // Again, check for different argument order.
+  clang_analyzer_eval((1 & a) <= 1); // expected-warning{{TRUE}}
+
+  unsigned int c = a;
+  c |= 1;
+  clang_analyzer_eval((c | 0) == 0); // expected-warning{{FALSE}}
+
+  // Rules don't apply to signed typed, as the values might be negative.
+  clang_analyzer_eval((b | 1) > 0); // expected-warning{{UNKNOWN}}
+
+  // Even for signed values, bitwise OR with a non-zero is always non-zero.
+  clang_analyzer_eval((b | 1) == 0); // expected-warning{{FALSE}}
+  clang_analyzer_eval((b | -2) == 0); // expected-warning{{FALSE}}
+  clang_analyzer_eval((b | 10) == 0); // expected-warning{{FALSE}}
+  clang_analyzer_eval((b | 0) == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval((b | -2) >= 0); // expected-warning{{UNKNOWN}}
+
+  // Check that dynamically computed constants also work.
+  int constant = 1 << 3;
+  unsigned int d = a | constant;
+  clang_analyzer_eval(constant > 0); // expected-warning{{TRUE}}
+}
diff --git a/test/Analysis/copypaste/asm.cpp b/test/Analysis/copypaste/asm.cpp
index 2e3613d..1d93469 100644
--- a/test/Analysis/copypaste/asm.cpp
+++ b/test/Analysis/copypaste/asm.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-linux -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/attributes.cpp b/test/Analysis/copypaste/attributes.cpp
index 083be74..f715451 100644
--- a/test/Analysis/copypaste/attributes.cpp
+++ b/test/Analysis/copypaste/attributes.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/autogenerated_automoc.cpp b/test/Analysis/copypaste/autogenerated_automoc.cpp
index 55963c4..0f7f9c9 100644
--- a/test/Analysis/copypaste/autogenerated_automoc.cpp
+++ b/test/Analysis/copypaste/autogenerated_automoc.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|.*_automoc.cpp" -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|.*_automoc.cpp" -verify %s
 
 // Because files that have `_automoc.' in their names are most likely autogenerated,
 // we suppress copy-paste warnings here.
diff --git a/test/Analysis/copypaste/blocks.cpp b/test/Analysis/copypaste/blocks.cpp
index 10467b7..2382156 100644
--- a/test/Analysis/copypaste/blocks.cpp
+++ b/test/Analysis/copypaste/blocks.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -fblocks -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fblocks -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // This tests if we search for clones in blocks.
 
diff --git a/test/Analysis/copypaste/call.cpp b/test/Analysis/copypaste/call.cpp
index 046229a..c5ddae5 100644
--- a/test/Analysis/copypaste/call.cpp
+++ b/test/Analysis/copypaste/call.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/catch.cpp b/test/Analysis/copypaste/catch.cpp
index cf3e807..edcf44a 100644
--- a/test/Analysis/copypaste/catch.cpp
+++ b/test/Analysis/copypaste/catch.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/delete.cpp b/test/Analysis/copypaste/delete.cpp
index 394226b..4edb460 100644
--- a/test/Analysis/copypaste/delete.cpp
+++ b/test/Analysis/copypaste/delete.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/dependent-exist.cpp b/test/Analysis/copypaste/dependent-exist.cpp
index 9046353..28f2ceb 100644
--- a/test/Analysis/copypaste/dependent-exist.cpp
+++ b/test/Analysis/copypaste/dependent-exist.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -fms-extensions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fms-extensions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/expr-types.cpp b/test/Analysis/copypaste/expr-types.cpp
index 601f0b1..6062be3 100644
--- a/test/Analysis/copypaste/expr-types.cpp
+++ b/test/Analysis/copypaste/expr-types.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/fold.cpp b/test/Analysis/copypaste/fold.cpp
index 0aed11b..fadcb49 100644
--- a/test/Analysis/copypaste/fold.cpp
+++ b/test/Analysis/copypaste/fold.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/function-try-block.cpp b/test/Analysis/copypaste/function-try-block.cpp
index d777145..d0fbc50 100644
--- a/test/Analysis/copypaste/function-try-block.cpp
+++ b/test/Analysis/copypaste/function-try-block.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -fcxx-exceptions -std=c++1z -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // Tests if function try blocks are correctly handled.
 
diff --git a/test/Analysis/copypaste/functions.cpp b/test/Analysis/copypaste/functions.cpp
index d2c607b..2bfe591 100644
--- a/test/Analysis/copypaste/functions.cpp
+++ b/test/Analysis/copypaste/functions.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // This tests if we search for clones in functions.
 
diff --git a/test/Analysis/copypaste/generic.c b/test/Analysis/copypaste/generic.c
index d4d4564..2fa6c30 100644
--- a/test/Analysis/copypaste/generic.c
+++ b/test/Analysis/copypaste/generic.c
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/labels.cpp b/test/Analysis/copypaste/labels.cpp
index eff3330..18c5b22 100644
--- a/test/Analysis/copypaste/labels.cpp
+++ b/test/Analysis/copypaste/labels.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=gnu++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=gnu++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/lambda.cpp b/test/Analysis/copypaste/lambda.cpp
index 17c8748..456d83a 100644
--- a/test/Analysis/copypaste/lambda.cpp
+++ b/test/Analysis/copypaste/lambda.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // expected-no-diagnostics
 
diff --git a/test/Analysis/copypaste/macros.cpp b/test/Analysis/copypaste/macros.cpp
index bdacd48..ea05bbd 100644
--- a/test/Analysis/copypaste/macros.cpp
+++ b/test/Analysis/copypaste/macros.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // Tests that macros and non-macro clones aren't mixed into the same hash
 // group. This is currently necessary as all clones in a hash group need
diff --git a/test/Analysis/copypaste/not-autogenerated.cpp b/test/Analysis/copypaste/not-autogenerated.cpp
index 765e7aa..d54ee17 100644
--- a/test/Analysis/copypaste/not-autogenerated.cpp
+++ b/test/Analysis/copypaste/not-autogenerated.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|ui_|dbus_|.*_automoc" -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -analyzer-config alpha.clone.CloneChecker:IgnoredFilesPattern="moc_|ui_|dbus_|.*_automoc" -verify %s
 
 void f1() {
   int *p1 = new int[1];
diff --git a/test/Analysis/copypaste/objc-methods.m b/test/Analysis/copypaste/objc-methods.m
index e63c7f6..0a84370 100644
--- a/test/Analysis/copypaste/objc-methods.m
+++ b/test/Analysis/copypaste/objc-methods.m
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -Wno-objc-root-class -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -Wno-objc-root-class -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // This tests if we search for clones in Objective-C methods.
 
diff --git a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
index 7c4f355..d4402a9 100644
--- a/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics-notes-as-events.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-output=plist -analyzer-config notes-as-events=true -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=plist -analyzer-config notes-as-events=true -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 void log();
diff --git a/test/Analysis/copypaste/plist-diagnostics.cpp b/test/Analysis/copypaste/plist-diagnostics.cpp
index e2fa759..c138c6f 100644
--- a/test/Analysis/copypaste/plist-diagnostics.cpp
+++ b/test/Analysis/copypaste/plist-diagnostics.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=plist -o %t.plist -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 // RUN: FileCheck --input-file=%t.plist %s
 
 void log();
diff --git a/test/Analysis/copypaste/sub-sequences.cpp b/test/Analysis/copypaste/sub-sequences.cpp
index 798662d..d2c0835 100644
--- a/test/Analysis/copypaste/sub-sequences.cpp
+++ b/test/Analysis/copypaste/sub-sequences.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // This tests if sub-sequences can match with normal sequences.
 
diff --git a/test/Analysis/copypaste/suspicious-clones.cpp b/test/Analysis/copypaste/suspicious-clones.cpp
index 3a760e2..ae29b0e 100644
--- a/test/Analysis/copypaste/suspicious-clones.cpp
+++ b/test/Analysis/copypaste/suspicious-clones.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true  -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:ReportSuspiciousClones=true  -analyzer-config alpha.clone.CloneChecker:ReportNormalClones=false -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 // Tests finding a suspicious clone that references local variables.
 
diff --git a/test/Analysis/copypaste/text-diagnostics.cpp b/test/Analysis/copypaste/text-diagnostics.cpp
index a6e358c..a3132e9 100644
--- a/test/Analysis/copypaste/text-diagnostics.cpp
+++ b/test/Analysis/copypaste/text-diagnostics.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_analyze_cc1 -analyzer-output=text -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-output=text -std=c++11 -analyzer-checker=alpha.clone.CloneChecker -analyzer-config alpha.clone.CloneChecker:MinimumCloneComplexity=10 -verify %s
 
 void log();
 
diff --git a/test/Analysis/ctor.mm b/test/Analysis/ctor.mm
index 619e2cb..e903263 100644
--- a/test/Analysis/ctor.mm
+++ b/test/Analysis/ctor.mm
@@ -199,7 +199,7 @@
     Inner p;
   };
 
-  void testPOD() {
+  void testPOD(const POD &pp) {
     POD p;
     p.x = 1;
     POD p2 = p; // no-warning
@@ -210,6 +210,15 @@
     // Use rvalues as well.
     clang_analyzer_eval(POD(p3).x == 1); // expected-warning{{TRUE}}
 
+    // Copy from symbolic references correctly.
+    POD p4 = pp;
+    // Make sure that p4.x contains a symbol after copy.
+    if (p4.x > 0)
+      clang_analyzer_eval(p4.x > 0); // expected-warning{{TRUE}}
+    // FIXME: Element region gets in the way, so these aren't the same symbols
+    // as they should be.
+    clang_analyzer_eval(pp.x == p4.x); // expected-warning{{UNKNOWN}}
+
     PODWrapper w;
     w.p.y = 1;
     PODWrapper w2 = w; // no-warning
diff --git a/test/Analysis/diagnostics/diag-cross-file-boundaries.c b/test/Analysis/diagnostics/diag-cross-file-boundaries.c
deleted file mode 100644
index b975af3..0000000
--- a/test/Analysis/diagnostics/diag-cross-file-boundaries.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html -o PR12421.html %s 2>&1 | FileCheck %s
-
-// Test for PR12421
-#include "diag-cross-file-boundaries.h"
-
-int main(){
-  f();
-  return 0;
-}
-
-// CHECK: warning: Path diagnostic report is not generated.
diff --git a/test/Analysis/edges-new.mm b/test/Analysis/edges-new.mm
index 47a125a..f310f1b 100644
--- a/test/Analysis/edges-new.mm
+++ b/test/Analysis/edges-new.mm
@@ -20288,7 +20288,7 @@
 // CHECK-NEXT:    <key>type</key><string>Bad deallocator</string>
 // CHECK-NEXT:    <key>check_name</key><string>unix.MismatchedDeallocator</string>
 // CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
-// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>d9dbbf68db41ab74e2158f4b131abe34</string>
+// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>046c88d1c91ff46d6506dff5ff880756</string>
 // CHECK-NEXT:   <key>issue_hash_function_offset</key><string>0</string>
 // CHECK-NEXT:   <key>location</key>
 // CHECK-NEXT:   <dict>
diff --git a/test/Analysis/exercise-ps.c b/test/Analysis/exercise-ps.c
index 577b88b..c459260 100644
--- a/test/Analysis/exercise-ps.c
+++ b/test/Analysis/exercise-ps.c
@@ -21,3 +21,11 @@
   memcpy((&x[1]), (buf), 1); // expected-warning{{implicitly declaring library function 'memcpy' with type 'void *(void *, const void *}} \
   // expected-note{{include the header <string.h> or explicitly provide a declaration for 'memcpy'}}
 }
+
+// AllocaRegion is untyped. Void pointer isn't of much help either. Before
+// realizing that the value is undefined, we need to somehow figure out
+// what type of value do we expect.
+void f3(void *dest) {
+  void *src = __builtin_alloca(5);
+  memcpy(dest, src, 1); // expected-warning{{2nd function call argument is a pointer to uninitialized value}}
+}
diff --git a/test/Analysis/expr-inspection.c b/test/Analysis/expr-inspection.c
index 59406cd..ec0e682 100644
--- a/test/Analysis/expr-inspection.c
+++ b/test/Analysis/expr-inspection.c
@@ -8,6 +8,7 @@
 
 void foo(int x) {
   clang_analyzer_dump(x); // expected-warning{{reg_$0<int x>}}
+  clang_analyzer_dump(x + (-1)); // expected-warning{{(reg_$0<int x>) + -1}}
   int y = 1;
   clang_analyzer_printState();
   for (; y < 3; ++y)
diff --git a/test/Analysis/gtest.cpp b/test/Analysis/gtest.cpp
index 5797a77..98f415e 100644
--- a/test/Analysis/gtest.cpp
+++ b/test/Analysis/gtest.cpp
@@ -151,3 +151,17 @@
   ASSERT_TRUE(false);
   clang_analyzer_warnIfReached(); // no-warning
 }
+
+void testAssertSymbolicPtr(const bool *b) {
+  ASSERT_TRUE(*b); // no-crash
+
+  // FIXME: Our solver doesn't handle this well yet.
+  clang_analyzer_eval(*b); // expected-warning{{UNKNOWN}}
+}
+
+void testAssertSymbolicRef(const bool &b) {
+  ASSERT_TRUE(b); // no-crash
+
+  // FIXME: Our solver doesn't handle this well yet.
+  clang_analyzer_eval(b); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/html-diag-singlefile.c b/test/Analysis/html-diag-singlefile.c
new file mode 100644
index 0000000..fc0dcc7
--- /dev/null
+++ b/test/Analysis/html-diag-singlefile.c
@@ -0,0 +1,14 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=html-single-file -o D30406.html %s 2>&1 | FileCheck %s
+
+// Check that single file HTML output does not process multi-file diagnostics.
+// (This used to test for PR12421, before the introduction of the html-single-file format)
+
+#include "html-diag-singlefile.h"
+
+int main(){
+  f();
+  return 0;
+}
+
+// CHECK: warning: Path diagnostic report is not generated.
diff --git a/test/Analysis/diagnostics/diag-cross-file-boundaries.h b/test/Analysis/html-diag-singlefile.h
similarity index 100%
rename from test/Analysis/diagnostics/diag-cross-file-boundaries.h
rename to test/Analysis/html-diag-singlefile.h
diff --git a/test/Analysis/html-diags-analyze-headers.c b/test/Analysis/html-diags-analyze-headers.c
new file mode 100644
index 0000000..fa5f21d
--- /dev/null
+++ b/test/Analysis/html-diags-analyze-headers.c
@@ -0,0 +1,10 @@
+// RUN: mkdir -p %t.dir
+// RUN: %clang_analyze_cc1 -analyzer-opt-analyze-headers -analyzer-output=html -analyzer-checker=core -o %t.dir %s
+// RUN: ls %t.dir | grep report
+// RUN: rm -rf %t.dir
+
+// This tests that we emit HTML diagnostics for reports in headers when the
+// analyzer is run with -analyzer-opt-analyze-headers. This was handled
+// incorrectly in the first iteration of D30406.
+
+#include "html-diags-analyze-headers.h"
diff --git a/test/Analysis/html-diags-analyze-headers.h b/test/Analysis/html-diags-analyze-headers.h
new file mode 100644
index 0000000..3641ca9
--- /dev/null
+++ b/test/Analysis/html-diags-analyze-headers.h
@@ -0,0 +1,5 @@
+#include "html-diags-multifile.h"
+
+void test_call_macro() {
+  has_bug(0);
+}
diff --git a/test/Analysis/html-diags-multifile.c b/test/Analysis/html-diags-multifile.c
index ce1f72b..ff7b625 100644
--- a/test/Analysis/html-diags-multifile.c
+++ b/test/Analysis/html-diags-multifile.c
@@ -1,10 +1,9 @@
 // RUN: mkdir -p %t.dir
 // RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o %t.dir %s
-// RUN: ls %t.dir | not grep report
+// RUN: ls %t.dir | grep report
 // RUN: rm -fR %t.dir
 
-// This tests that we do not currently emit HTML diagnostics for reports that
-// cross file boundaries.
+// This tests that we emit HTML diagnostics for reports that cross file boundaries.
 
 #include "html-diags-multifile.h"
 
diff --git a/test/Analysis/html-diags.c b/test/Analysis/html-diags.c
index 182bcfb..dd185b5 100644
--- a/test/Analysis/html-diags.c
+++ b/test/Analysis/html-diags.c
@@ -3,6 +3,12 @@
 // RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o %T/dir %s
 // RUN: ls %T/dir | grep report
 
+// D30406: Test new html-single-file output
+// RUN: rm -fR %T/dir
+// RUN: mkdir %T/dir
+// RUN: %clang_analyze_cc1 -analyzer-output=html-single-file -analyzer-checker=core -o %T/dir %s
+// RUN: ls %T/dir | grep report
+
 // PR16547: Test relative paths
 // RUN: cd %T/dir
 // RUN: %clang_analyze_cc1 -analyzer-output=html -analyzer-checker=core -o testrelative %s
diff --git a/test/Analysis/initializer.cpp b/test/Analysis/initializer.cpp
index c736356..e9658a0 100644
--- a/test/Analysis/initializer.cpp
+++ b/test/Analysis/initializer.cpp
@@ -1,7 +1,9 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-inlining=constructors -std=c++11 -verify %s
 
 void clang_analyzer_eval(bool);
 
+#include "Inputs/system-header-simulator-cxx.h"
+
 class A {
   int x;
 public:
@@ -204,3 +206,17 @@
    const char(&f)[2];
 };
 }
+
+namespace CXX_initializer_lists {
+struct C {
+  C(std::initializer_list<int *> list);
+};
+void foo() {
+  C empty{}; // no-crash
+
+  // Do not warn that 'x' leaks. It might have been deleted by
+  // the destructor of 'c'.
+  int *x = new int;
+  C c{x}; // no-warning
+}
+}
diff --git a/test/Analysis/inlining/inline-defensive-checks.c b/test/Analysis/inlining/inline-defensive-checks.c
index 010d3a7..9f211b5 100644
--- a/test/Analysis/inlining/inline-defensive-checks.c
+++ b/test/Analysis/inlining/inline-defensive-checks.c
@@ -169,6 +169,18 @@
   *x = 7; // no-warning
 }
 
+void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignment(struct S *s) {
+  idc(s);
+  int *x = &*&(s->f1);
+  *x = 7; // no-warning
+}
+
+void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S *s) {
+  idc(s);
+  int *x = &*&((++s)->f1);
+  *x = 7; // no-warning
+}
+
 
 struct S2 {
   int a[1];
diff --git a/test/Analysis/loop-unrolling.cpp b/test/Analysis/loop-unrolling.cpp
new file mode 100644
index 0000000..844d1f1
--- /dev/null
+++ b/test/Analysis/loop-unrolling.cpp
@@ -0,0 +1,381 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config unroll-loops=true,cfg-loopexit=true -verify -std=c++11 %s
+
+void clang_analyzer_numTimesReached();
+void clang_analyzer_warnIfReached();
+
+int getNum();
+void foo(int &);
+
+int simple_unroll1() {
+  int a[9];
+  int k = 42;
+  for (int i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{9}}
+    a[i] = 42;
+  }
+  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+  return 0;
+}
+
+int simple_unroll2() {
+  int a[9];
+  int k = 42;
+  int i;
+  for (i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{9}}
+    a[i] = 42;
+  }
+
+  for (int j = 0; j <= 9; ++j) {
+    clang_analyzer_numTimesReached(); // expected-warning {{10}}
+    a[j] = 42;
+  }
+
+  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+  return 0;
+}
+
+int simple_no_unroll1() {
+  int a[9];
+  int k = 42;
+  for (int i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    a[i] = 42;
+    foo(i);
+  }
+  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+  return 0;
+}
+
+int simple_no_unroll2() {
+  int a[9];
+  int k = 42;
+  int i;
+  for (i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    a[i] = 42;
+    i += getNum();
+  }
+  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+  return 0;
+}
+
+int simple_no_unroll3() {
+  int a[9];
+  int k = 42;
+  for (int i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    a[i] = 42;
+    (void)&i;
+  }
+  int b = 22 / (k - 42); // no-warning
+  return 0;
+}
+
+int simple_no_unroll4() {
+  int a[9];
+  int k = 42;
+  int i;
+  for (i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    a[i] = 42;
+    int &j = i;
+  }
+  int b = 22 / (k - 42); // no-warning
+  return 0;
+}
+
+int simple_no_unroll5() {
+  int a[9];
+  int k = 42;
+  int i;
+  for (i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    a[i] = 42;
+    int &j{i};
+  }
+  int b = 22 / (k - 42); // no-warning
+  return 0;
+}
+
+int make_new_branches_loop_cached() {
+  for (int i = 0; i < 8; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    if(getNum()){
+        (void) i; // Since this Stmt does not change the State the analyzer
+                  // won't make a new execution path but reuse the earlier nodes.
+      }
+  }
+  clang_analyzer_warnIfReached(); // no-warning
+  return 0;
+}
+
+int make_new_branches_loop_uncached() {
+  int l = 2;
+  for (int i = 0; i < 8; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{10}}
+    if(getNum()){
+      ++l;
+    }
+  }
+  clang_analyzer_warnIfReached(); // no-warning
+  return 0;
+}
+
+int make_new_branches_loop_uncached2() {
+  int l = 2;
+  for (int i = 0; i < 8; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{10}}
+    if(getNum()){
+      ++l;
+    }
+    (void)&i; // This ensures that the loop won't be unrolled.
+  }
+  clang_analyzer_warnIfReached(); // no-warning
+  return 0;
+}
+
+
+int escape_before_loop_no_unroll1() {
+  int a[9];
+  int k = 42;
+  int i;
+  int &j = i;
+  for (i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    a[i] = 42;
+  }
+  int b = 22 / (k - 42); // no-warning
+  return 0;
+}
+
+int escape_before_loop_no_unroll2() {
+  int a[9];
+  int k = 42;
+  int i;
+  int *p = &i;
+  for (i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    a[i] = 42;
+  }
+  int b = 22 / (k - 42); // no-warning
+  return 0;
+}
+
+int escape_before_loop_no_unroll3() {
+  int a[9];
+  int k = 42;
+  int i;
+  foo(i);
+  for (i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    a[i] = 42;
+  }
+  int b = 22 / (k - 42); // no-warning
+  return 0;
+}
+
+int nested_outer_unrolled() {
+  int a[9];
+  int k = 42;
+  int j = 0;
+  for (int i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{1}}
+    for (j = 0; j < 9; ++j) {
+      clang_analyzer_numTimesReached(); // expected-warning {{4}}
+      a[j] = 22;
+      (void) &j; // ensures that the inner loop won't be unrolled
+    }
+    a[i] = 42;
+  }
+  int b = 22 / (k - 42); // no-warning
+  return 0;
+}
+
+int nested_inner_unrolled() {
+  int a[9];
+  int k = 42;
+  int j = 0;
+  for (int i = 0; i < getNum(); i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    for (j = 0; j < 8; ++j) {
+      clang_analyzer_numTimesReached(); // expected-warning {{32}}
+      a[j] = 22;
+    }
+    a[i] = 42;
+  }
+  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+  return 0;
+}
+
+int nested_both_unrolled() {
+  int a[9];
+  int k = 42;
+  int j = 0;
+  for (int i = 0; i < 7; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{7}}
+    for (j = 0; j < 6; ++j) {
+      clang_analyzer_numTimesReached(); // expected-warning {{42}}
+      a[j] = 22;
+    }
+    a[i] = 42;
+  }
+  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
+  return 0;
+}
+
+int simple_known_bound_loop() {
+  for (int i = 2; i < 12; i++) {
+    // This function is inlined in nested_inlined_unroll1()
+    clang_analyzer_numTimesReached(); // expected-warning {{90}}
+  }
+  return 0;
+}
+
+int simple_unknown_bound_loop() {
+  for (int i = 2; i < getNum(); i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{10}}
+  }
+  return 0;
+}
+
+int nested_inlined_unroll1() {
+  int k;
+  for (int i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{9}}
+    k = simple_known_bound_loop();    // no reevaluation without inlining
+  }
+  int a = 22 / k; // expected-warning {{Division by zero}}
+  return 0;
+}
+
+int nested_inlined_no_unroll1() {
+  int k;
+  for (int i = 0; i < 9; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{15}}
+    k = simple_unknown_bound_loop();  // reevaluation without inlining, splits the state as well
+  }
+  int a = 22 / k; // no-warning
+  return 0;
+}
+
+int recursion_unroll1(bool b) {
+  int k = 2;
+  for (int i = 0; i < 5; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{13}}
+    if(i == 0 && b) // Splits the state in the first iteration but the recursion
+                    // call will be unrolled anyway since the condition is known there.
+      recursion_unroll1(false);
+    clang_analyzer_numTimesReached(); // expected-warning {{14}}
+  }
+  int a = 22 / k; // no-warning
+  return 0;
+}
+
+int recursion_unroll2(bool b) {
+  int k = 0;
+  for (int i = 0; i < 5; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{9}}
+    if(i == 0 && b)
+      recursion_unroll2(false);
+    clang_analyzer_numTimesReached(); // expected-warning {{9}}
+  }
+  int a = 22 / k; // expected-warning {{Division by zero}}
+  return 0;
+}
+
+int recursion_unroll3(bool b) {
+  int k = 2;
+  for (int i = 0; i < 5; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{10}}
+    if (i == 4 && b) {
+      recursion_unroll3(false);
+      break;
+    }
+    clang_analyzer_numTimesReached(); // expected-warning {{10}}
+  }
+  int a = 22 / k;
+  return 0;
+}
+
+int recursion_unroll4(bool b) {
+  int k = 2;
+  for (int i = 0; i < 5; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{13}}
+    if(i == 0 && b) {
+      recursion_unroll4(false);
+      continue;
+    }
+    clang_analyzer_numTimesReached(); // expected-warning {{13}}
+  }
+  int a = 22 / k;
+  return 0;
+}
+
+int loop_exit_while_empty_loop_stack() {
+  if (getNum())
+    for (int i = 1; i < 8; i++)
+      ;
+  return 0;
+}
+
+int num_steps_on_limit() {
+  for (int i = 0; i < 128; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{128}}
+  }
+  clang_analyzer_numTimesReached(); // expected-warning {{1}}
+  return 0;
+}
+
+int num_steps_over_limit1() {
+  for (int i = 0; i < 129; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+  }
+  return 0;
+}
+
+int num_steps_on_limit2() {
+  for (int i = 0; i < 2; i++) {
+    for (int j = 0; j < 64; j++) {
+      clang_analyzer_numTimesReached(); // expected-warning {{128}}
+    }
+  }
+  return 0;
+}
+
+int num_steps_over_limit2() {
+  for (int i = 0; i < 2; i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{1}}
+    for (int j = 0; j <= 64; j++) {
+      clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    }
+  }
+  return 0;
+}
+
+int num_steps_on_limit3() {
+  for (int i = 0; i < getNum(); i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    for (int j = 0; j < 32; j++) {
+      clang_analyzer_numTimesReached(); // expected-warning {{128}}
+    }
+  }
+  return 0;
+}
+
+int num_steps_over_limit3() {
+  for (int i = 0; i < getNum(); i++) {
+    clang_analyzer_numTimesReached(); // expected-warning {{1}}
+    for (int j = 0; j < 33; j++) {
+      clang_analyzer_numTimesReached(); // expected-warning {{4}}
+    }
+  }
+  return 0;
+}
+
+
+void pr34943() {
+  for (int i = 0; i < 6L; ++i) {
+    clang_analyzer_numTimesReached(); // expected-warning {{6}}
+  }
+}
diff --git a/test/Analysis/loopexit-cfg-output.cpp b/test/Analysis/loopexit-cfg-output.cpp
new file mode 100644
index 0000000..8e53ce3
--- /dev/null
+++ b/test/Analysis/loopexit-cfg-output.cpp
@@ -0,0 +1,476 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-loopexit=true %s > %t 2>&1
+// RUN: FileCheck --input-file=%t %s
+
+// CHECK:       [B6 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   2: return;
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B2.1]++
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B3.1]++
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B4.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 12
+// CHECK-NEXT:   4: [B4.2] < [B4.3]
+// CHECK-NEXT:   T: for (...; [B4.4]; ...)
+// CHECK-NEXT:   Preds (2): B2 B5
+// CHECK-NEXT:   Succs (2): B3 B1
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: 0
+// CHECK-NEXT:   2: int i = 0;
+// CHECK-NEXT:   Preds (1): B6
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_forloop1() {
+  for (int i = 0; i < 12; i++) {
+    i++;
+  }
+  return;
+}
+
+// CHECK:       [B4 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B3]
+// CHECK-NEXT:   T: for (; ; )
+// CHECK-NEXT:   Preds (2): B2 B4
+// CHECK-NEXT:   Succs (2): B2 NULL
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_forloop2() {
+  for (;;)
+    ;
+}
+
+// CHECK:       [B5 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: int i;
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: true
+// CHECK-NEXT:   T: while [B4.1]
+// CHECK-NEXT:   Preds (2): B2 B5
+// CHECK-NEXT:   Succs (2): B3 NULL
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_while1() {
+  while (true) {
+    int i;
+  }
+}
+
+// CHECK:       [B5 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   2: 2
+// CHECK-NEXT:   3: int k = 2;
+// CHECK-NEXT:   4: return;
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: l
+// CHECK-NEXT:   2: [B3.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 42
+// CHECK-NEXT:   4: [B3.2] < [B3.3]
+// CHECK-NEXT:   T: while [B3.4]
+// CHECK-NEXT:   Preds (2): B2 B4
+// CHECK-NEXT:   Succs (2): B2 B1
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: int l;
+// CHECK-NEXT:   Preds (1): B5
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_while2() {
+  int l;
+  while (l < 42)
+    ;
+  int k = 2;
+  return;
+}
+
+// CHECK:       [B4 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: false
+// CHECK-NEXT:   T: while [B3.1]
+// CHECK-NEXT:   Preds (2): B2 B4
+// CHECK-NEXT:   Succs (2): NULL B1
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_while3() {
+  while (false) {
+    ;
+  }
+}
+
+// CHECK:       [B4 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: DoStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B2
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   1: false
+// CHECK-NEXT:   T: do ... while [B2.1]
+// CHECK-NEXT:   Preds (2): B3 B4
+// CHECK-NEXT:   Succs (2): NULL B1
+
+// CHECK:       [B3]
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_dowhile1() {
+  do {
+  } while (false);
+}
+
+// CHECK:       [B6 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: DoStmt (LoopExit)
+// CHECK-NEXT:   2: j
+// CHECK-NEXT:   3: [B1.2]--
+// CHECK-NEXT:   4: return;
+// CHECK-NEXT:   Preds (1): B2
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B2.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 20
+// CHECK-NEXT:   4: [B2.2] < [B2.3]
+// CHECK-NEXT:   T: do ... while [B2.4]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (2): B4 B1
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: 2
+// CHECK-NEXT:   3: [B3.1] += [B3.2]
+// CHECK-NEXT:   Preds (2): B4 B5
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   Preds (1): B2
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: 2
+// CHECK-NEXT:   2: int j = 2;
+// CHECK-NEXT:   Preds (1): B6
+// CHECK-NEXT:   Succs (1): B3
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_dowhile2() {
+  int j = 2;
+  do {
+    j += 2;
+  } while (j < 20);
+  j--;
+  return;
+}
+
+// CHECK:       [B10 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B9
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B8
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B8
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B6
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B4.1]++
+// CHECK-NEXT:   Preds (1): B5
+// CHECK-NEXT:   Succs (1): B6
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B5.1]++
+// CHECK-NEXT:   Preds (1): B6
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B6]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B6.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 6
+// CHECK-NEXT:   4: [B6.2] < [B6.3]
+// CHECK-NEXT:   T: for (...; [B6.4]; ...)
+// CHECK-NEXT:   Preds (2): B4 B7
+// CHECK-NEXT:   Succs (2): B5 B3
+
+// CHECK:       [B7]
+// CHECK-NEXT:   1: 1
+// CHECK-NEXT:   2: int j = 1;
+// CHECK-NEXT:   Preds (1): B8
+// CHECK-NEXT:   Succs (1): B6
+
+// CHECK:       [B8]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B8.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 2
+// CHECK-NEXT:   4: [B8.2] < [B8.3]
+// CHECK-NEXT:   T: while [B8.4]
+// CHECK-NEXT:   Preds (2): B2 B9
+// CHECK-NEXT:   Succs (2): B7 B1
+
+// CHECK:       [B9]
+// CHECK-NEXT:   1: 40
+// CHECK-NEXT:   2: -[B9.1]
+// CHECK-NEXT:   3: int i = -40;
+// CHECK-NEXT:   Preds (1): B10
+// CHECK-NEXT:   Succs (1): B8
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void nested_loops1() {
+  int i = -40;
+  while (i < 2) {
+    for (int j = 1; j < 6; j++)
+      i++;
+  }
+}
+
+// CHECK:       [B9 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B8
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   Preds (1): B7
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B2.1]++
+// CHECK-NEXT:   Preds (1): B3
+// CHECK-NEXT:   Succs (1): B7
+
+// CHECK:       [B3]
+// CHECK-NEXT:   1: DoStmt (LoopExit)
+// CHECK-NEXT:   2: i
+// CHECK-NEXT:   3: [B3.2]--
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B2
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B4.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 2
+// CHECK-NEXT:   4: [B4.2] < [B4.3]
+// CHECK-NEXT:   T: do ... while [B4.4]
+// CHECK-NEXT:   Preds (1): B5
+// CHECK-NEXT:   Succs (2): B6 B3
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B5.1]++
+// CHECK-NEXT:   Preds (2): B6 B7
+// CHECK-NEXT:   Succs (1): B4
+
+// CHECK:       [B6]
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B7]
+// CHECK-NEXT:   1: j
+// CHECK-NEXT:   2: [B7.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 6
+// CHECK-NEXT:   4: [B7.2] < [B7.3]
+// CHECK-NEXT:   T: for (...; [B7.4]; ...)
+// CHECK-NEXT:   Preds (2): B2 B8
+// CHECK-NEXT:   Succs (2): B5 B1
+
+// CHECK:       [B8]
+// CHECK-NEXT:   1: 40
+// CHECK-NEXT:   2: -[B8.1]
+// CHECK-NEXT:   3: int i = -40;
+// CHECK-NEXT:   4: 1
+// CHECK-NEXT:   5: int j = 1;
+// CHECK-NEXT:   Preds (1): B9
+// CHECK-NEXT:   Succs (1): B7
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void nested_loops2() {
+  int i = -40;
+  for (int j = 1; j < 6; j++) {
+    do {
+      i++;
+    } while (i < 2);
+    i--;
+  }
+}
+
+// CHECK:       [B12 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B11
+
+// CHECK:       [B1]
+// CHECK-NEXT:   1: WhileStmt (LoopExit)
+// CHECK-NEXT:   2: return;
+// CHECK-NEXT:   Preds (2): B3 B5
+// CHECK-NEXT:   Succs (1): B0
+
+// CHECK:       [B2]
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B3]
+// CHECK-NEXT:   T: break;
+// CHECK-NEXT:   Preds (1): B4
+// CHECK-NEXT:   Succs (1): B1
+
+// CHECK:       [B4]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B4.1]++
+// CHECK-NEXT:   3: i
+// CHECK-NEXT:   4: [B4.3] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   5: 2
+// CHECK-NEXT:   6: [B4.4] % [B4.5]
+// CHECK-NEXT:   7: [B4.6] (ImplicitCastExpr, IntegralToBoolean, _Bool)
+// CHECK-NEXT:   T: if [B4.7]
+// CHECK-NEXT:   Preds (1): B5
+// CHECK-NEXT:   Succs (2): B3 B2
+
+// CHECK:       [B5]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B5.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 5
+// CHECK-NEXT:   4: [B5.2] < [B5.3]
+// CHECK-NEXT:   T: while [B5.4]
+// CHECK-NEXT:   Preds (2): B2 B6
+// CHECK-NEXT:   Succs (2): B4 B1
+
+// CHECK:       [B6]
+// CHECK-NEXT:   1: ForStmt (LoopExit)
+// CHECK-NEXT:   2: 1
+// CHECK-NEXT:   3: int i = 1;
+// CHECK-NEXT:   Preds (2): B8 B10
+// CHECK-NEXT:   Succs (1): B5
+
+// CHECK:       [B7]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B7.1]++
+// CHECK-NEXT:   Preds (1): B9
+// CHECK-NEXT:   Succs (1): B10
+
+// CHECK:       [B8]
+// CHECK-NEXT:   T: break;
+// CHECK-NEXT:   Preds (1): B9
+// CHECK-NEXT:   Succs (1): B6
+
+// CHECK:       [B9]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B9.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 4
+// CHECK-NEXT:   4: [B9.2] == [B9.3]
+// CHECK-NEXT:   T: if [B9.4]
+// CHECK-NEXT:   Preds (1): B10
+// CHECK-NEXT:   Succs (2): B8 B7
+
+// CHECK:       [B10]
+// CHECK-NEXT:   1: i
+// CHECK-NEXT:   2: [B10.1] (ImplicitCastExpr, LValueToRValue, int)
+// CHECK-NEXT:   3: 6
+// CHECK-NEXT:   4: [B10.2] < [B10.3]
+// CHECK-NEXT:   T: for (...; [B10.4]; ...)
+// CHECK-NEXT:   Preds (2): B7 B11
+// CHECK-NEXT:   Succs (2): B9 B6
+
+// CHECK:       [B11]
+// CHECK-NEXT:   1: 2
+// CHECK-NEXT:   2: int i = 2;
+// CHECK-NEXT:   Preds (1): B12
+// CHECK-NEXT:   Succs (1): B10
+
+// CHECK:       [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void check_break()
+{
+  for(int i = 2; i < 6; i++) {
+    if(i == 4)
+      break;
+  }
+
+  int i = 1;
+  while(i<5){
+    i++;
+    if(i%2)
+      break;
+  }
+  
+  return;
+}
diff --git a/test/Analysis/max-nodes-suppress-on-sink.c b/test/Analysis/max-nodes-suppress-on-sink.c
index 8d955b9..da1e7bf 100644
--- a/test/Analysis/max-nodes-suppress-on-sink.c
+++ b/test/Analysis/max-nodes-suppress-on-sink.c
@@ -15,6 +15,8 @@
 
 void clang_analyzer_warnIfReached(void);
 
+int coin();
+
 void test_single_cfg_block_sink() {
   void *p = malloc(1); // no-warning (wherever the leak warning may occur here)
 
@@ -29,3 +31,53 @@
   // the leak report.
   exit(0);
 }
+
+// A similar test with more complicated control flow before the no-return thing,
+// so that the no-return thing wasn't in the same CFG block.
+void test_more_complex_control_flow_before_sink() {
+  void *p = malloc(1); // no-warning
+
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+  clang_analyzer_warnIfReached(); // no-warning
+
+  if (coin())
+    exit(0);
+  else
+    exit(1);
+}
+
+// A loop before the no-return function, to make sure that
+// the dominated-by-sink analysis doesn't hang.
+void test_loop_before_sink(int n) {
+  void *p = malloc(1); // no-warning
+
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+  clang_analyzer_warnIfReached(); // no-warning
+
+  for (int i = 0; i < n; ++i) {
+  }
+  exit(1);
+}
+
+// We're not sure if this is no-return.
+void test_loop_with_sink(int n) {
+  void *p = malloc(1); // expected-warning@+2{{Potential leak of memory}}
+
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+  clang_analyzer_warnIfReached(); // no-warning
+
+  for (int i = 0; i < n; ++i)
+    if (i == 0)
+      exit(1);
+}
+
+// Handle unreachable blocks correctly.
+void test_unreachable_successor_blocks() {
+  void *p = malloc(1); // no-warning
+
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+  clang_analyzer_warnIfReached(); // no-warning
+
+  if (1) // no-crash
+    exit(1);
+}
diff --git a/test/Analysis/max-nodes-suppress-on-sink.cpp b/test/Analysis/max-nodes-suppress-on-sink.cpp
new file mode 100644
index 0000000..814b302
--- /dev/null
+++ b/test/Analysis/max-nodes-suppress-on-sink.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_analyze_cc1 -x c++ -fcxx-exceptions -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config max-nodes=12 -verify %s
+
+// Here we test how "suppress on sink" feature of certain bugtypes interacts
+// with reaching analysis limits. See comments in max-nodes-suppress-on-sink.c
+// for more discussion.
+
+typedef __typeof(sizeof(int)) size_t;
+void *malloc(size_t);
+
+void clang_analyzer_warnIfReached(void);
+
+// Because we don't have a better approach, we currently treat throw as
+// noreturn.
+void test_throw_treated_as_noreturn() {
+  void *p = malloc(1); // no-warning
+
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+  clang_analyzer_warnIfReached(); // no-warning
+
+  throw 0;
+}
+
+// FIXME: Handled throws shouldn't be suppressing us!
+void test_handled_throw_treated_as_noreturn() {
+  void *p = malloc(1); // no-warning
+
+  clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+  clang_analyzer_warnIfReached(); // no-warning
+
+  try {
+    throw 0;
+  } catch (int i) {
+  }
+}
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/nonnull-global-constants.mm b/test/Analysis/nonnull-global-constants.mm
new file mode 100644
index 0000000..7900b9d
--- /dev/null
+++ b/test/Analysis/nonnull-global-constants.mm
@@ -0,0 +1,103 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+
+// Nullability of const string-like globals, testing
+// NonnullGlobalConstantsChecker.
+
+void clang_analyzer_eval(bool);
+
+@class NSString;
+typedef const struct __CFString *CFStringRef;
+typedef const struct __CFBoolean * CFBooleanRef;
+
+// Global NSString* is non-null.
+extern NSString *const StringConstGlobal;
+void stringConstGlobal() {
+  clang_analyzer_eval(StringConstGlobal); // expected-warning{{TRUE}}
+}
+
+// The logic does not apply to local variables though.
+extern NSString *stringGetter();
+void stringConstLocal() {
+  NSString *const local = stringGetter();
+  clang_analyzer_eval(local); // expected-warning{{UNKNOWN}}
+}
+
+// Global const CFStringRef's are also assumed to be non-null.
+extern const CFStringRef CFStringConstGlobal;
+void cfStringCheckGlobal() {
+  clang_analyzer_eval(CFStringConstGlobal); // expected-warning{{TRUE}}
+}
+
+// But only "const" ones.
+extern CFStringRef CFStringNonConstGlobal;
+void cfStringCheckMutableGlobal() {
+  clang_analyzer_eval(CFStringNonConstGlobal); // expected-warning{{UNKNOWN}}
+}
+
+// char* const is also assumed to be non-null.
+extern const char *const ConstCharStarConst;
+void constCharStarCheckGlobal() {
+  clang_analyzer_eval(ConstCharStarConst); // expected-warning{{TRUE}}
+}
+
+// Pointer value can be mutable.
+extern char *const CharStarConst;
+void charStarCheckGlobal() {
+  clang_analyzer_eval(CharStarConst); // expected-warning{{TRUE}}
+}
+
+// But the pointer itself should be immutable.
+extern char *CharStar;
+void charStartCheckMutableGlobal() {
+  clang_analyzer_eval(CharStar); // expected-warning{{UNKNOWN}}
+}
+
+// Type definitions should also work across typedefs, for pointers:
+typedef char *const str;
+extern str globalStr;
+void charStarCheckTypedef() {
+  clang_analyzer_eval(globalStr); // expected-warning{{TRUE}}
+}
+
+// And for types.
+typedef NSString *const NStr;
+extern NStr globalNSString;
+void NSStringCheckTypedef() {
+  clang_analyzer_eval(globalNSString); // expected-warning{{TRUE}}
+}
+
+// Note that constness could be either inside
+// the var declaration, or in a typedef.
+typedef NSString *NStr2;
+extern const NStr2 globalNSString2;
+void NSStringCheckConstTypedef() {
+  clang_analyzer_eval(globalNSString2); // expected-warning{{TRUE}}
+}
+
+// Nested typedefs should work as well.
+typedef const CFStringRef str1;
+typedef str1 str2;
+extern str2 globalStr2;
+void testNestedTypedefs() {
+  clang_analyzer_eval(globalStr2); // expected-warning{{TRUE}}
+}
+
+// And for NSString *.
+typedef NSString *const nstr1;
+typedef nstr1 nstr2;
+extern nstr2 nglobalStr2;
+void testNestedTypedefsForNSString() {
+  clang_analyzer_eval(nglobalStr2); // expected-warning{{TRUE}}
+}
+
+// And for CFBooleanRefs.
+extern const CFBooleanRef kBool;
+void testNonnullBool() {
+  clang_analyzer_eval(kBool); // expected-warning{{TRUE}}
+}
+
+// And again, only for const one.
+extern CFBooleanRef kBoolMutable;
+void testNonnullNonconstBool() {
+  clang_analyzer_eval(kBoolMutable); // expected-warning{{UNKNOWN}}
+}
diff --git a/test/Analysis/ns_error_enum.m b/test/Analysis/ns_error_enum.m
new file mode 100644
index 0000000..bf61629
--- /dev/null
+++ b/test/Analysis/ns_error_enum.m
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -verify %s
+
+#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#define NS_ENUM(_type, _name) CF_ENUM(_type, _name)
+
+#define NS_ERROR_ENUM(_type, _name, _domain)  \
+  enum _name : _type _name; enum __attribute__((ns_error_domain(_domain))) _name : _type
+
+typedef NS_ENUM(unsigned, MyEnum) {
+  MyFirst,
+  MySecond,
+};
+
+typedef NS_ENUM(invalidType, MyInvalidEnum) {
+// expected-error@-1{{unknown type name 'invalidType'}}
+// expected-error@-2{{unknown type name 'invalidType'}}
+  MyFirstInvalid,
+  MySecondInvalid,
+};
+
+const char *MyErrorDomain;
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnum, MyErrorDomain) {
+	MyErrFirst,
+	MyErrSecond,
+};
+struct __attribute__((ns_error_domain(MyErrorDomain))) MyStructErrorDomain {};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, InvalidDomain) {
+	// expected-error@-1{{domain argument 'InvalidDomain' does not refer to global constant}}
+	MyErrFirstInvalid,
+	MyErrSecondInvalid,
+};
+
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalid, "domain-string");
+  // expected-error@-1{{domain argument must be an identifier}}
+
+int __attribute__((ns_error_domain(MyErrorDomain))) NotTagDecl;
+  // expected-error@-1{{ns_error_domain attribute only valid on enums, structs, and unions}}
+
+void foo() {}
+typedef NS_ERROR_ENUM(unsigned char, MyErrorEnumInvalidFunction, foo);
+  // expected-error@-1{{domain argument 'foo' does not refer to global constant}}
diff --git a/test/Analysis/null-deref-path-notes.c b/test/Analysis/null-deref-path-notes.c
new file mode 100644
index 0000000..a1477a6
--- /dev/null
+++ b/test/Analysis/null-deref-path-notes.c
@@ -0,0 +1,9 @@
+// RUN: %clang_analyze_cc1 -w -x c -analyzer-checker=core -analyzer-output=text -verify %s
+
+// Avoid the crash when finding the expression for tracking the origins
+// of the null pointer for path notes.
+void pr34373() {
+  int *a = 0; // expected-note{{'a' initialized to a null pointer value}}
+  (a + 0)[0]; // expected-warning{{Array access results in a null pointer dereference}}
+              // expected-note@-1{{Array access results in a null pointer dereference}}
+}
diff --git a/test/Analysis/null-deref-path-notes.cpp b/test/Analysis/null-deref-path-notes.cpp
new file mode 100644
index 0000000..617f5de
--- /dev/null
+++ b/test/Analysis/null-deref-path-notes.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_analyze_cc1 -w -x c++ -analyzer-checker=core -analyzer-output=text -analyzer-eagerly-assume -verify %s
+
+namespace pr34731 {
+int b;
+class c {
+  class B {
+   public:
+    double ***d;
+    B();
+  };
+  void e(double **, int);
+  void f(B &, int &);
+};
+
+// Properly track the null pointer in the array field back to the default
+// constructor of 'h'.
+void c::f(B &g, int &i) {
+  e(g.d[9], i); // expected-warning{{Array access (via field 'd') results in a null pointer dereference}}
+                // expected-note@-1{{Array access (via field 'd') results in a null pointer dereference}}
+  B h, a; // expected-note{{Value assigned to 'h.d'}}
+  a.d == __null; // expected-note{{Assuming the condition is true}}
+  a.d != h.d; // expected-note{{Assuming pointer value is null}}
+  f(h, b); // expected-note{{Calling 'c::f'}}
+}
+}
diff --git a/test/Analysis/null-deref-path-notes.m b/test/Analysis/null-deref-path-notes.m
index 242b5da..39cf9c7 100644
--- a/test/Analysis/null-deref-path-notes.m
+++ b/test/Analysis/null-deref-path-notes.m
@@ -50,6 +50,23 @@
   *p = 1; // expected-warning{{Dereference of null pointer}} expected-note{{Dereference of null pointer}}
 }
 
+@interface WithArrayPtr
+- (void) useArray;
+@end
+
+@implementation WithArrayPtr {
+@public int *p;
+}
+- (void)useArray {
+  p[1] = 2; // expected-warning{{Array access (via ivar 'p') results in a null pointer dereference}}
+            // expected-note@-1{{Array access (via ivar 'p') results in a null pointer dereference}}
+}
+@end
+
+void testWithArrayPtr(WithArrayPtr *w) {
+  w->p = 0; // expected-note{{Null pointer value stored to 'p'}}
+  [w useArray]; // expected-note{{Calling 'useArray'}}
+}
 
 // CHECK:  <key>diagnostics</key>
 // CHECK-NEXT:  <array>
@@ -801,4 +818,227 @@
 // CHECK-NEXT:    <key>file</key><integer>0</integer>
 // CHECK-NEXT:   </dict>
 // CHECK-NEXT:   </dict>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>path</key>
+// CHECK-NEXT:    <array>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>67</integer>
+// CHECK-NEXT:       <key>col</key><integer>3</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>67</integer>
+// CHECK-NEXT:          <key>col</key><integer>3</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>67</integer>
+// CHECK-NEXT:          <key>col</key><integer>10</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>67</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>67</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>68</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>68</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>68</integer>
+// CHECK-NEXT:       <key>col</key><integer>3</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>68</integer>
+// CHECK-NEXT:          <key>col</key><integer>3</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>68</integer>
+// CHECK-NEXT:          <key>col</key><integer>14</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>0</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Calling &apos;useArray&apos;</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Calling &apos;useArray&apos;</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>60</integer>
+// CHECK-NEXT:       <key>col</key><integer>1</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>depth</key><integer>1</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Entered call from &apos;testWithArrayPtr&apos;</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Entered call from &apos;testWithArrayPtr&apos;</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>60</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>60</integer>
+// CHECK-NEXT:            <key>col</key><integer>1</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>61</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>61</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>61</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>61</integer>
+// CHECK-NEXT:            <key>col</key><integer>3</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>61</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>61</integer>
+// CHECK-NEXT:            <key>col</key><integer>8</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>event</string>
+// CHECK-NEXT:      <key>location</key>
+// CHECK-NEXT:      <dict>
+// CHECK-NEXT:       <key>line</key><integer>61</integer>
+// CHECK-NEXT:       <key>col</key><integer>8</integer>
+// CHECK-NEXT:       <key>file</key><integer>0</integer>
+// CHECK-NEXT:      </dict>
+// CHECK-NEXT:      <key>ranges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:        <array>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>61</integer>
+// CHECK-NEXT:          <key>col</key><integer>3</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:         <dict>
+// CHECK-NEXT:          <key>line</key><integer>61</integer>
+// CHECK-NEXT:          <key>col</key><integer>3</integer>
+// CHECK-NEXT:          <key>file</key><integer>0</integer>
+// CHECK-NEXT:         </dict>
+// CHECK-NEXT:        </array>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:      <key>depth</key><integer>1</integer>
+// CHECK-NEXT:      <key>extended_message</key>
+// CHECK-NEXT:      <string>Array access (via ivar &apos;p&apos;) results in a null pointer dereference</string>
+// CHECK-NEXT:      <key>message</key>
+// CHECK-NEXT:      <string>Array access (via ivar &apos;p&apos;) results in a null pointer dereference</string>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:    </array>
+// CHECK-NEXT:    <key>description</key><string>Array access (via ivar &apos;p&apos;) results in a null pointer dereference</string>
+// CHECK-NEXT:    <key>category</key><string>Logic error</string>
+// CHECK-NEXT:    <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT:    <key>check_name</key><string>core.NullDereference</string>
+// CHECK-NEXT:    <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:    <key>issue_hash_content_of_line_in_context</key><string>fb0ad1e4e3090d9834d542eb54bc9d2e</string>
+// CHECK-NEXT:   <key>issue_context_kind</key><string>Objective-C method</string>
+// CHECK-NEXT:   <key>issue_context</key><string>useArray</string>
+// CHECK-NEXT:   <key>issue_hash_function_offset</key><string>1</string>
+// CHECK-NEXT:   <key>location</key>
+// CHECK-NEXT:   <dict>
+// CHECK-NEXT:    <key>line</key><integer>61</integer>
+// CHECK-NEXT:    <key>col</key><integer>8</integer>
+// CHECK-NEXT:    <key>file</key><integer>0</integer>
+// CHECK-NEXT:   </dict>
+// CHECK-NEXT:   </dict>
 // CHECK-NEXT:  </array>
diff --git a/test/Analysis/nullptr.cpp b/test/Analysis/nullptr.cpp
index 229ad7b..b3e61c9 100644
--- a/test/Analysis/nullptr.cpp
+++ b/test/Analysis/nullptr.cpp
@@ -1,11 +1,12 @@
-// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -verify %s
+// RUN: %clang_analyze_cc1 -std=c++11 -Wno-conversion-null -analyzer-checker=core,debug.ExprInspection -analyzer-store region -analyzer-output=text -verify %s
 
 void clang_analyzer_eval(int);
 
 // test to see if nullptr is detected as a null pointer
 void foo1(void) {
-  char  *np = nullptr;
+  char  *np = nullptr; // expected-note{{'np' initialized to a null pointer value}}
   *np = 0;  // expected-warning{{Dereference of null pointer}}
+            // expected-note@-1{{Dereference of null pointer}}
 }
 
 // check if comparing nullptr to nullptr is detected properly
@@ -23,10 +24,11 @@
   struct foo {
     int a, f;
   };
-  char *np = nullptr;
+  char *np = nullptr; // expected-note{{'np' initialized to a null pointer value}}
   // casting a nullptr to anything should be caught eventually
-  int *ip = &(((struct foo *)np)->f);
+  int *ip = &(((struct foo *)np)->f); // expected-note{{'ip' initialized to a null pointer value}}
   *ip = 0;  // expected-warning{{Dereference of null pointer}}
+            // expected-note@-1{{Dereference of null pointer}}
   // should be error here too, but analysis gets stopped
 //  *np = 0;
 }
@@ -49,16 +51,31 @@
 }
 
 void zoo1() {
-  char **p = 0;
+  char **p = 0; // expected-note{{'p' initialized to a null pointer value}}
   delete *(p + 0); // expected-warning{{Dereference of null pointer}}
+                   // expected-note@-1{{Dereference of null pointer}}
+}
+
+void zoo1backwards() {
+  char **p = 0; // expected-note{{'p' initialized to a null pointer value}}
+  delete *(0 + p); // expected-warning{{Dereference of null pointer}}
+                   // expected-note@-1{{Dereference of null pointer}}
+}
+
+typedef __INTPTR_TYPE__ intptr_t;
+void zoo1multiply() {
+  char **p = 0; // FIXME-should-be-note:{{'p' initialized to a null pointer value}}
+  delete *((char **)((intptr_t)p * 2)); // expected-warning{{Dereference of null pointer}}
+                   // expected-note@-1{{Dereference of null pointer}}
 }
 
 void zoo2() {
   int **a = 0;
-  int **b = 0;
+  int **b = 0; // expected-note{{'b' initialized to a null pointer value}}
   asm ("nop"
       :"=r"(*a)
       :"0"(*b) // expected-warning{{Dereference of null pointer}}
+               // expected-note@-1{{Dereference of null pointer}}
       );
 }
 
@@ -70,17 +87,19 @@
     int a;
   };
 
-  int *x = 0;
+  int *x = 0; // expected-note{{'x' initialized to a null pointer value}}
   return S(*x).a; // expected-warning{{Dereference of null pointer}}
+                  // expected-note@-1{{Dereference of null pointer}}
 }
 
 int materializeTempExpr() {
-  int *n = 0;
+  int *n = 0; // expected-note{{'n' initialized to a null pointer value}}
   struct S {
     int a;
     S(int i): a(i) {}
   };
   const S &s = S(*n); // expected-warning{{Dereference of null pointer}}
+                      // expected-note@-1{{Dereference of null pointer}}
   return s.a;
 }
 
@@ -98,6 +117,7 @@
 
 void invokeF(X* x) {
   x->f(); // expected-warning{{Called C++ object pointer is null}}
+          // expected-note@-1{{Called C++ object pointer is null}}
 }
 
 struct Type {
@@ -105,26 +125,41 @@
 };
 
 void shouldNotCrash() {
-  decltype(nullptr) p;
-  if (getSymbol())
-    invokeF(p); // expected-warning{{1st function call argument is an uninit}}
-  if (getSymbol())
-    invokeF(nullptr);
-  if (getSymbol()) {
-    X *x = Type().x;
+  decltype(nullptr) p; // expected-note{{'p' declared without an initial value}}
+  if (getSymbol()) // expected-note   {{Assuming the condition is false}}
+                   // expected-note@-1{{Taking false branch}}
+                   // expected-note@-2{{Assuming the condition is false}}
+                   // expected-note@-3{{Taking false branch}}
+                   // expected-note@-4{{Assuming the condition is true}}
+                   // expected-note@-5{{Taking true branch}}
+    invokeF(p); // expected-warning{{1st function call argument is an uninitialized value}}
+                // expected-note@-1{{1st function call argument is an uninitialized value}}
+  if (getSymbol()) // expected-note   {{Assuming the condition is false}}
+                   // expected-note@-1{{Taking false branch}}
+                   // expected-note@-2{{Assuming the condition is true}}
+                   // expected-note@-3{{Taking true branch}}
+    invokeF(nullptr); // expected-note   {{Calling 'invokeF'}}
+                      // expected-note@-1{{Passing null pointer value via 1st parameter 'x'}}
+  if (getSymbol()) {  // expected-note  {{Assuming the condition is true}}
+                      // expected-note@-1{{Taking true branch}}
+    X *x = Type().x; // expected-note{{'x' initialized to a null pointer value}}
     x->f(); // expected-warning{{Called C++ object pointer is null}}
+            // expected-note@-1{{Called C++ object pointer is null}}
   }
 }
 
 void f(decltype(nullptr) p) {
   int *q = nullptr;
   clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
+                               // expected-note@-1{{TRUE}}
   clang_analyzer_eval(q == 0); // expected-warning{{TRUE}}
+                               // expected-note@-1{{TRUE}}
 }
 
 decltype(nullptr) returnsNullPtrType();
 void fromReturnType() {
   ((X *)returnsNullPtrType())->f(); // expected-warning{{Called C++ object pointer is null}}
+                                    // expected-note@-1{{Called C++ object pointer is null}}
 }
 
 #define AS_ATTRIBUTE __attribute__((address_space(256)))
diff --git a/test/Analysis/objc-boxing.m b/test/Analysis/objc-boxing.m
index 963374b..66f24dd 100644
--- a/test/Analysis/objc-boxing.m
+++ b/test/Analysis/objc-boxing.m
@@ -5,6 +5,16 @@
 typedef signed char BOOL;
 typedef long NSInteger;
 typedef unsigned long NSUInteger;
+
+@protocol NSObject
+@end
+@interface NSObject <NSObject> {}
+@end
+@protocol NSCopying
+@end
+@protocol NSCoding
+@end
+
 @interface NSString @end
 @interface NSString (NSStringExtensionMethods)
 + (id)stringWithUTF8String:(const char *)nullTerminatedCString;
@@ -28,7 +38,15 @@
 + (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value ;
 @end
 
+@interface NSValue : NSObject <NSCopying, NSCoding>
+- (void)getValue:(void *)value;
++ (NSValue *)valueWithBytes:(const void *)value
+                   objCType:(const char *)type;
+@end
 
+typedef typeof(sizeof(int)) size_t;
+extern void *malloc(size_t);
+extern void free(void *);
 extern char *strdup(const char *str);
 
 id constant_string() {
@@ -39,6 +57,23 @@
     return @(strdup("boxed dynamic string")); // expected-warning{{Potential memory leak}}
 }
 
+typedef struct __attribute__((objc_boxable)) {
+  const char *str;
+} BoxableStruct;
+
+id leak_within_boxed_struct() {
+  BoxableStruct bs;
+  bs.str = strdup("dynamic string"); // The duped string shall be owned by val.
+  NSValue *val = @(bs); // no-warning
+  return val;
+}
+
+id leak_of_boxed_struct() {
+  BoxableStruct *bs = malloc(sizeof(BoxableStruct)); // The pointer stored in bs isn't owned by val.
+  NSValue *val = @(*bs); // expected-warning{{Potential leak of memory pointed to by 'bs'}}
+  return val;
+}
+
 id const_char_pointer(int *x) {
   if (x)
     return @(3);
diff --git a/test/Analysis/objc-encode.m b/test/Analysis/objc-encode.m
new file mode 100644
index 0000000..b2379e9
--- /dev/null
+++ b/test/Analysis/objc-encode.m
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=debug.ExprInspection -verify %s
+// expected-no-diagnostics
+
+void clang_analyzer_eval(int);
+
+// rdar://problem/34831581: Used to crash.
+void foo(void) {
+  char buf1[] = @encode(int **);
+}
diff --git a/test/Analysis/objc-for.m b/test/Analysis/objc-for.m
index 41709be..f1d0cf1 100644
--- a/test/Analysis/objc-for.m
+++ b/test/Analysis/objc-for.m
@@ -1,6 +1,7 @@
 // RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.cocoa.Loops,debug.ExprInspection -verify %s
 
 void clang_analyzer_eval(int);
+void clang_analyzer_warnIfReached();
 
 #define nil ((id)0)
 
@@ -20,11 +21,13 @@
 @interface NSArray : NSObject <NSFastEnumeration>
 - (NSUInteger)count;
 - (NSEnumerator *)objectEnumerator;
++ (NSArray *)arrayWithObjects:(const id [])objects count:(NSUInteger)count;
 @end
 
 @interface NSDictionary : NSObject <NSFastEnumeration>
 - (NSUInteger)count;
 - (id)objectForKey:(id)key;
++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id /* <NSCopying> */ [])keys count:(NSUInteger)count;
 @end
 
 @interface NSDictionary (SomeCategory)
@@ -324,3 +327,19 @@
   for (id key in array)
     clang_analyzer_eval(0); // expected-warning{{FALSE}}
 }
+
+NSArray *globalArray;
+NSDictionary *globalDictionary;
+void boxedArrayEscape(NSMutableArray *array) {
+  if ([array count])
+    return;
+  globalArray = @[array];
+  for (id key in array)
+    clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+
+  if ([array count])
+    return;
+  globalDictionary = @{ @"array" : array };
+  for (id key in array)
+    clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
+}
diff --git a/test/Analysis/pointer-arithmetic.c b/test/Analysis/pointer-arithmetic.c
new file mode 100644
index 0000000..575dfff
--- /dev/null
+++ b/test/Analysis/pointer-arithmetic.c
@@ -0,0 +1,30 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -verify %s
+
+int test1() {
+  int *p = (int *)sizeof(int);
+  p -= 1;
+  return *p; // expected-warning {{Dereference of null pointer}}
+}
+
+int test2() {
+  int *p = (int *)sizeof(int);
+  p -= 2;
+  p += 1;
+  return *p; // expected-warning {{Dereference of null pointer}}
+}
+
+int test3() {
+  int *p = (int *)sizeof(int);
+  p++;
+  p--;
+  p--;
+  return *p; // expected-warning {{Dereference of null pointer}}
+}
+
+int test4() {
+  // This is a special case where pointer arithmetic is not calculated to
+  // preserve useful warnings on dereferences of null pointers.
+  int *p = 0;
+  p += 1;
+  return *p; // expected-warning {{Dereference of null pointer}}
+}
diff --git a/test/Analysis/ptr-arith.c b/test/Analysis/ptr-arith.c
index b78ec50..93cb4ee 100644
--- a/test/Analysis/ptr-arith.c
+++ b/test/Analysis/ptr-arith.c
@@ -342,3 +342,8 @@
   clang_analyzer_eval(*ptr3 == 'a'); // expected-warning{{UNKNOWN}}
 }
 
+void test_no_crash_on_pointer_to_label() {
+  char *a = &&label;
+  a[0] = 0;
+label:;
+}
diff --git a/test/Analysis/ptr-arith.cpp b/test/Analysis/ptr-arith.cpp
index e1860f4..1eec83c 100644
--- a/test/Analysis/ptr-arith.cpp
+++ b/test/Analysis/ptr-arith.cpp
@@ -98,3 +98,22 @@
   int a[5][5];
    *(*(a+1)+2) = 2;
 }
+
+unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
+  auto N = End - Begin;
+  if (Begin)
+    return 0;
+  return N;
+}
+
+// Bug 34309
+bool ptrAsIntegerSubtractionNoCrash(__UINTPTR_TYPE__ x, char *p) {
+  __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
+  return y == x;
+}
+
+// Bug 34374
+bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
+  auto n = p - reinterpret_cast<char*>((__UINTPTR_TYPE__)1);
+  return n == m;
+}
diff --git a/test/Analysis/retain-release-inline.m b/test/Analysis/retain-release-inline.m
index 388c55f..4fe6bca 100644
--- a/test/Analysis/retain-release-inline.m
+++ b/test/Analysis/retain-release-inline.m
@@ -299,15 +299,18 @@
   bar(s);
 }
 
-__attribute__((cf_returns_retained)) isl_basic_map *isl_basic_map_cow(__attribute__((cf_consumed)) isl_basic_map *bmap);
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_cow(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap);
 void free(void *);
 
+void callee_side_parameter_checking_leak(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) { // expected-warning {{Potential leak of an object}}
+}
+
 // As 'isl_basic_map_free' is annotated with 'rc_ownership_trusted_implementation', RetainCountChecker trusts its
 // implementation and doesn't analyze its body. If the annotation 'rc_ownership_trusted_implementation' is removed,
 // a leak warning is raised by RetainCountChecker as the analyzer is unable to detect a decrement in the reference
 // count of 'bmap' along the path in 'isl_basic_map_free' assuming the predicate of the second 'if' branch to be
 // true or assuming both the predicates in the function to be false.
-__attribute__((annotate("rc_ownership_trusted_implementation"))) isl_basic_map *isl_basic_map_free(__attribute__((cf_consumed)) isl_basic_map *bmap) {
+__attribute__((annotate("rc_ownership_trusted_implementation"))) isl_basic_map *isl_basic_map_free(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
   if (!bmap)
     return NULL;
 
@@ -322,7 +325,7 @@
 // implementation and doesn't analyze its body. If that annotation is removed, a 'use-after-release' warning might
 // be raised by RetainCountChecker as the pointer which is passed as an argument to this function and the pointer
 // which is returned from the function point to the same memory location.
-__attribute__((annotate("rc_ownership_trusted_implementation"))) __attribute__((cf_returns_retained)) isl_basic_map *isl_basic_map_copy(isl_basic_map *bmap) {
+__attribute__((annotate("rc_ownership_trusted_implementation"))) __attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_copy(isl_basic_map *bmap) {
   if (!bmap)
     return NULL;
 
@@ -330,7 +333,7 @@
   return bmap;
 }
 
-void test_use_after_release_with_trusted_implementation_annotate_attribute(__attribute__((cf_consumed)) isl_basic_map *bmap) {
+void test_use_after_release_with_trusted_implementation_annotate_attribute(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
   // After this call, 'bmap' has a +1 reference count.
   bmap = isl_basic_map_cow(bmap);
   // After the call to 'isl_basic_map_copy', 'bmap' has a +1 reference count.
@@ -341,13 +344,44 @@
   isl_basic_map_free(temp);
 }
 
-void test_leak_with_trusted_implementation_annotate_attribute(__attribute__((cf_consumed)) isl_basic_map *bmap) {
+void test_leak_with_trusted_implementation_annotate_attribute(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
   // After this call, 'bmap' has a +1 reference count.
   bmap = isl_basic_map_cow(bmap); // no-warning
   // After this call, 'bmap' has a +0 reference count.
   isl_basic_map_free(bmap);
 }
 
+void callee_side_parameter_checking_incorrect_rc_decrement(isl_basic_map *bmap) {
+  isl_basic_map_free(bmap); // expected-warning {{Incorrect decrement of the reference count}}
+}
+
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *callee_side_parameter_checking_return_notowned_object(isl_basic_map *bmap) {
+  return bmap; // expected-warning {{Object with a +0 retain count returned to caller where a +1 (owning) retain count is expected}}
+}
+
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *callee_side_parameter_checking_assign_consumed_parameter_leak_return(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap1, __attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap2) { // expected-warning {{Potential leak of an object}}
+  bmap1 = bmap2;
+  isl_basic_map_free(bmap2);
+  return bmap1;
+}
+
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *callee_side_parameter_checking_assign_consumed_parameter_leak(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap1, __attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap2) { // expected-warning {{Potential leak of an object}}
+  bmap1 = bmap2;
+  isl_basic_map_free(bmap1);
+  return bmap2;
+}
+
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *error_path_leak(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap1, __attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap2) { // expected-warning {{Potential leak of an object}}
+  bmap1 = isl_basic_map_cow(bmap1);
+  if (!bmap1 || !bmap2)
+    goto error;
+
+  isl_basic_map_free(bmap2);
+  return bmap1;
+error:
+  return isl_basic_map_free(bmap1);
+}
+
 //===----------------------------------------------------------------------===//
 // Test returning retained and not-retained values.
 //===----------------------------------------------------------------------===//
diff --git a/test/Analysis/retain-release-safe.c b/test/Analysis/retain-release-safe.c
new file mode 100644
index 0000000..de74355
--- /dev/null
+++ b/test/Analysis/retain-release-safe.c
@@ -0,0 +1,72 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,osx.coreFoundation.CFRetainRelease,osx.cocoa.RetainCount -verify %s
+
+#pragma clang arc_cf_code_audited begin
+typedef const void * CFTypeRef;
+extern CFTypeRef CFRetain(CFTypeRef cf);
+extern void CFRelease(CFTypeRef cf);
+#pragma clang arc_cf_code_audited end
+
+#define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
+#define CF_CONSUMED __attribute__((cf_consumed))
+
+extern CFTypeRef CFCreate() CF_RETURNS_RETAINED;
+
+// A "safe" variant of CFRetain that doesn't crash when a null pointer is
+// retained. This is often defined by users in a similar manner. The
+// CF_RETURNS_RETAINED annotation is misleading here, because the function
+// is not supposed to return an object with a +1 retain count. Instead, it
+// is supposed to return an object with +(N+1) retain count, where N is
+// the original retain count of 'cf'. However, there is no good annotation
+// to use in this case, and it is pointless to provide such annotation
+// because the only use cases would be CFRetain and SafeCFRetain.
+// So instead we teach the analyzer to be able to accept such code
+// and ignore the misplaced annotation.
+CFTypeRef SafeCFRetain(CFTypeRef cf) CF_RETURNS_RETAINED {
+  if (cf) {
+    return CFRetain(cf);
+  }
+  return cf;
+}
+
+// A "safe" variant of CFRelease that doesn't crash when a null pointer is
+// released. The CF_CONSUMED annotation seems reasonable here.
+void SafeCFRelease(CFTypeRef CF_CONSUMED cf) {
+  if (cf)
+    CFRelease(cf); // no-warning (when inlined)
+}
+
+void escape(CFTypeRef cf);
+
+void makeSureTestsWork() {
+  CFTypeRef cf = CFCreate();
+  CFRelease(cf);
+  CFRelease(cf); // expected-warning{{Reference-counted object is used after it is released}}
+}
+
+// Make sure we understand that the second SafeCFRetain doesn't return an
+// object with +1 retain count, which we won't be able to release twice.
+void falseOverrelease(CFTypeRef cf) {
+  SafeCFRetain(cf);
+  SafeCFRetain(cf);
+  SafeCFRelease(cf);
+  SafeCFRelease(cf); // no-warning after inlining this.
+}
+
+// Regular CFRelease() should behave similarly.
+void sameWithNormalRelease(CFTypeRef cf) {
+  SafeCFRetain(cf);
+  SafeCFRetain(cf);
+  CFRelease(cf);
+  CFRelease(cf); // no-warning
+}
+
+// Make sure we understand that the second SafeCFRetain doesn't return an
+// object with +1 retain count, which would no longer be owned by us after
+// it escapes to escape() and released once.
+void falseReleaseNotOwned(CFTypeRef cf) {
+  SafeCFRetain(cf);
+  SafeCFRetain(cf);
+  escape(cf);
+  SafeCFRelease(cf);
+  SafeCFRelease(cf); // no-warning after inlining this.
+}
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 29af194..8e4dcb5 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -325,6 +325,9 @@
 
 extern
 void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
+typedef struct {
+  int ref;
+} isl_basic_map;
 
 //===----------------------------------------------------------------------===//
 // Test cases.
@@ -574,6 +577,14 @@
   }
 }
 
+__attribute__((annotate("rc_ownership_returns_retained"))) isl_basic_map *isl_basic_map_cow(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap);
+
+// Test custom diagnostics for generalized objects.
+void f18(__attribute__((annotate("rc_ownership_consumed"))) isl_basic_map *bmap) {
+  // After this call, 'bmap' has a +1 reference count.
+  bmap = isl_basic_map_cow(bmap); // expected-warning {{Potential leak of an object}}
+}
+
 // Test basic tracking of ivars associated with 'self'.  For the retain/release
 // checker we currently do not want to flag leaks associated with stores
 // of tracked objects to ivars.
diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm
index c981700..ac83c1a 100644
--- a/test/Analysis/retain-release.mm
+++ b/test/Analysis/retain-release.mm
@@ -461,3 +461,12 @@
 	}
 }
 
+// rdar://34210609
+void _() { _(); }; // no-warning
+
+// Do not assume that IOBSDNameMatching increments a reference counter,
+// unless return type is CFMutableDictionaryRef.
+void* IOBSDNameMatching();
+void rdar33832412() {
+  void* x = IOBSDNameMatching(); // no-warning
+}
diff --git a/test/Analysis/string-with-signedness.c b/test/Analysis/string-with-signedness.c
new file mode 100644
index 0000000..1b00971
--- /dev/null
+++ b/test/Analysis/string-with-signedness.c
@@ -0,0 +1,10 @@
+// RUN: %clang_analyze_cc1 -Wno-incompatible-library-redeclaration -analyzer-checker=core,unix.cstring,alpha.unix.cstring -verify %s
+
+// expected-no-diagnostics
+
+void *strcpy(unsigned char *, unsigned char *);
+
+unsigned char a, b;
+void testUnsignedStrcpy() {
+  strcpy(&a, &b);
+}
diff --git a/test/Analysis/taint-tester.c b/test/Analysis/taint-tester.c
index 1b59e7b..3a8cc18 100644
--- a/test/Analysis/taint-tester.c
+++ b/test/Analysis/taint-tester.c
@@ -189,3 +189,10 @@
 
 }
 
+char *pointer1;
+void *pointer2;
+void noCrashTest() {
+  if (!*pointer1) {
+    __builtin___memcpy_chk(pointer2, pointer1, 0, 0); // no-crash
+  }
+}
diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c
index 481f545..9126e1b 100644
--- a/test/Analysis/unix-fns.c
+++ b/test/Analysis/unix-fns.c
@@ -34,11 +34,40 @@
  struct dispatch_disk_s *_ddisk;
 } dispatch_object_t __attribute__((__transparent_union__));
 typedef void (^dispatch_block_t)(void);
-typedef long dispatch_once_t;
 typedef struct dispatch_queue_s *dispatch_queue_t;
-void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
 void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
 
+typedef long dispatch_once_t;
+
+extern
+__attribute__((__nonnull__))
+__attribute__((__nothrow__))
+void dispatch_once(dispatch_once_t *predicate,
+                   __attribute__((__noescape__)) dispatch_block_t block);
+
+// Inlined fast-path dispatch_once defers to the real dispatch_once
+// on the slow path.
+static
+__inline__
+__attribute__((__always_inline__))
+__attribute__((__nonnull__))
+__attribute__((__nothrow__))
+void _dispatch_once(dispatch_once_t *predicate,
+                    __attribute__((__noescape__)) dispatch_block_t block)
+{
+ if (__builtin_expect((*predicate), (~0l)) != ~0l) {
+  dispatch_once(predicate, block);
+ } else {
+  __asm__ __volatile__("" ::: "memory");
+ }
+ __builtin_assume(*predicate == ~0l);
+}
+
+// Macro so that user calls to dispatch_once() call the inlined fast-path
+// variant.
+#undef dispatch_once
+#define dispatch_once _dispatch_once
+
 #ifndef O_CREAT
 #define O_CREAT 0x0200
 #define O_RDONLY 0x0000
@@ -181,16 +210,6 @@
   }
 }
 
-// Test dispatch_once being a macro that wraps a call to _dispatch_once, which in turn
-// calls the real dispatch_once.
-
-static inline void _dispatch_once(dispatch_once_t *predicate, dispatch_block_t block)
-{
-  dispatch_once(predicate, block);
-}
-
-#define dispatch_once _dispatch_once
-
 void test_dispatch_once_in_macro() {
   dispatch_once_t pred = 0;
   dispatch_once(&pred, ^(){});  // expected-warning {{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}}
@@ -206,7 +225,7 @@
   });
 }
 
-// Test inlining if dispatch_once.
+// Test inlining of dispatch_once.
 void test_inline_dispatch_once() {
   static dispatch_once_t pred;
   int *p = 0;
@@ -215,6 +234,17 @@
   });
 }
 
+// Make sure code after call to dispatch once is reached.
+void test_inline_dispatch_once_reachable() {
+  static dispatch_once_t pred;
+  __block int *p;
+  dispatch_once(&pred, ^(void) {
+      p = 0;
+  });
+
+  *p = 7; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}}
+}
+
 // CHECK: <key>diagnostics</key>
 // CHECK-NEXT: <array>
 // CHECK-NEXT:  <dict>
@@ -228,12 +258,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>51</integer>
+// CHECK-NEXT:           <key>line</key><integer>80</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>51</integer>
+// CHECK-NEXT:           <key>line</key><integer>80</integer>
 // CHECK-NEXT:           <key>col</key><integer>5</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -241,12 +271,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>line</key><integer>82</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>line</key><integer>82</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -262,12 +292,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>line</key><integer>82</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>line</key><integer>82</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -275,12 +305,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>line</key><integer>82</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>line</key><integer>82</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -292,7 +322,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>53</integer>
+// CHECK-NEXT:      <key>line</key><integer>82</integer>
 // CHECK-NEXT:      <key>col</key><integer>7</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -300,12 +330,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>53</integer>
+// CHECK-NEXT:         <key>line</key><integer>82</integer>
 // CHECK-NEXT:         <key>col</key><integer>7</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>53</integer>
+// CHECK-NEXT:         <key>line</key><integer>82</integer>
 // CHECK-NEXT:         <key>col</key><integer>9</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -325,12 +355,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>line</key><integer>82</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>53</integer>
+// CHECK-NEXT:           <key>line</key><integer>82</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -338,12 +368,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>line</key><integer>85</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>line</key><integer>85</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -359,12 +389,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>line</key><integer>85</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>line</key><integer>85</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -372,12 +402,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>line</key><integer>85</integer>
 // CHECK-NEXT:           <key>col</key><integer>8</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>56</integer>
+// CHECK-NEXT:           <key>line</key><integer>85</integer>
 // CHECK-NEXT:           <key>col</key><integer>11</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -389,7 +419,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>56</integer>
+// CHECK-NEXT:      <key>line</key><integer>85</integer>
 // CHECK-NEXT:      <key>col</key><integer>8</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -397,12 +427,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>56</integer>
+// CHECK-NEXT:         <key>line</key><integer>85</integer>
 // CHECK-NEXT:         <key>col</key><integer>19</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>56</integer>
+// CHECK-NEXT:         <key>line</key><integer>85</integer>
 // CHECK-NEXT:         <key>col</key><integer>25</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -426,7 +456,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>6</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>56</integer>
+// CHECK-NEXT:   <key>line</key><integer>85</integer>
 // CHECK-NEXT:   <key>col</key><integer>8</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -442,12 +472,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>62</integer>
+// CHECK-NEXT:           <key>line</key><integer>91</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>62</integer>
+// CHECK-NEXT:           <key>line</key><integer>91</integer>
 // CHECK-NEXT:           <key>col</key><integer>5</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -455,12 +485,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>line</key><integer>93</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>line</key><integer>93</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -476,12 +506,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>line</key><integer>93</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>line</key><integer>93</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -489,12 +519,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>line</key><integer>93</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>line</key><integer>93</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -506,7 +536,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>64</integer>
+// CHECK-NEXT:      <key>line</key><integer>93</integer>
 // CHECK-NEXT:      <key>col</key><integer>7</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -514,12 +544,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>64</integer>
+// CHECK-NEXT:         <key>line</key><integer>93</integer>
 // CHECK-NEXT:         <key>col</key><integer>7</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>64</integer>
+// CHECK-NEXT:         <key>line</key><integer>93</integer>
 // CHECK-NEXT:         <key>col</key><integer>9</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -539,12 +569,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>line</key><integer>93</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>64</integer>
+// CHECK-NEXT:           <key>line</key><integer>93</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -552,12 +582,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>line</key><integer>96</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>line</key><integer>96</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -573,12 +603,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>line</key><integer>96</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>line</key><integer>96</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -586,12 +616,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>line</key><integer>96</integer>
 // CHECK-NEXT:           <key>col</key><integer>8</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>67</integer>
+// CHECK-NEXT:           <key>line</key><integer>96</integer>
 // CHECK-NEXT:           <key>col</key><integer>13</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -603,7 +633,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>67</integer>
+// CHECK-NEXT:      <key>line</key><integer>96</integer>
 // CHECK-NEXT:      <key>col</key><integer>8</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -611,12 +641,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>67</integer>
+// CHECK-NEXT:         <key>line</key><integer>96</integer>
 // CHECK-NEXT:         <key>col</key><integer>44</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>67</integer>
+// CHECK-NEXT:         <key>line</key><integer>96</integer>
 // CHECK-NEXT:         <key>col</key><integer>50</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -640,7 +670,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>6</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>67</integer>
+// CHECK-NEXT:   <key>line</key><integer>96</integer>
 // CHECK-NEXT:   <key>col</key><integer>8</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -656,12 +686,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>73</integer>
+// CHECK-NEXT:           <key>line</key><integer>102</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>73</integer>
+// CHECK-NEXT:           <key>line</key><integer>102</integer>
 // CHECK-NEXT:           <key>col</key><integer>17</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -669,12 +699,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -690,12 +720,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -703,12 +733,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>8</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>9</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -724,12 +754,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>8</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>9</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -737,12 +767,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>52</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>74</integer>
+// CHECK-NEXT:           <key>line</key><integer>103</integer>
 // CHECK-NEXT:           <key>col</key><integer>64</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -754,7 +784,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>74</integer>
+// CHECK-NEXT:      <key>line</key><integer>103</integer>
 // CHECK-NEXT:      <key>col</key><integer>52</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -762,12 +792,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>74</integer>
+// CHECK-NEXT:         <key>line</key><integer>103</integer>
 // CHECK-NEXT:         <key>col</key><integer>66</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>74</integer>
+// CHECK-NEXT:         <key>line</key><integer>103</integer>
 // CHECK-NEXT:         <key>col</key><integer>72</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -791,7 +821,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>2</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>74</integer>
+// CHECK-NEXT:   <key>line</key><integer>103</integer>
 // CHECK-NEXT:   <key>col</key><integer>52</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -807,12 +837,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>84</integer>
+// CHECK-NEXT:           <key>line</key><integer>113</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>84</integer>
+// CHECK-NEXT:           <key>line</key><integer>113</integer>
 // CHECK-NEXT:           <key>col</key><integer>16</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -820,12 +850,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>85</integer>
+// CHECK-NEXT:           <key>line</key><integer>114</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>85</integer>
+// CHECK-NEXT:           <key>line</key><integer>114</integer>
 // CHECK-NEXT:           <key>col</key><integer>14</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -837,7 +867,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>85</integer>
+// CHECK-NEXT:      <key>line</key><integer>114</integer>
 // CHECK-NEXT:      <key>col</key><integer>3</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -845,12 +875,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>85</integer>
+// CHECK-NEXT:         <key>line</key><integer>114</integer>
 // CHECK-NEXT:         <key>col</key><integer>16</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>85</integer>
+// CHECK-NEXT:         <key>line</key><integer>114</integer>
 // CHECK-NEXT:         <key>col</key><integer>20</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -874,7 +904,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>2</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>85</integer>
+// CHECK-NEXT:   <key>line</key><integer>114</integer>
 // CHECK-NEXT:   <key>col</key><integer>3</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -890,12 +920,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>94</integer>
+// CHECK-NEXT:           <key>line</key><integer>123</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>94</integer>
+// CHECK-NEXT:           <key>line</key><integer>123</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -903,12 +933,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>94</integer>
+// CHECK-NEXT:           <key>line</key><integer>123</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>94</integer>
+// CHECK-NEXT:           <key>line</key><integer>123</integer>
 // CHECK-NEXT:           <key>col</key><integer>20</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -920,7 +950,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>94</integer>
+// CHECK-NEXT:      <key>line</key><integer>123</integer>
 // CHECK-NEXT:      <key>col</key><integer>15</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -928,12 +958,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>94</integer>
+// CHECK-NEXT:         <key>line</key><integer>123</integer>
 // CHECK-NEXT:         <key>col</key><integer>22</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>94</integer>
+// CHECK-NEXT:         <key>line</key><integer>123</integer>
 // CHECK-NEXT:         <key>col</key><integer>22</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -957,7 +987,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>94</integer>
+// CHECK-NEXT:   <key>line</key><integer>123</integer>
 // CHECK-NEXT:   <key>col</key><integer>15</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -973,12 +1003,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>106</integer>
+// CHECK-NEXT:           <key>line</key><integer>135</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>106</integer>
+// CHECK-NEXT:           <key>line</key><integer>135</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -986,12 +1016,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>106</integer>
+// CHECK-NEXT:           <key>line</key><integer>135</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>106</integer>
+// CHECK-NEXT:           <key>line</key><integer>135</integer>
 // CHECK-NEXT:           <key>col</key><integer>20</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1003,7 +1033,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>106</integer>
+// CHECK-NEXT:      <key>line</key><integer>135</integer>
 // CHECK-NEXT:      <key>col</key><integer>15</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1011,12 +1041,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>106</integer>
+// CHECK-NEXT:         <key>line</key><integer>135</integer>
 // CHECK-NEXT:         <key>col</key><integer>22</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>106</integer>
+// CHECK-NEXT:         <key>line</key><integer>135</integer>
 // CHECK-NEXT:         <key>col</key><integer>22</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1040,7 +1070,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>106</integer>
+// CHECK-NEXT:   <key>line</key><integer>135</integer>
 // CHECK-NEXT:   <key>col</key><integer>15</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -1056,12 +1086,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>112</integer>
+// CHECK-NEXT:           <key>line</key><integer>141</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>112</integer>
+// CHECK-NEXT:           <key>line</key><integer>141</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1069,12 +1099,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>112</integer>
+// CHECK-NEXT:           <key>line</key><integer>141</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>112</integer>
+// CHECK-NEXT:           <key>line</key><integer>141</integer>
 // CHECK-NEXT:           <key>col</key><integer>20</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1086,7 +1116,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>112</integer>
+// CHECK-NEXT:      <key>line</key><integer>141</integer>
 // CHECK-NEXT:      <key>col</key><integer>15</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1094,12 +1124,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>112</integer>
+// CHECK-NEXT:         <key>line</key><integer>141</integer>
 // CHECK-NEXT:         <key>col</key><integer>26</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>112</integer>
+// CHECK-NEXT:         <key>line</key><integer>141</integer>
 // CHECK-NEXT:         <key>col</key><integer>26</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1123,7 +1153,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>112</integer>
+// CHECK-NEXT:   <key>line</key><integer>141</integer>
 // CHECK-NEXT:   <key>col</key><integer>15</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -1139,12 +1169,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>124</integer>
+// CHECK-NEXT:           <key>line</key><integer>153</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>124</integer>
+// CHECK-NEXT:           <key>line</key><integer>153</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1152,12 +1182,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>124</integer>
+// CHECK-NEXT:           <key>line</key><integer>153</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>124</integer>
+// CHECK-NEXT:           <key>line</key><integer>153</integer>
 // CHECK-NEXT:           <key>col</key><integer>21</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1169,7 +1199,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>124</integer>
+// CHECK-NEXT:      <key>line</key><integer>153</integer>
 // CHECK-NEXT:      <key>col</key><integer>15</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1177,12 +1207,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>124</integer>
+// CHECK-NEXT:         <key>line</key><integer>153</integer>
 // CHECK-NEXT:         <key>col</key><integer>28</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>124</integer>
+// CHECK-NEXT:         <key>line</key><integer>153</integer>
 // CHECK-NEXT:         <key>col</key><integer>28</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1206,7 +1236,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>124</integer>
+// CHECK-NEXT:   <key>line</key><integer>153</integer>
 // CHECK-NEXT:   <key>col</key><integer>15</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -1222,12 +1252,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>130</integer>
+// CHECK-NEXT:           <key>line</key><integer>159</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>130</integer>
+// CHECK-NEXT:           <key>line</key><integer>159</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1235,12 +1265,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>130</integer>
+// CHECK-NEXT:           <key>line</key><integer>159</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>130</integer>
+// CHECK-NEXT:           <key>line</key><integer>159</integer>
 // CHECK-NEXT:           <key>col</key><integer>22</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1252,7 +1282,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>130</integer>
+// CHECK-NEXT:      <key>line</key><integer>159</integer>
 // CHECK-NEXT:      <key>col</key><integer>15</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1260,12 +1290,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>130</integer>
+// CHECK-NEXT:         <key>line</key><integer>159</integer>
 // CHECK-NEXT:         <key>col</key><integer>29</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>130</integer>
+// CHECK-NEXT:         <key>line</key><integer>159</integer>
 // CHECK-NEXT:         <key>col</key><integer>29</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1289,7 +1319,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>130</integer>
+// CHECK-NEXT:   <key>line</key><integer>159</integer>
 // CHECK-NEXT:   <key>col</key><integer>15</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -1305,12 +1335,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>148</integer>
+// CHECK-NEXT:           <key>line</key><integer>177</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>148</integer>
+// CHECK-NEXT:           <key>line</key><integer>177</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1318,12 +1348,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>148</integer>
+// CHECK-NEXT:           <key>line</key><integer>177</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>148</integer>
+// CHECK-NEXT:           <key>line</key><integer>177</integer>
 // CHECK-NEXT:           <key>col</key><integer>20</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1335,7 +1365,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>148</integer>
+// CHECK-NEXT:      <key>line</key><integer>177</integer>
 // CHECK-NEXT:      <key>col</key><integer>15</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1343,12 +1373,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>148</integer>
+// CHECK-NEXT:         <key>line</key><integer>177</integer>
 // CHECK-NEXT:         <key>col</key><integer>22</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>148</integer>
+// CHECK-NEXT:         <key>line</key><integer>177</integer>
 // CHECK-NEXT:         <key>col</key><integer>22</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1372,7 +1402,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>148</integer>
+// CHECK-NEXT:   <key>line</key><integer>177</integer>
 // CHECK-NEXT:   <key>col</key><integer>15</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -1388,12 +1418,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>160</integer>
+// CHECK-NEXT:           <key>line</key><integer>189</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>160</integer>
+// CHECK-NEXT:           <key>line</key><integer>189</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1401,12 +1431,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>160</integer>
+// CHECK-NEXT:           <key>line</key><integer>189</integer>
 // CHECK-NEXT:           <key>col</key><integer>16</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>160</integer>
+// CHECK-NEXT:           <key>line</key><integer>189</integer>
 // CHECK-NEXT:           <key>col</key><integer>31</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1418,7 +1448,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>160</integer>
+// CHECK-NEXT:      <key>line</key><integer>189</integer>
 // CHECK-NEXT:      <key>col</key><integer>16</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1426,12 +1456,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>160</integer>
+// CHECK-NEXT:         <key>line</key><integer>189</integer>
 // CHECK-NEXT:         <key>col</key><integer>33</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>160</integer>
+// CHECK-NEXT:         <key>line</key><integer>189</integer>
 // CHECK-NEXT:         <key>col</key><integer>33</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1455,7 +1485,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>160</integer>
+// CHECK-NEXT:   <key>line</key><integer>189</integer>
 // CHECK-NEXT:   <key>col</key><integer>16</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -1471,12 +1501,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>172</integer>
+// CHECK-NEXT:           <key>line</key><integer>201</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>172</integer>
+// CHECK-NEXT:           <key>line</key><integer>201</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1484,12 +1514,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>172</integer>
+// CHECK-NEXT:           <key>line</key><integer>201</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>172</integer>
+// CHECK-NEXT:           <key>line</key><integer>201</integer>
 // CHECK-NEXT:           <key>col</key><integer>20</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1501,7 +1531,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>172</integer>
+// CHECK-NEXT:      <key>line</key><integer>201</integer>
 // CHECK-NEXT:      <key>col</key><integer>15</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1509,12 +1539,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>172</integer>
+// CHECK-NEXT:         <key>line</key><integer>201</integer>
 // CHECK-NEXT:         <key>col</key><integer>22</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>172</integer>
+// CHECK-NEXT:         <key>line</key><integer>201</integer>
 // CHECK-NEXT:         <key>col</key><integer>22</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1538,7 +1568,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>1</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>172</integer>
+// CHECK-NEXT:   <key>line</key><integer>201</integer>
 // CHECK-NEXT:   <key>col</key><integer>15</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -1554,12 +1584,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>195</integer>
+// CHECK-NEXT:           <key>line</key><integer>214</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>195</integer>
+// CHECK-NEXT:           <key>line</key><integer>214</integer>
 // CHECK-NEXT:           <key>col</key><integer>17</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1567,12 +1597,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>196</integer>
+// CHECK-NEXT:           <key>line</key><integer>215</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>196</integer>
+// CHECK-NEXT:           <key>line</key><integer>215</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1584,7 +1614,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>196</integer>
+// CHECK-NEXT:      <key>line</key><integer>215</integer>
 // CHECK-NEXT:      <key>col</key><integer>3</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1592,12 +1622,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>196</integer>
+// CHECK-NEXT:         <key>line</key><integer>215</integer>
 // CHECK-NEXT:         <key>col</key><integer>17</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>196</integer>
+// CHECK-NEXT:         <key>line</key><integer>215</integer>
 // CHECK-NEXT:         <key>col</key><integer>21</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1621,7 +1651,7 @@
 // CHECK-NEXT:  <key>issue_hash_function_offset</key><string>2</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>196</integer>
+// CHECK-NEXT:   <key>line</key><integer>215</integer>
 // CHECK-NEXT:   <key>col</key><integer>3</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -1633,7 +1663,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>201</integer>
+// CHECK-NEXT:      <key>line</key><integer>220</integer>
 // CHECK-NEXT:      <key>col</key><integer>3</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1641,12 +1671,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>201</integer>
+// CHECK-NEXT:         <key>line</key><integer>220</integer>
 // CHECK-NEXT:         <key>col</key><integer>3</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>201</integer>
+// CHECK-NEXT:         <key>line</key><integer>220</integer>
 // CHECK-NEXT:         <key>col</key><integer>8</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1666,12 +1696,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>201</integer>
+// CHECK-NEXT:           <key>line</key><integer>220</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>201</integer>
+// CHECK-NEXT:           <key>line</key><integer>220</integer>
 // CHECK-NEXT:           <key>col</key><integer>5</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1679,12 +1709,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>line</key><integer>221</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>line</key><integer>221</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1700,12 +1730,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>line</key><integer>221</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>line</key><integer>221</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1713,12 +1743,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>line</key><integer>221</integer>
 // CHECK-NEXT:           <key>col</key><integer>24</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>line</key><integer>221</integer>
 // CHECK-NEXT:           <key>col</key><integer>24</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1730,7 +1760,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>202</integer>
+// CHECK-NEXT:      <key>line</key><integer>221</integer>
 // CHECK-NEXT:      <key>col</key><integer>24</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1738,12 +1768,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>202</integer>
+// CHECK-NEXT:         <key>line</key><integer>221</integer>
 // CHECK-NEXT:         <key>col</key><integer>24</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>206</integer>
+// CHECK-NEXT:         <key>line</key><integer>225</integer>
 // CHECK-NEXT:         <key>col</key><integer>3</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1759,7 +1789,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>202</integer>
+// CHECK-NEXT:      <key>line</key><integer>221</integer>
 // CHECK-NEXT:      <key>col</key><integer>3</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1767,12 +1797,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>202</integer>
+// CHECK-NEXT:         <key>line</key><integer>221</integer>
 // CHECK-NEXT:         <key>col</key><integer>3</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>206</integer>
+// CHECK-NEXT:         <key>line</key><integer>225</integer>
 // CHECK-NEXT:         <key>col</key><integer>4</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1788,7 +1818,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>202</integer>
+// CHECK-NEXT:      <key>line</key><integer>221</integer>
 // CHECK-NEXT:      <key>col</key><integer>3</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1796,12 +1826,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>202</integer>
+// CHECK-NEXT:         <key>line</key><integer>221</integer>
 // CHECK-NEXT:         <key>col</key><integer>3</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>206</integer>
+// CHECK-NEXT:         <key>line</key><integer>225</integer>
 // CHECK-NEXT:         <key>col</key><integer>4</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1817,7 +1847,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>202</integer>
+// CHECK-NEXT:      <key>line</key><integer>221</integer>
 // CHECK-NEXT:      <key>col</key><integer>24</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1835,12 +1865,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>line</key><integer>221</integer>
 // CHECK-NEXT:           <key>col</key><integer>24</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>202</integer>
+// CHECK-NEXT:           <key>line</key><integer>221</integer>
 // CHECK-NEXT:           <key>col</key><integer>24</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1848,12 +1878,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>line</key><integer>222</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>line</key><integer>222</integer>
 // CHECK-NEXT:           <key>col</key><integer>5</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1869,12 +1899,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>line</key><integer>222</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>line</key><integer>222</integer>
 // CHECK-NEXT:           <key>col</key><integer>5</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1882,12 +1912,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>line</key><integer>222</integer>
 // CHECK-NEXT:           <key>col</key><integer>8</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>line</key><integer>222</integer>
 // CHECK-NEXT:           <key>col</key><integer>8</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1899,7 +1929,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>203</integer>
+// CHECK-NEXT:      <key>line</key><integer>222</integer>
 // CHECK-NEXT:      <key>col</key><integer>8</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -1907,12 +1937,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>203</integer>
+// CHECK-NEXT:         <key>line</key><integer>222</integer>
 // CHECK-NEXT:         <key>col</key><integer>8</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>203</integer>
+// CHECK-NEXT:         <key>line</key><integer>222</integer>
 // CHECK-NEXT:         <key>col</key><integer>8</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -1932,12 +1962,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>line</key><integer>222</integer>
 // CHECK-NEXT:           <key>col</key><integer>8</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>203</integer>
+// CHECK-NEXT:           <key>line</key><integer>222</integer>
 // CHECK-NEXT:           <key>col</key><integer>8</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1945,12 +1975,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>line</key><integer>223</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>line</key><integer>223</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1966,12 +1996,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>line</key><integer>223</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>line</key><integer>223</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1979,12 +2009,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>line</key><integer>223</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>204</integer>
+// CHECK-NEXT:           <key>line</key><integer>223</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -1996,7 +2026,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>204</integer>
+// CHECK-NEXT:      <key>line</key><integer>223</integer>
 // CHECK-NEXT:      <key>col</key><integer>6</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -2004,12 +2034,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>204</integer>
+// CHECK-NEXT:         <key>line</key><integer>223</integer>
 // CHECK-NEXT:         <key>col</key><integer>4</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>204</integer>
+// CHECK-NEXT:         <key>line</key><integer>223</integer>
 // CHECK-NEXT:         <key>col</key><integer>4</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -2030,7 +2060,7 @@
 // CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>5d3f4c433004c7a6d4a06aa30cc3ea85</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>204</integer>
+// CHECK-NEXT:   <key>line</key><integer>223</integer>
 // CHECK-NEXT:   <key>col</key><integer>6</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
@@ -2046,12 +2076,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>211</integer>
+// CHECK-NEXT:           <key>line</key><integer>230</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>211</integer>
+// CHECK-NEXT:           <key>line</key><integer>230</integer>
 // CHECK-NEXT:           <key>col</key><integer>8</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2059,12 +2089,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>212</integer>
+// CHECK-NEXT:           <key>line</key><integer>231</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>212</integer>
+// CHECK-NEXT:           <key>line</key><integer>231</integer>
 // CHECK-NEXT:           <key>col</key><integer>5</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2076,7 +2106,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>212</integer>
+// CHECK-NEXT:      <key>line</key><integer>231</integer>
 // CHECK-NEXT:      <key>col</key><integer>3</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -2084,12 +2114,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>212</integer>
+// CHECK-NEXT:         <key>line</key><integer>231</integer>
 // CHECK-NEXT:         <key>col</key><integer>3</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>212</integer>
+// CHECK-NEXT:         <key>line</key><integer>231</integer>
 // CHECK-NEXT:         <key>col</key><integer>8</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -2109,12 +2139,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>212</integer>
+// CHECK-NEXT:           <key>line</key><integer>231</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>212</integer>
+// CHECK-NEXT:           <key>line</key><integer>231</integer>
 // CHECK-NEXT:           <key>col</key><integer>5</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2122,12 +2152,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>213</integer>
+// CHECK-NEXT:           <key>line</key><integer>232</integer>
 // CHECK-NEXT:           <key>col</key><integer>24</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>213</integer>
+// CHECK-NEXT:           <key>line</key><integer>232</integer>
 // CHECK-NEXT:           <key>col</key><integer>24</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2139,7 +2169,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>213</integer>
+// CHECK-NEXT:      <key>line</key><integer>232</integer>
 // CHECK-NEXT:      <key>col</key><integer>24</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -2147,12 +2177,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>213</integer>
+// CHECK-NEXT:         <key>line</key><integer>232</integer>
 // CHECK-NEXT:         <key>col</key><integer>24</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>215</integer>
+// CHECK-NEXT:         <key>line</key><integer>234</integer>
 // CHECK-NEXT:         <key>col</key><integer>3</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -2168,7 +2198,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>213</integer>
+// CHECK-NEXT:      <key>line</key><integer>232</integer>
 // CHECK-NEXT:      <key>col</key><integer>3</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -2176,12 +2206,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>213</integer>
+// CHECK-NEXT:         <key>line</key><integer>232</integer>
 // CHECK-NEXT:         <key>col</key><integer>3</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>215</integer>
+// CHECK-NEXT:         <key>line</key><integer>234</integer>
 // CHECK-NEXT:         <key>col</key><integer>4</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -2197,7 +2227,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>187</integer>
+// CHECK-NEXT:      <key>line</key><integer>50</integer>
 // CHECK-NEXT:      <key>col</key><integer>1</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -2215,12 +2245,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>187</integer>
+// CHECK-NEXT:           <key>line</key><integer>50</integer>
 // CHECK-NEXT:           <key>col</key><integer>1</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>187</integer>
+// CHECK-NEXT:           <key>line</key><integer>50</integer>
 // CHECK-NEXT:           <key>col</key><integer>6</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2228,12 +2258,46 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>189</integer>
+// CHECK-NEXT:           <key>line</key><integer>58</integer>
+// CHECK-NEXT:           <key>col</key><integer>2</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>58</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>58</integer>
+// CHECK-NEXT:           <key>col</key><integer>2</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>58</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>59</integer>
 // CHECK-NEXT:           <key>col</key><integer>3</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>189</integer>
+// CHECK-NEXT:           <key>line</key><integer>59</integer>
 // CHECK-NEXT:           <key>col</key><integer>15</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2245,7 +2309,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>189</integer>
+// CHECK-NEXT:      <key>line</key><integer>59</integer>
 // CHECK-NEXT:      <key>col</key><integer>3</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -2253,12 +2317,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>189</integer>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
 // CHECK-NEXT:         <key>col</key><integer>3</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>189</integer>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
 // CHECK-NEXT:         <key>col</key><integer>33</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -2274,7 +2338,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>189</integer>
+// CHECK-NEXT:      <key>line</key><integer>59</integer>
 // CHECK-NEXT:      <key>col</key><integer>3</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -2282,12 +2346,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>189</integer>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
 // CHECK-NEXT:         <key>col</key><integer>3</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>189</integer>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
 // CHECK-NEXT:         <key>col</key><integer>33</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -2303,7 +2367,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>213</integer>
+// CHECK-NEXT:      <key>line</key><integer>232</integer>
 // CHECK-NEXT:      <key>col</key><integer>24</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -2321,12 +2385,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>213</integer>
+// CHECK-NEXT:           <key>line</key><integer>232</integer>
 // CHECK-NEXT:           <key>col</key><integer>24</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>213</integer>
+// CHECK-NEXT:           <key>line</key><integer>232</integer>
 // CHECK-NEXT:           <key>col</key><integer>24</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2334,12 +2398,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>line</key><integer>233</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>line</key><integer>233</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2355,12 +2419,12 @@
 // CHECK-NEXT:        <key>start</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>line</key><integer>233</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>line</key><integer>233</integer>
 // CHECK-NEXT:           <key>col</key><integer>4</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2368,12 +2432,12 @@
 // CHECK-NEXT:        <key>end</key>
 // CHECK-NEXT:         <array>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>line</key><integer>233</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
 // CHECK-NEXT:          <dict>
-// CHECK-NEXT:           <key>line</key><integer>214</integer>
+// CHECK-NEXT:           <key>line</key><integer>233</integer>
 // CHECK-NEXT:           <key>col</key><integer>7</integer>
 // CHECK-NEXT:           <key>file</key><integer>0</integer>
 // CHECK-NEXT:          </dict>
@@ -2385,7 +2449,7 @@
 // CHECK-NEXT:     <key>kind</key><string>event</string>
 // CHECK-NEXT:     <key>location</key>
 // CHECK-NEXT:     <dict>
-// CHECK-NEXT:      <key>line</key><integer>214</integer>
+// CHECK-NEXT:      <key>line</key><integer>233</integer>
 // CHECK-NEXT:      <key>col</key><integer>7</integer>
 // CHECK-NEXT:      <key>file</key><integer>0</integer>
 // CHECK-NEXT:     </dict>
@@ -2393,12 +2457,12 @@
 // CHECK-NEXT:     <array>
 // CHECK-NEXT:       <array>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>214</integer>
+// CHECK-NEXT:         <key>line</key><integer>233</integer>
 // CHECK-NEXT:         <key>col</key><integer>5</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
 // CHECK-NEXT:        <dict>
-// CHECK-NEXT:         <key>line</key><integer>214</integer>
+// CHECK-NEXT:         <key>line</key><integer>233</integer>
 // CHECK-NEXT:         <key>col</key><integer>5</integer>
 // CHECK-NEXT:         <key>file</key><integer>0</integer>
 // CHECK-NEXT:        </dict>
@@ -2419,9 +2483,459 @@
 // CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>265c4fd608dafee211bfa93d21c28866</string>
 // CHECK-NEXT:  <key>location</key>
 // CHECK-NEXT:  <dict>
-// CHECK-NEXT:   <key>line</key><integer>214</integer>
+// CHECK-NEXT:   <key>line</key><integer>233</integer>
 // CHECK-NEXT:   <key>col</key><integer>7</integer>
 // CHECK-NEXT:   <key>file</key><integer>0</integer>
 // CHECK-NEXT:  </dict>
 // CHECK-NEXT:  </dict>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>path</key>
+// CHECK-NEXT:   <array>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>241</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>241</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>243</integer>
+// CHECK-NEXT:         <key>col</key><integer>4</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Calling &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Calling &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>50</integer>
+// CHECK-NEXT:      <key>col</key><integer>1</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>depth</key><integer>1</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;test_inline_dispatch_once_reachable&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;test_inline_dispatch_once_reachable&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>50</integer>
+// CHECK-NEXT:           <key>col</key><integer>1</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>50</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>58</integer>
+// CHECK-NEXT:           <key>col</key><integer>2</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>58</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>58</integer>
+// CHECK-NEXT:           <key>col</key><integer>2</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>58</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>59</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>59</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>59</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
+// CHECK-NEXT:         <key>col</key><integer>33</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>1</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Calling &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Calling &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>59</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
+// CHECK-NEXT:         <key>col</key><integer>33</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>2</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Calling anonymous block</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Calling anonymous block</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>241</integer>
+// CHECK-NEXT:      <key>col</key><integer>24</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>depth</key><integer>3</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Entered call from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>241</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>241</integer>
+// CHECK-NEXT:           <key>col</key><integer>24</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>242</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>242</integer>
+// CHECK-NEXT:           <key>col</key><integer>7</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>242</integer>
+// CHECK-NEXT:      <key>col</key><integer>7</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>242</integer>
+// CHECK-NEXT:         <key>col</key><integer>7</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>242</integer>
+// CHECK-NEXT:         <key>col</key><integer>11</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>3</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Null pointer value stored to &apos;p&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>59</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
+// CHECK-NEXT:         <key>col</key><integer>33</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>2</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Returning to caller</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Returning to caller</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>59</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>59</integer>
+// CHECK-NEXT:         <key>col</key><integer>33</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>1</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Returning from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Returning from &apos;dispatch_once&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>59</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>59</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>63</integer>
+// CHECK-NEXT:           <key>col</key><integer>2</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>63</integer>
+// CHECK-NEXT:           <key>col</key><integer>17</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>241</integer>
+// CHECK-NEXT:      <key>col</key><integer>3</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>241</integer>
+// CHECK-NEXT:         <key>col</key><integer>3</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>243</integer>
+// CHECK-NEXT:         <key>col</key><integer>4</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Returning from &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Returning from &apos;_dispatch_once&apos;</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>control</string>
+// CHECK-NEXT:     <key>edges</key>
+// CHECK-NEXT:      <array>
+// CHECK-NEXT:       <dict>
+// CHECK-NEXT:        <key>start</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>241</integer>
+// CHECK-NEXT:           <key>col</key><integer>3</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>241</integer>
+// CHECK-NEXT:           <key>col</key><integer>15</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:        <key>end</key>
+// CHECK-NEXT:         <array>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>245</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:          <dict>
+// CHECK-NEXT:           <key>line</key><integer>245</integer>
+// CHECK-NEXT:           <key>col</key><integer>6</integer>
+// CHECK-NEXT:           <key>file</key><integer>0</integer>
+// CHECK-NEXT:          </dict>
+// CHECK-NEXT:         </array>
+// CHECK-NEXT:       </dict>
+// CHECK-NEXT:      </array>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:    <dict>
+// CHECK-NEXT:     <key>kind</key><string>event</string>
+// CHECK-NEXT:     <key>location</key>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>line</key><integer>245</integer>
+// CHECK-NEXT:      <key>col</key><integer>6</integer>
+// CHECK-NEXT:      <key>file</key><integer>0</integer>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <key>ranges</key>
+// CHECK-NEXT:     <array>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>245</integer>
+// CHECK-NEXT:         <key>col</key><integer>4</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>line</key><integer>245</integer>
+// CHECK-NEXT:         <key>col</key><integer>4</integer>
+// CHECK-NEXT:         <key>file</key><integer>0</integer>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </array>
+// CHECK-NEXT:     <key>depth</key><integer>0</integer>
+// CHECK-NEXT:     <key>extended_message</key>
+// CHECK-NEXT:     <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:     <key>message</key>
+// CHECK-NEXT:     <string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:    </dict>
+// CHECK-NEXT:   </array>
+// CHECK-NEXT:   <key>description</key><string>Dereference of null pointer (loaded from variable &apos;p&apos;)</string>
+// CHECK-NEXT:   <key>category</key><string>Logic error</string>
+// CHECK-NEXT:   <key>type</key><string>Dereference of null pointer</string>
+// CHECK-NEXT:   <key>check_name</key><string>core.NullDereference</string>
+// CHECK-NEXT:   <!-- This hash is experimental and going to change! -->
+// CHECK-NEXT:   <key>issue_hash_content_of_line_in_context</key><string>1e83bd4361a2351df0b4e77eb3a9109b</string>
+// CHECK-NEXT:  <key>issue_context_kind</key><string>function</string>
+// CHECK-NEXT:  <key>issue_context</key><string>test_inline_dispatch_once_reachable</string>
+// CHECK-NEXT:  <key>issue_hash_function_offset</key><string>7</string>
+// CHECK-NEXT:  <key>location</key>
+// CHECK-NEXT:  <dict>
+// CHECK-NEXT:   <key>line</key><integer>245</integer>
+// CHECK-NEXT:   <key>col</key><integer>6</integer>
+// CHECK-NEXT:   <key>file</key><integer>0</integer>
+// CHECK-NEXT:  </dict>
+// CHECK-NEXT:  </dict>
 // CHECK-NEXT: </array>
diff --git a/test/Analysis/unreachable-code-path.c b/test/Analysis/unreachable-code-path.c
index ff58587..effa4d9 100644
--- a/test/Analysis/unreachable-code-path.c
+++ b/test/Analysis/unreachable-code-path.c
@@ -213,3 +213,13 @@
   RETURN(1); // no-warning
 }
 
+// Avoid FP when macro argument is known
+void writeSomething(int *x);
+#define MACRO(C)        \
+  if (!C) {             \
+    static int x;       \
+    writeSomething(&x); \
+  }
+void macro2(void) {
+  MACRO(1);
+}
diff --git a/test/Analysis/vector.c b/test/Analysis/vector.c
new file mode 100644
index 0000000..32b568f
--- /dev/null
+++ b/test/Analysis/vector.c
@@ -0,0 +1,28 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+
+typedef int __attribute__((ext_vector_type(2))) V;
+
+void clang_analyzer_numTimesReached();
+void clang_analyzer_eval(int);
+
+int flag;
+
+V pass_through_and_set_flag(V v) {
+  flag = 1;
+  return v;
+}
+
+V dont_crash_and_dont_split_state(V x, V y) {
+  flag = 0;
+  V z = x && pass_through_and_set_flag(y);
+  clang_analyzer_eval(flag); // expected-warning{{TRUE}}
+  // FIXME: For now we treat vector operator && as short-circuit,
+  // but in fact it is not. It should always evaluate
+  // pass_through_and_set_flag(). It should not split state.
+  // Now we also get FALSE on the other path.
+  // expected-warning@-5{{FALSE}}
+
+  // FIXME: Should be 1 since we should not split state.
+  clang_analyzer_numTimesReached(); // expected-warning{{2}}
+  return z;
+}
diff --git a/test/Analysis/virtualcall.cpp b/test/Analysis/virtualcall.cpp
index 56bd324..c22a846 100644
--- a/test/Analysis/virtualcall.cpp
+++ b/test/Analysis/virtualcall.cpp
@@ -1,98 +1,83 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -verify -std=c++11 %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:Interprocedural=true -DINTERPROCEDURAL=1 -verify -std=c++11 %s
-// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -verify -std=c++11 %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-output=text -verify -std=c++11 %s
 
-/* When INTERPROCEDURAL is set, we expect diagnostics in all functions reachable
-   from a constructor or destructor. If it is not set, we expect diagnostics
-   only in the constructor or destructor.
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.cplusplus.VirtualCall -analyzer-store region -analyzer-config optin.cplusplus.VirtualCall:PureOnly=true -DPUREONLY=1 -analyzer-output=text -verify -std=c++11 %s
 
-   When PUREONLY is set, we expect diagnostics only for calls to pure virtual
-   functions not to non-pure virtual functions.
-*/
+#include "virtualcall.h"
 
 class A {
 public:
   A();
-  A(int i);
 
-  ~A() {};
-  
-  virtual int foo() = 0; // from Sema: expected-note {{'foo' declared here}}
+  ~A(){};
+
+  virtual int foo() = 0;
   virtual void bar() = 0;
   void f() {
     foo();
-#if INTERPROCEDURAL
-        // expected-warning-re@-2 {{{{^}}Call Path : foo <-- fCall to pure virtual function during construction has undefined behavior}}
-#endif
+	// expected-warning-re@-1 {{{{^}}Call to pure virtual function during construction}}
+	// expected-note-re@-2 {{{{^}}Call to pure virtual function during construction}}
   }
 };
 
 class B : public A {
 public:
-  B() {
-    foo();
+  B() { // expected-note {{Calling default constructor for 'A'}}
+    foo(); 
 #if !PUREONLY
-#if INTERPROCEDURAL
-        // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
-#else
-        // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}}
+  	// expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+	// expected-note-re@-3 {{{{^}}This constructor of an object of type 'B' has not returned when the virtual method was called}}
+  	// expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
 #endif
-#endif
-
   }
   ~B();
-  
+
   virtual int foo();
-  virtual void bar() { foo(); }
-#if INTERPROCEDURAL
-      // expected-warning-re@-2 {{{{^}}Call Path : foo <-- barCall to virtual function during destruction will not dispatch to derived class}}
+  virtual void bar() {
+    foo(); 
+#if !PUREONLY
+  	// expected-warning-re@-2 {{{{^}}Call to virtual function during destruction}}
+  	// expected-note-re@-3 {{{{^}}Call to virtual function during destruction}}
 #endif
+  } 
 };
 
-A::A() {
-  f();
-}
-
-A::A(int i) {
-  foo(); // From Sema: expected-warning {{call to pure virtual member function 'foo' has undefined behavior}}
-#if INTERPROCEDURAL
-      // expected-warning-re@-2 {{{{^}}Call Path : fooCall to pure virtual function during construction has undefined behavior}}
-#else
-      // expected-warning-re@-4 {{{{^}}Call to pure virtual function during construction has undefined behavior}}
-#endif
+A::A() { 
+  f(); 
+// expected-note-re@-1 {{{{^}}This constructor of an object of type 'A' has not returned when the virtual method was called}}
+// expected-note-re@-2 {{{{^}}Calling 'A::f'}}
 }
 
 B::~B() {
   this->B::foo(); // no-warning
   this->B::bar();
-  this->foo();
 #if !PUREONLY
-#if INTERPROCEDURAL
-      // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during destruction will not dispatch to derived class}}
-#else
-      // expected-warning-re@-5 {{{{^}}Call to virtual function during destruction will not dispatch to derived class}}
+ 	 // expected-note-re@-2 {{{{^}}This destructor of an object of type '~B' has not returned when the virtual method was called}}
+ 	 // expected-note-re@-3 {{{{^}}Calling 'B::bar'}}
 #endif
+  this->foo(); 
+#if !PUREONLY
+ 	 // expected-warning-re@-2 {{{{^}}Call to virtual function during destruction}}
+ 	 // expected-note-re@-3 {{{{^}}This destructor of an object of type '~B' has not returned when the virtual method was called}}
+ 	 // expected-note-re@-4 {{{{^}}Call to virtual function during destruction}}
 #endif
-
+	
 }
 
 class C : public B {
 public:
   C();
   ~C();
-  
+
   virtual int foo();
   void f(int i);
 };
 
 C::C() {
-  f(foo());
+  f(foo()); 
 #if !PUREONLY
-#if INTERPROCEDURAL
-      // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
-#else
-      // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}}
-#endif
+  	// expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+	// expected-note-re@-3 {{{{^}}This constructor of an object of type 'C' has not returned when the virtual method was called}}
+  	// expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
 #endif
 }
 
@@ -112,30 +97,198 @@
     foo(); // no-warning
   }
   ~E() { bar(); }
+#if !PUREONLY
+ 	 // expected-note-re@-2 2{{{{^}}Calling '~B'}}
+#endif
   int foo() override;
 };
 
-// Regression test: don't crash when there's no direct callee.
 class F {
 public:
   F() {
-    void (F::* ptr)() = &F::foo;
+    void (F::*ptr)() = &F::foo;
     (this->*ptr)();
   }
   void foo();
 };
 
-int main() {
-  A *a;
-  B *b;
-  C *c;
-  D *d;
-  E *e;
-  F *f;
+class G {
+public:
+  G() {}
+  virtual void bar();
+  void foo() {
+    bar(); // no warning
+  }
+};
+
+class H {
+public:
+  H() : initState(0) { init(); }
+  int initState;
+  virtual void f() const;
+  void init() {
+    if (initState)
+      f(); // no warning
+  }
+
+  H(int i) {
+    G g;
+    g.foo();
+    g.bar(); // no warning
+    f();     
+#if !PUREONLY
+  	// expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+	// expected-note-re@-3 {{{{^}}This constructor of an object of type 'H' has not returned when the virtual method was called}}
+  	// expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
+#endif
+    H &h = *this;
+    h.f(); 
+#if !PUREONLY
+  	// expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+  	// expected-note-re@-3 {{{{^}}This constructor of an object of type 'H' has not returned when the virtual method was called}}
+  	// expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
+#endif
+  }
+};
+
+class X {
+public:
+  X() {
+    g(); 
+#if !PUREONLY
+  	// expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+	// expected-note-re@-3 {{{{^}}This constructor of an object of type 'X' has not returned when the virtual method was called}}
+  	// expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
+#endif
+  }
+  X(int i) {
+    if (i > 0) {
+#if !PUREONLY
+	// expected-note-re@-2 {{{{^}}Taking true branch}}
+	// expected-note-re@-3 {{{{^}}Taking false branch}}
+#endif
+      X x(i - 1);
+#if !PUREONLY
+	// expected-note-re@-2 {{{{^}}Calling constructor for 'X'}}
+#endif
+      x.g(); // no warning
+    }
+    g(); 
+#if !PUREONLY
+  	// expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+	// expected-note-re@-3 {{{{^}}This constructor of an object of type 'X' has not returned when the virtual method was called}}
+  	// expected-note-re@-4 {{{{^}}Call to virtual function during construction}}
+#endif
+  }
+  virtual void g();
+};
+
+class M;
+class N {
+public:
+  virtual void virtualMethod();
+  void callFooOfM(M *);
+};
+class M {
+public:
+  M() {
+    N n;
+    n.virtualMethod(); // no warning
+    n.callFooOfM(this);
+#if !PUREONLY
+  	// expected-note-re@-2 {{{{^}}This constructor of an object of type 'M' has not returned when the virtual method was called}}
+	// expected-note-re@-3 {{{{^}}Calling 'N::callFooOfM'}}
+#endif
+  }
+  virtual void foo();
+};
+void N::callFooOfM(M *m) {
+  m->foo(); 
+#if !PUREONLY
+  	// expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+  	// expected-note-re@-3 {{{{^}}Call to virtual function during construction}}
+#endif
 }
 
-#include "virtualcall.h"
+class Y {
+public:
+  virtual void foobar();
+  void fooY() {
+    F f1;
+    foobar(); 
+#if !PUREONLY
+  	// expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+  	// expected-note-re@-3 {{{{^}}Call to virtual function during construction}}
+#endif
+  }
+  Y() { fooY(); }
+#if !PUREONLY
+  	// expected-note-re@-2 {{{{^}}This constructor of an object of type 'Y' has not returned when the virtual method was called}}
+  	// expected-note-re@-3 {{{{^}}Calling 'Y::fooY'}}
+#endif
+};
 
-#define AS_SYSTEM
-#include "virtualcall.h"
-#undef AS_SYSTEM
+int main() {
+  B b;
+#if PUREONLY
+	//expected-note-re@-2 {{{{^}}Calling default constructor for 'B'}}
+#else 
+	//expected-note-re@-4 2{{{{^}}Calling default constructor for 'B'}}
+#endif
+  C c;
+#if !PUREONLY
+	//expected-note-re@-2 {{{{^}}Calling default constructor for 'C'}}
+#endif
+  D d;
+  E e;
+  F f;
+  G g;
+  H h;
+  H h1(1);
+#if !PUREONLY
+	//expected-note-re@-2 {{{{^}}Calling constructor for 'H'}}
+	//expected-note-re@-3 {{{{^}}Calling constructor for 'H'}}
+#endif
+  X x; 
+#if !PUREONLY
+	//expected-note-re@-2 {{{{^}}Calling default constructor for 'X'}}
+#endif
+  X x1(1);
+#if !PUREONLY
+	//expected-note-re@-2 {{{{^}}Calling constructor for 'X'}}
+#endif
+  M m;
+#if !PUREONLY
+	//expected-note-re@-2 {{{{^}}Calling default constructor for 'M'}}
+#endif
+  Y *y = new Y;
+  delete y;
+  header::Z z;
+#if !PUREONLY
+	// expected-note-re@-2 {{{{^}}Calling default constructor for 'Z'}}
+#endif
+}
+#if !PUREONLY
+	//expected-note-re@-2 2{{{{^}}Calling '~E'}}
+#endif
+
+namespace PR34451 {
+struct a {
+  void b() {
+    a c[1];
+    c->b();
+  }
+};
+
+class e {
+ public:
+  void b() const;
+};
+
+class c {
+  void m_fn2() const;
+  e d[];
+};
+
+void c::m_fn2() const { d->b(); }
+}
diff --git a/test/Analysis/virtualcall.h b/test/Analysis/virtualcall.h
index c2ad8a6..e2fde24 100644
--- a/test/Analysis/virtualcall.h
+++ b/test/Analysis/virtualcall.h
@@ -1,36 +1,14 @@
-#ifdef AS_SYSTEM
-#pragma clang system_header
-
-namespace system {
-  class A {
-  public:
-    A() {
-      foo(); // no-warning
-    }
-
-    virtual int foo();
-  };
-}
-
-#else
-
 namespace header {
-  class A {
+  class Z {
   public:
-    A() {
+    Z() {
       foo();
 #if !PUREONLY
-#if INTERPROCEDURAL
-          // expected-warning-re@-3 {{{{^}}Call Path : fooCall to virtual function during construction will not dispatch to derived class}}
-#else
-          // expected-warning-re@-5 {{{{^}}Call to virtual function during construction will not dispatch to derived class}}
+	// expected-warning-re@-2 {{{{^}}Call to virtual function during construction}}
+	// expected-note-re@-3 {{{{^}}This constructor of an object of type 'Z' has not returned when the virtual method was called}}
+	// expected-note-re@-4 {{{{^}}Call to virtual function during construction}}	
 #endif
-#endif
-
     }
-
     virtual int foo();
   };
 }
-
-#endif
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/Inputs/sanitizer-special-case-list.sanitized.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt
new file mode 100644
index 0000000..a2afde0
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.sanitized.txt
@@ -0,0 +1,4 @@
+[unsigned-integer-overflow]
+fun:*cfi*
+[cfi]
+fun:*overflow*
diff --git a/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt
new file mode 100644
index 0000000..45ad57b
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized1.txt
@@ -0,0 +1,2 @@
+fun:*cfi*
+fun:*overflow*
diff --git a/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt
new file mode 100644
index 0000000..375b246
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized2.txt
@@ -0,0 +1,4 @@
+[cfi]
+fun:*cfi*
+[unsigned-integer-overflow]
+fun:*overflow*
diff --git a/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt
new file mode 100644
index 0000000..b038fee
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized3.txt
@@ -0,0 +1,4 @@
+[cfi-icall]
+fun:*cfi*
+[unsigned-integer-overflow]
+fun:*overflow*
diff --git a/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt
new file mode 100644
index 0000000..b31747e
--- /dev/null
+++ b/test/CodeGen/Inputs/sanitizer-special-case-list.unsanitized4.txt
@@ -0,0 +1,4 @@
+[c*]
+fun:*cfi*
+[u*]
+fun:*overflow*
diff --git a/test/CodeGen/builtins.c b/test/CodeGen/builtins.c
index 390c2e3..3584585 100644
--- a/test/CodeGen/builtins.c
+++ b/test/CodeGen/builtins.c
@@ -378,229 +378,385 @@
 #ifdef __x86_64__
 
 // CHECK-LABEL: define void @test_builtin_os_log
-// CHECK: (i8* [[BUF:%.*]], i32 [[I:%.*]], i8* [[DATA:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i32 %[[I:.*]], i8* %[[DATA:.*]])
 void test_builtin_os_log(void *buf, int i, const char *data) {
   volatile int len;
-  // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
-  // CHECK: store i32 [[I]], i32* [[I_ADDR:%.*]], align 4
-  // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
+  // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[I_ADDR:.*]] = alloca i32, align 4
+  // CHECK: %[[DATA_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[LEN:.*]] = alloca i32, align 4
+  // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+  // CHECK: store i32 %[[I]], i32* %[[I_ADDR]], align 4
+  // CHECK: store i8* %[[DATA]], i8** %[[DATA_ADDR]], align 8
 
-  // CHECK: store volatile i32 34
+  // CHECK: store volatile i32 34, i32* %[[LEN]]
   len = __builtin_os_log_format_buffer_size("%d %{public}s %{private}.16P", i, data, data);
 
-  // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
-  // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
-  // CHECK: store i8 3, i8* [[SUMMARY]]
-  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
-  // CHECK: store i8 4, i8* [[NUM_ARGS]]
-  //
-  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
-  // CHECK: store i8 0, i8* [[ARG1_DESC]]
-  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
-  // CHECK: store i8 4, i8* [[ARG1_SIZE]]
-  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
-  // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
-  // CHECK: [[I2:%.*]] = load i32, i32* [[I_ADDR]]
-  // CHECK: store i32 [[I2]], i32* [[ARG1_INT]]
-
-  // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 8
-  // CHECK: store i8 34, i8* [[ARG2_DESC]]
-  // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 9
-  // CHECK: store i8 8, i8* [[ARG2_SIZE]]
-  // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 10
-  // CHECK: [[ARG2_PTR:%.*]] = bitcast i8* [[ARG2]] to i8**
-  // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]]
-  // CHECK: store i8* [[DATA2]], i8** [[ARG2_PTR]]
-
-  // CHECK: [[ARG3_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 18
-  // CHECK: store i8 17, i8* [[ARG3_DESC]]
-  // CHECK: [[ARG3_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 19
-  // CHECK: store i8 4, i8* [[ARG3_SIZE]]
-  // CHECK: [[ARG3:%.*]] = getelementptr i8, i8* [[BUF2]], i64 20
-  // CHECK: [[ARG3_INT:%.*]] = bitcast i8* [[ARG3]] to i32*
-  // CHECK: store i32 16, i32* [[ARG3_INT]]
-
-  // CHECK: [[ARG4_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 24
-  // CHECK: store i8 49, i8* [[ARG4_DESC]]
-  // CHECK: [[ARG4_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 25
-  // CHECK: store i8 8, i8* [[ARG4_SIZE]]
-  // CHECK: [[ARG4:%.*]] = getelementptr i8, i8* [[BUF2]], i64 26
-  // CHECK: [[ARG4_PTR:%.*]] = bitcast i8* [[ARG4]] to i8**
-  // CHECK: [[DATA3:%.*]] = load i8*, i8** [[DATA_ADDR]]
-  // CHECK: store i8* [[DATA3]], i8** [[ARG4_PTR]]
-
+  // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]]
+  // CHECK: %[[V2:.*]] = load i32, i32* %[[I_ADDR]]
+  // CHECK: %[[V3:.*]] = load i8*, i8** %[[DATA_ADDR]]
+  // CHECK: %[[V4:.*]] = ptrtoint i8* %[[V3]] to i64
+  // CHECK: %[[V5:.*]] = load i8*, i8** %[[DATA_ADDR]]
+  // CHECK: %[[V6:.*]] = ptrtoint i8* %[[V5]] to i64
+  // CHECK: call void @__os_log_helper_1_3_4_4_0_8_34_4_17_8_49(i8* %[[V1]], i32 %[[V2]], i64 %[[V4]], i32 16, i64 %[[V6]])
   __builtin_os_log_format(buf, "%d %{public}s %{private}.16P", i, data, data);
 }
 
-// CHECK-LABEL: define void @test_builtin_os_log_errno
-// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]])
-void test_builtin_os_log_errno(void *buf, const char *data) {
-  volatile int len;
-  // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
-  // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_3_4_4_0_8_34_4_17_8_49
+// CHECK: (i8* %[[BUFFER:.*]], i32 %[[ARG0:.*]], i64 %[[ARG1:.*]], i32 %[[ARG2:.*]], i64 %[[ARG3:.*]])
 
-  // CHECK: store volatile i32 2
-  len = __builtin_os_log_format_buffer_size("%S");
-
-  // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
-  // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
-  // CHECK: store i8 2, i8* [[SUMMARY]]
-  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
-  // CHECK: store i8 1, i8* [[NUM_ARGS]]
-
-  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
-  // CHECK: store i8 96, i8* [[ARG1_DESC]]
-  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
-  // CHECK: store i8 0, i8* [[ARG1_SIZE]]
-  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
-  // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
-  // CHECK: store i32 0, i32* [[ARG1_INT]]
-
-  __builtin_os_log_format(buf, "%m");
-}
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i32, align 4
+// CHECK: %[[ARG1_ADDR:.*]] = alloca i64, align 8
+// CHECK: %[[ARG2_ADDR:.*]] = alloca i32, align 4
+// CHECK: %[[ARG3_ADDR:.*]] = alloca i64, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i32 %[[ARG0]], i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i64 %[[ARG1]], i64* %[[ARG1_ADDR]], align 8
+// CHECK: store i32 %[[ARG2]], i32* %[[ARG2_ADDR]], align 4
+// CHECK: store i64 %[[ARG3]], i64* %[[ARG3_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 3, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 4, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 0, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 4, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i32*
+// CHECK: %[[V0:.*]] = load i32, i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i32 %[[V0]], i32* %[[ARGDATACAST]], align 1
+// CHECK: %[[ARGDESCRIPTOR1:.*]] = getelementptr i8, i8* %[[BUF]], i64 8
+// CHECK: store i8 34, i8* %[[ARGDESCRIPTOR1]], align 1
+// CHECK: %[[ARGSIZE2:.*]] = getelementptr i8, i8* %[[BUF]], i64 9
+// CHECK: store i8 8, i8* %[[ARGSIZE2]], align 1
+// CHECK: %[[ARGDATA3:.*]] = getelementptr i8, i8* %[[BUF]], i64 10
+// CHECK: %[[ARGDATACAST4:.*]] = bitcast i8* %[[ARGDATA3]] to i64*
+// CHECK: %[[V1:.*]] = load i64, i64* %[[ARG1_ADDR]], align 8
+// CHECK: store i64 %[[V1]], i64* %[[ARGDATACAST4]], align 1
+// CHECK: %[[ARGDESCRIPTOR5:.*]] = getelementptr i8, i8* %[[BUF]], i64 18
+// CHECK: store i8 17, i8* %[[ARGDESCRIPTOR5]], align 1
+// CHECK: %[[ARGSIZE6:.*]] = getelementptr i8, i8* %[[BUF]], i64 19
+// CHECK: store i8 4, i8* %[[ARGSIZE6]], align 1
+// CHECK: %[[ARGDATA7:.*]] = getelementptr i8, i8* %[[BUF]], i64 20
+// CHECK: %[[ARGDATACAST8:.*]] = bitcast i8* %[[ARGDATA7]] to i32*
+// CHECK: %[[V2:.*]] = load i32, i32* %[[ARG2_ADDR]], align 4
+// CHECK: store i32 %[[V2]], i32* %[[ARGDATACAST8]], align 1
+// CHECK: %[[ARGDESCRIPTOR9:.*]] = getelementptr i8, i8* %[[BUF]], i64 24
+// CHECK: store i8 49, i8* %[[ARGDESCRIPTOR9]], align 1
+// CHECK: %[[ARGSIZE10:.*]] = getelementptr i8, i8* %[[BUF]], i64 25
+// CHECK: store i8 8, i8* %[[ARGSIZE10]], align 1
+// CHECK: %[[ARGDATA11:.*]] = getelementptr i8, i8* %[[BUF]], i64 26
+// CHECK: %[[ARGDATACAST12:.*]] = bitcast i8* %[[ARGDATA11]] to i64*
+// CHECK: %[[V3:.*]] = load i64, i64* %[[ARG3_ADDR]], align 8
+// CHECK: store i64 %[[V3]], i64* %[[ARGDATACAST12]], align 1
 
 // CHECK-LABEL: define void @test_builtin_os_log_wide
-// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]], i32* [[STR:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i8* %[[DATA:.*]], i32* %[[STR:.*]])
 typedef int wchar_t;
 void test_builtin_os_log_wide(void *buf, const char *data, wchar_t *str) {
   volatile int len;
-  // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
-  // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
-  // CHECK: store i32* [[STR]], i32** [[STR_ADDR:%.*]],
 
-  // CHECK: store volatile i32 12
+  // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[DATA_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[STR_ADDR:.*]] = alloca i32*, align 8
+  // CHECK: %[[LEN:.*]] = alloca i32, align 4
+  // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+  // CHECK: store i8* %[[DATA]], i8** %[[DATA_ADDR]], align 8
+  // CHECK: store i32* %[[STR]], i32** %[[STR_ADDR]], align 8
+
+  // CHECK: store volatile i32 12, i32* %[[LEN]], align 4
   len = __builtin_os_log_format_buffer_size("%S", str);
 
-  // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
-  // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
-  // CHECK: store i8 2, i8* [[SUMMARY]]
-  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
-  // CHECK: store i8 1, i8* [[NUM_ARGS]]
-
-  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
-  // CHECK: store i8 80, i8* [[ARG1_DESC]]
-  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
-  // CHECK: store i8 8, i8* [[ARG1_SIZE]]
-  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
-  // CHECK: [[ARG1_PTR:%.*]] = bitcast i8* [[ARG1]] to i32**
-  // CHECK: [[STR2:%.*]] = load i32*, i32** [[STR_ADDR]]
-  // CHECK: store i32* [[STR2]], i32** [[ARG1_PTR]]
+  // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+  // CHECK: %[[V2:.*]] = load i32*, i32** %[[STR_ADDR]], align 8
+  // CHECK: %[[V3:.*]] = ptrtoint i32* %[[V2]] to i64
+  // CHECK: call void @__os_log_helper_1_2_1_8_80(i8* %[[V1]], i64 %[[V3]])
 
   __builtin_os_log_format(buf, "%S", str);
 }
 
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_1_8_80
+// CHECK: (i8* %[[BUFFER:.*]], i64 %[[ARG0:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i64, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i64 %[[ARG0]], i64* %[[ARG0_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 80, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 8, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i64*
+// CHECK: %[[V0:.*]] = load i64, i64* %[[ARG0_ADDR]], align 8
+// CHECK: store i64 %[[V0]], i64* %[[ARGDATACAST]], align 1
+
 // CHECK-LABEL: define void @test_builtin_os_log_precision_width
-// CHECK: (i8* [[BUF:%.*]], i8* [[DATA:%.*]], i32 [[PRECISION:%.*]], i32 [[WIDTH:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i8* %[[DATA:.*]], i32 %[[PRECISION:.*]], i32 %[[WIDTH:.*]])
 void test_builtin_os_log_precision_width(void *buf, const char *data,
                                          int precision, int width) {
   volatile int len;
-  // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
-  // CHECK: store i8* [[DATA]], i8** [[DATA_ADDR:%.*]], align 8
-  // CHECK: store i32 [[PRECISION]], i32* [[PRECISION_ADDR:%.*]], align 4
-  // CHECK: store i32 [[WIDTH]], i32* [[WIDTH_ADDR:%.*]], align 4
+  // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[DATA_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[PRECISION_ADDR:.*]] = alloca i32, align 4
+  // CHECK: %[[WIDTH_ADDR:.*]] = alloca i32, align 4
+  // CHECK: %[[LEN:.*]] = alloca i32, align 4
+  // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+  // CHECK: store i8* %[[DATA]], i8** %[[DATA_ADDR]], align 8
+  // CHECK: store i32 %[[PRECISION]], i32* %[[PRECISION_ADDR]], align 4
+  // CHECK: store i32 %[[WIDTH]], i32* %[[WIDTH_ADDR]], align 4
 
-  // CHECK: store volatile i32 24,
+  // CHECK: store volatile i32 24, i32* %[[LEN]], align 4
   len = __builtin_os_log_format_buffer_size("Hello %*.*s World", precision, width, data);
 
-  // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
-  // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
-  // CHECK: store i8 2, i8* [[SUMMARY]]
-  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
-  // CHECK: store i8 3, i8* [[NUM_ARGS]]
-
-  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
-  // CHECK: store i8 0, i8* [[ARG1_DESC]]
-  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
-  // CHECK: store i8 4, i8* [[ARG1_SIZE]]
-  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
-  // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
-  // CHECK: [[ARG1_VAL:%.*]] = load i32, i32* [[PRECISION_ADDR]]
-  // CHECK: store i32 [[ARG1_VAL]], i32* [[ARG1_INT]]
-
-  // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 8
-  // CHECK: store i8 16, i8* [[ARG2_DESC]]
-  // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 9
-  // CHECK: store i8 4, i8* [[ARG2_SIZE]]
-  // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 10
-  // CHECK: [[ARG2_INT:%.*]] = bitcast i8* [[ARG2]] to i32*
-  // CHECK: [[ARG2_VAL:%.*]] = load i32, i32* [[WIDTH_ADDR]]
-  // CHECK: store i32 [[ARG2_VAL]], i32* [[ARG2_INT]]
-
-  // CHECK: [[ARG3_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 14
-  // CHECK: store i8 32, i8* [[ARG3_DESC]]
-  // CHECK: [[ARG3_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 15
-  // CHECK: store i8 8, i8* [[ARG3_SIZE]]
-  // CHECK: [[ARG3:%.*]] = getelementptr i8, i8* [[BUF2]], i64 16
-  // CHECK: [[ARG3_PTR:%.*]] = bitcast i8* [[ARG3]] to i8**
-  // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA_ADDR]]
-  // CHECK: store i8* [[DATA2]], i8** [[ARG3_PTR]]
-
+  // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+  // CHECK: %[[V2:.*]] = load i32, i32* %[[PRECISION_ADDR]], align 4
+  // CHECK: %[[V3:.*]] = load i32, i32* %[[WIDTH_ADDR]], align 4
+  // CHECK: %[[V4:.*]] = load i8*, i8** %[[DATA_ADDR]], align 8
+  // CHECK: %[[V5:.*]] = ptrtoint i8* %[[V4]] to i64
+  // CHECK: call void @__os_log_helper_1_2_3_4_0_4_16_8_32(i8* %[[V1]], i32 %[[V2]], i32 %[[V3]], i64 %[[V5]])
   __builtin_os_log_format(buf, "Hello %*.*s World", precision, width, data);
 }
 
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_3_4_0_4_16_8_32
+// CHECK: (i8* %[[BUFFER:.*]], i32 %[[ARG0:.*]], i32 %[[ARG1:.*]], i64 %[[ARG2:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i32, align 4
+// CHECK: %[[ARG1_ADDR:.*]] = alloca i32, align 4
+// CHECK: %[[ARG2_ADDR:.*]] = alloca i64, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i32 %[[ARG0]], i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i32 %[[ARG1]], i32* %[[ARG1_ADDR]], align 4
+// CHECK: store i64 %[[ARG2]], i64* %[[ARG2_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 3, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 0, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 4, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i32*
+// CHECK: %[[V0:.*]] = load i32, i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i32 %[[V0]], i32* %[[ARGDATACAST]], align 1
+// CHECK: %[[ARGDESCRIPTOR1:.*]] = getelementptr i8, i8* %[[BUF]], i64 8
+// CHECK: store i8 16, i8* %[[ARGDESCRIPTOR1]], align 1
+// CHECK: %[[ARGSIZE2:.*]] = getelementptr i8, i8* %[[BUF]], i64 9
+// CHECK: store i8 4, i8* %[[ARGSIZE2]], align 1
+// CHECK: %[[ARGDATA3:.*]] = getelementptr i8, i8* %[[BUF]], i64 10
+// CHECK: %[[ARGDATACAST4:.*]] = bitcast i8* %[[ARGDATA3]] to i32*
+// CHECK: %[[V1:.*]] = load i32, i32* %[[ARG1_ADDR]], align 4
+// CHECK: store i32 %[[V1]], i32* %[[ARGDATACAST4]], align 1
+// CHECK: %[[ARGDESCRIPTOR5:.*]] = getelementptr i8, i8* %[[BUF]], i64 14
+// CHECK: store i8 32, i8* %[[ARGDESCRIPTOR5]], align 1
+// CHECK: %[[ARGSIZE6:.*]] = getelementptr i8, i8* %[[BUF]], i64 15
+// CHECK: store i8 8, i8* %[[ARGSIZE6]], align 1
+// CHECK: %[[ARGDATA7:.*]] = getelementptr i8, i8* %[[BUF]], i64 16
+// CHECK: %[[ARGDATACAST8:.*]] = bitcast i8* %[[ARGDATA7]] to i64*
+// CHECK: %[[V2:.*]] = load i64, i64* %[[ARG2_ADDR]], align 8
+// CHECK: store i64 %[[V2]], i64* %[[ARGDATACAST8]], align 1
+
 // CHECK-LABEL: define void @test_builtin_os_log_invalid
-// CHECK: (i8* [[BUF:%.*]], i32 [[DATA:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i32 %[[DATA:.*]])
 void test_builtin_os_log_invalid(void *buf, int data) {
   volatile int len;
-  // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
-  // CHECK: store i32 [[DATA]], i32* [[DATA_ADDR:%.*]]
+  // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[DATA_ADDR:.*]] = alloca i32, align 4
+  // CHECK: %[[LEN:.*]] = alloca i32, align 4
+  // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+  // CHECK: store i32 %[[DATA]], i32* %[[DATA_ADDR]], align 4
 
-  // CHECK: store volatile i32 8,
+  // CHECK: store volatile i32 8, i32* %[[LEN]], align 4
   len = __builtin_os_log_format_buffer_size("invalid specifier %: %d even a trailing one%", data);
 
-  // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
-  // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
-  // CHECK: store i8 0, i8* [[SUMMARY]]
-  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
-  // CHECK: store i8 1, i8* [[NUM_ARGS]]
-
-  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
-  // CHECK: store i8 0, i8* [[ARG1_DESC]]
-  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
-  // CHECK: store i8 4, i8* [[ARG1_SIZE]]
-  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
-  // CHECK: [[ARG1_INT:%.*]] = bitcast i8* [[ARG1]] to i32*
-  // CHECK: [[ARG1_VAL:%.*]] = load i32, i32* [[DATA_ADDR]]
-  // CHECK: store i32 [[ARG1_VAL]], i32* [[ARG1_INT]]
+  // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+  // CHECK: %[[V2:.*]] = load i32, i32* %[[DATA_ADDR]], align 4
+  // CHECK: call void @__os_log_helper_1_0_1_4_0(i8* %[[V1]], i32 %[[V2]])
 
   __builtin_os_log_format(buf, "invalid specifier %: %d even a trailing one%", data);
 }
 
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_0_1_4_0
+// CHECK: (i8* %[[BUFFER:.*]], i32 %[[ARG0:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i32, align 4
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i32 %[[ARG0]], i32* %[[ARG0_ADDR]], align 4
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 0, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 0, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 4, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i32*
+// CHECK: %[[V0:.*]] = load i32, i32* %[[ARG0_ADDR]], align 4
+// CHECK: store i32 %[[V0]], i32* %[[ARGDATACAST]], align 1
+
 // CHECK-LABEL: define void @test_builtin_os_log_percent
-// CHECK: (i8* [[BUF:%.*]], i8* [[DATA1:%.*]], i8* [[DATA2:%.*]])
+// CHECK: (i8* %[[BUF:.*]], i8* %[[DATA1:.*]], i8* %[[DATA2:.*]])
 // Check that the %% which does not consume any argument is correctly handled
 void test_builtin_os_log_percent(void *buf, const char *data1, const char *data2) {
   volatile int len;
-  // CHECK: store i8* [[BUF]], i8** [[BUF_ADDR:%.*]], align 8
-  // CHECK: store i8* [[DATA1]], i8** [[DATA1_ADDR:%.*]], align 8
-  // CHECK: store i8* [[DATA2]], i8** [[DATA2_ADDR:%.*]], align 8
-  // CHECK: store volatile i32 22
+  // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[DATA1_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[DATA2_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[LEN:.*]] = alloca i32, align 4
+  // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+  // CHECK: store i8* %[[DATA1]], i8** %[[DATA1_ADDR]], align 8
+  // CHECK: store i8* %[[DATA2]], i8** %[[DATA2_ADDR]], align 8
+  // CHECK: store volatile i32 22, i32* %[[LEN]], align 4
+
   len = __builtin_os_log_format_buffer_size("%s %% %s", data1, data2);
 
-  // CHECK: [[BUF2:%.*]] = load i8*, i8** [[BUF_ADDR]]
-  // CHECK: [[SUMMARY:%.*]] = getelementptr i8, i8* [[BUF2]], i64 0
-  // CHECK: store i8 2, i8* [[SUMMARY]]
-  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* [[BUF2]], i64 1
-  // CHECK: store i8 2, i8* [[NUM_ARGS]]
-  //
-  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 2
-  // CHECK: store i8 32, i8* [[ARG1_DESC]]
-  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 3
-  // CHECK: store i8 8, i8* [[ARG1_SIZE]]
-  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* [[BUF2]], i64 4
-  // CHECK: [[ARG1_PTR:%.*]] = bitcast i8* [[ARG1]] to i8**
-  // CHECK: [[DATA1:%.*]] = load i8*, i8** [[DATA1_ADDR]]
-  // CHECK: store i8* [[DATA1]], i8** [[ARG1_PTR]]
-  //
-  // CHECK: [[ARG2_DESC:%.*]] = getelementptr i8, i8* [[BUF2]], i64 12
-  // CHECK: store i8 32, i8* [[ARG2_DESC]]
-  // CHECK: [[ARG2_SIZE:%.*]] = getelementptr i8, i8* [[BUF2]], i64 13
-  // CHECK: store i8 8, i8* [[ARG2_SIZE]]
-  // CHECK: [[ARG2:%.*]] = getelementptr i8, i8* [[BUF2]], i64 14
-  // CHECK: [[ARG2_PTR:%.*]] = bitcast i8* [[ARG2]] to i8**
-  // CHECK: [[DATA2:%.*]] = load i8*, i8** [[DATA2_ADDR]]
-  // CHECK: store i8* [[DATA2]], i8** [[ARG2_PTR]]
+  // CHECK: %[[V1:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+  // CHECK: %[[V2:.*]] = load i8*, i8** %[[DATA1_ADDR]], align 8
+  // CHECK: %[[V3:.*]] = ptrtoint i8* %[[V2]] to i64
+  // CHECK: %[[V4:.*]] = load i8*, i8** %[[DATA2_ADDR]], align 8
+  // CHECK: %[[V5:.*]] = ptrtoint i8* %[[V4]] to i64
+  // CHECK: call void @__os_log_helper_1_2_2_8_32_8_32(i8* %[[V1]], i64 %[[V3]], i64 %[[V5]])
+
   __builtin_os_log_format(buf, "%s %% %s", data1, data2);
 }
 
-#endif
\ No newline at end of file
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_2_8_32_8_32
+// CHECK: (i8* %[[BUFFER:.*]], i64 %[[ARG0:.*]], i64 %[[ARG1:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i64, align 8
+// CHECK: %[[ARG1_ADDR:.*]] = alloca i64, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i64 %[[ARG0]], i64* %[[ARG0_ADDR]], align 8
+// CHECK: store i64 %[[ARG1]], i64* %[[ARG1_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 2, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 32, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 8, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i64*
+// CHECK: %[[V0:.*]] = load i64, i64* %[[ARG0_ADDR]], align 8
+// CHECK: store i64 %[[V0]], i64* %[[ARGDATACAST]], align 1
+// CHECK: %[[ARGDESCRIPTOR1:.*]] = getelementptr i8, i8* %[[BUF]], i64 12
+// CHECK: store i8 32, i8* %[[ARGDESCRIPTOR1]], align 1
+// CHECK: %[[ARGSIZE2:.*]] = getelementptr i8, i8* %[[BUF]], i64 13
+// CHECK: store i8 8, i8* %[[ARGSIZE2]], align 1
+// CHECK: %[[ARGDATA3:.*]] = getelementptr i8, i8* %[[BUF]], i64 14
+// CHECK: %[[ARGDATACAST4:.*]] = bitcast i8* %[[ARGDATA3]] to i64*
+// CHECK: %[[V1:.*]] = load i64, i64* %[[ARG1_ADDR]], align 8
+// CHECK: store i64 %[[V1]], i64* %[[ARGDATACAST4]], align 1
+
+// Check that the following two functions call the same helper function.
+
+// CHECK-LABEL: define void @test_builtin_os_log_merge_helper0
+// CHECK: call void @__os_log_helper_1_0_2_4_0_8_0(
+void test_builtin_os_log_merge_helper0(void *buf, int i, double d) {
+  __builtin_os_log_format(buf, "%d %f", i, d);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_0_2_4_0_8_0(
+
+// CHECK-LABEL: define void @test_builtin_os_log_merge_helper1
+// CHECK: call void @__os_log_helper_1_0_2_4_0_8_0(
+void test_builtin_os_log_merge_helper1(void *buf, unsigned u, long long ll) {
+  __builtin_os_log_format(buf, "%u %lld", u, ll);
+}
+
+// Check that this function doesn't write past the end of array 'buf'.
+
+// CHECK-LABEL: define void @test_builtin_os_log_errno
+void test_builtin_os_log_errno() {
+  // CHECK: %[[VLA:.*]] = alloca i8, i64 4, align 16
+  // CHECK: call void @__os_log_helper_16_2_1_0_96(i8* %[[VLA]])
+
+  char buf[__builtin_os_log_format_buffer_size("%m")];
+  __builtin_os_log_format(buf, "%m");
+}
+
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_16_2_1_0_96
+// CHECK: (i8* %[[BUFFER:.*]])
+
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 2, i8* %[[SUMMARY]], align 16
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 96, i8* %[[ARGDESCRIPTOR]], align 2
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 0, i8* %[[ARGSIZE]], align 1
+// CHECK-NEXT: ret void
+
+// CHECK-LABEL: define void @test_builtin_os_log_long_double
+// CHECK: (i8* %[[BUF:.*]], x86_fp80 %[[LD:.*]])
+void test_builtin_os_log_long_double(void *buf, long double ld) {
+  // CHECK: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+  // CHECK: %[[LD_ADDR:.*]] = alloca x86_fp80, align 16
+  // CHECK: %[[COERCE:.*]] = alloca i128, align 16
+  // CHECK: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+  // CHECK: store x86_fp80 %[[LD]], x86_fp80* %[[LD_ADDR]], align 16
+  // CHECK: %[[V0:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+  // CHECK: %[[V1:.*]] = load x86_fp80, x86_fp80* %[[LD_ADDR]], align 16
+  // CHECK: %[[V2:.*]] = bitcast x86_fp80 %[[V1]] to i80
+  // CHECK: %[[V3:.*]] = zext i80 %[[V2]] to i128
+  // CHECK: store i128 %[[V3]], i128* %[[COERCE]], align 16
+  // CHECK: %[[V4:.*]] = bitcast i128* %[[COERCE]] to { i64, i64 }*
+  // CHECK: %[[V5:.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* %[[V4]], i32 0, i32 0
+  // CHECK: %[[V6:.*]] = load i64, i64* %[[V5]], align 16
+  // CHECK: %[[V7:.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* %[[V4]], i32 0, i32 1
+  // CHECK: %[[V8:.*]] = load i64, i64* %[[V7]], align 8
+  // CHECK: call void @__os_log_helper_1_0_1_16_0(i8* %[[V0]], i64 %[[V6]], i64 %[[V8]])
+
+  __builtin_os_log_format(buf, "%Lf", ld);
+}
+
+// CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_0_1_16_0
+// CHECK: (i8* %[[BUFFER:.*]], i64 %[[ARG0_COERCE0:.*]], i64 %[[ARG0_COERCE1:.*]])
+
+// CHECK: %[[ARG0:.*]] = alloca i128, align 16
+// CHECK: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK: %[[ARG0_ADDR:.*]] = alloca i128, align 16
+// CHECK: %[[V0:.*]] = bitcast i128* %[[ARG0]] to { i64, i64 }*
+// CHECK: %[[V1:.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* %[[V0]], i32 0, i32 0
+// CHECK: store i64 %[[ARG0_COERCE0]], i64* %[[V1]], align 16
+// CHECK: %[[V2:.*]] = getelementptr inbounds { i64, i64 }, { i64, i64 }* %[[V0]], i32 0, i32 1
+// CHECK: store i64 %[[ARG0_COERCE1]], i64* %[[V2]], align 8
+// CHECK: %[[ARG01:.*]] = load i128, i128* %[[ARG0]], align 16
+// CHECK: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK: store i128 %[[ARG01]], i128* %[[ARG0_ADDR]], align 16
+// CHECK: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK: store i8 0, i8* %[[SUMMARY]], align 1
+// CHECK: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK: store i8 0, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK: store i8 16, i8* %[[ARGSIZE]], align 1
+// CHECK: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i128*
+// CHECK: %[[V3:.*]] = load i128, i128* %[[ARG0_ADDR]], align 16
+// CHECK: store i128 %[[V3]], i128* %[[ARGDATACAST]], align 1
+
+#endif
diff --git a/test/CodeGen/catch-undef-behavior.c b/test/CodeGen/catch-undef-behavior.c
index e67f0a1..7915ed9 100644
--- a/test/CodeGen/catch-undef-behavior.c
+++ b/test/CodeGen/catch-undef-behavior.c
@@ -59,8 +59,7 @@
   // CHECK-COMMON-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRINT]], 3
   // CHECK-COMMON-NEXT: icmp eq i64 %[[MISALIGN]], 0
 
-  // CHECK-UBSAN:      %[[ARG:.*]] = ptrtoint
-  // CHECK-UBSAN-NEXT: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[ARG]])
+  // CHECK-UBSAN: call void @__ubsan_handle_type_mismatch_v1(i8* bitcast ({{.*}} @[[LINE_200]] to i8*), i64 %[[PTRINT]])
 
   // CHECK-TRAP:      call void @llvm.trap() [[NR_NUW]]
   // CHECK-TRAP-NEXT: unreachable
diff --git a/test/CodeGen/debug-info-block-vars.c b/test/CodeGen/debug-info-block-vars.c
new file mode 100644
index 0000000..e0bb61e
--- /dev/null
+++ b/test/CodeGen/debug-info-block-vars.c
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -x c -fblocks -debug-info-kind=standalone -emit-llvm -O0 \
+// RUN:   -triple x86_64-apple-darwin -o - %s | FileCheck %s
+// RUN: %clang_cc1 -x c -fblocks -debug-info-kind=standalone -emit-llvm -O1 \
+// RUN:   -triple x86_64-apple-darwin -o - %s \
+// RUN:   | FileCheck --check-prefix=CHECK-OPT %s
+
+// CHECK: define internal void @__f_block_invoke(i8* %.block_descriptor)
+// CHECK: %.block_descriptor.addr = alloca i8*, align 8
+// CHECK: %block.addr = alloca <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*, align 8
+// CHECK: store i8* %.block_descriptor, i8** %.block_descriptor.addr, align 8
+// CHECK: call void @llvm.dbg.declare(metadata i8** %.block_descriptor.addr,
+// CHECK-SAME:                        metadata !DIExpression())
+// CHECK-OPT-NOT: alloca
+// CHECK-OPT: call void @llvm.dbg.value(metadata i8* %.block_descriptor,
+// CHECK-OPT-SAME:                      metadata !DIExpression())
+void f() {
+  a(^{
+    b();
+  });
+}
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/sanitizer-special-case-list.c b/test/CodeGen/sanitizer-special-case-list.c
new file mode 100644
index 0000000..45cfecd
--- /dev/null
+++ b/test/CodeGen/sanitizer-special-case-list.c
@@ -0,0 +1,26 @@
+// Verify that blacklist sections correctly select sanitizers to apply blacklist entries to.
+//
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized1.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized2.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized3.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.unsanitized4.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=UNSANITIZED
+//
+// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow,cfi-icall -fsanitize-blacklist=%S/Inputs/sanitizer-special-case-list.sanitized.txt -emit-llvm %s -o - | FileCheck %s --check-prefix=SANITIZED
+
+unsigned i;
+
+// SANITIZED: @overflow
+// UNSANITIZED: @overflow
+unsigned overflow() {
+  // SANITIZED: call {{.*}}void @__ubsan
+  // UNSANITIZED-NOT: call {{.*}}void @__ubsan
+  return i * 37;
+}
+
+// SANITIZED: @cfi
+// UNSANITIZED: @cfi
+void cfi(void (*fp)()) {
+  // SANITIZED: llvm.type.test
+  // UNSANITIZED-NOT: llvm.type.test
+  fp();
+}
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/CodeGen/verify-debuginfo.ll b/test/CodeGen/verify-debuginfo.ll
new file mode 100644
index 0000000..0a18585
--- /dev/null
+++ b/test/CodeGen/verify-debuginfo.ll
@@ -0,0 +1,17 @@
+; REQUIRES: x86-registered-target
+; RUN: %clang_cc1 -triple i386-apple-darwin -disable-llvm-optzns -S %s -o - 2>&1 \
+; RUN:   | FileCheck %s
+; CHECK: invalid global variable ref
+; CHECK: warning: ignoring invalid debug info in {{.*}}.ll
+
+@global = common global i32 0, align 4, !dbg !2
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!5, !6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "adrian", emissionKind: FullDebug, globals: !{!3})
+!1 = !DIFile(filename: "broken.c", directory: "/")
+!2 = !DIGlobalVariableExpression(var: !3, expr: !DIExpression())
+!3 = !DIGlobalVariable(name: "g", scope: !0, file: !1, line: 1, type: !1, isLocal: false, isDefinition: true)
+!5 = !{i32 2, !"Dwarf Version", i32 4}
+!6 = !{i32 1, !"Debug Info Version", i32 3}
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/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index 5b7c7e6..37219d3 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -122,7 +122,6 @@
   // CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke
   // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
   // CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8
-  // CHECK-NEXT: load i8*, i8**
   // CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*
   // CHECK:      call void @_ZN5test41AC1Ev([[A]]* [[TMP]])
   // CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]])
diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp
index d58853c..e828753 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,26 +399,93 @@
   // 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);
 }
 
+namespace FunctionSanitizerVirtualCalls {
+struct A {
+  virtual void f() {}
+  virtual void g() {}
+  void h() {}
+};
+
+struct B : virtual A {
+  virtual void b() {}
+  virtual void f();
+  void g() final {}
+  static void q() {}
+};
+
+void B::f() {}
+
+void force_irgen() {
+  A a;
+  a.g();
+  a.h();
+
+  B b;
+  b.f();
+  b.b();
+  b.g();
+  B::q();
+}
+
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZTv0_n24_N29FunctionSanitizerVirtualCalls1B1fEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define void @_ZN29FunctionSanitizerVirtualCalls11force_irgenEv()
+// CHECK: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1AC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1A1hEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1BC1Ev
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1bEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1gEv
+// CHECK-NOT: prologue
+//
+// CHECK-LABEL: define linkonce_odr void @_ZN29FunctionSanitizerVirtualCalls1B1qEv
+// CHECK: prologue
+
+}
+
 namespace UpcastPointerTest {
 struct S {};
 struct T : S { double d; };
@@ -454,7 +525,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 +626,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/cfi-blacklist.cpp b/test/CodeGenCXX/cfi-blacklist.cpp
index af8a106..c01e5fc 100644
--- a/test/CodeGenCXX/cfi-blacklist.cpp
+++ b/test/CodeGenCXX/cfi-blacklist.cpp
@@ -1,6 +1,18 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
-// RUN: echo "type:std::*" > %t.txt
-// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+
+// Check that blacklisting cfi and cfi-vcall work correctly
+// RUN: echo "[cfi-vcall]" > %t.vcall.txt
+// RUN: echo "type:std::*" >> %t.vcall.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.vcall.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+//
+// RUN: echo "[cfi]" > %t.cfi.txt
+// RUN: echo "type:std::*" >> %t.cfi.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.cfi.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOSTD %s
+
+// Check that blacklisting non-vcall modes does not affect vcalls
+// RUN: echo "[cfi-icall|cfi-nvcall|cfi-cast-strict|cfi-derived-cast|cfi-unrelated-cast]" > %t.other.txt
+// RUN: echo "type:std::*" >> %t.other.txt
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fvisibility hidden -fms-extensions -fsanitize=cfi-vcall -fsanitize-blacklist=%t.other.txt -emit-llvm -o - %s | FileCheck --check-prefix=CHECK --check-prefix=NOBL %s
 
 struct S1 {
   virtual void f();
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-suppress-checks.cpp b/test/CodeGenCXX/ubsan-suppress-checks.cpp
index ae7c94b..fa7ea29 100644
--- a/test/CodeGenCXX/ubsan-suppress-checks.cpp
+++ b/test/CodeGenCXX/ubsan-suppress-checks.cpp
@@ -17,6 +17,17 @@
   // CHECK: ret void
 }
 
+// CHECK-LABEL: define void @_Z31use_us16_aligned_array_elementsv
+void use_us16_aligned_array_elements() {
+  static const unsigned short Arr[] = {0, 1, 2};
+  auto use_array = [](const unsigned short(&X)[3]) -> void {};
+  use_array(Arr);
+
+  // CHECK-NOT: br i1 true
+  // ALIGN-NOT: call void @__ubsan_handle_type_mismatch
+  // CHECK: ret void
+}
+
 struct A {
   int foo;
 
@@ -229,4 +240,5 @@
   d->load_member_3();
 
   load_non_null_pointers();
+  use_us16_aligned_array_elements();
 }
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
deleted file mode 100644
index e142a0b..0000000
--- a/test/CodeGenObjC/debug-info-block-captured-self.m
+++ /dev/null
@@ -1,72 +0,0 @@
-// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s
-//
-// Test that debug location is generated for a captured "self" inside
-// a block.
-//
-// This test is split into two parts, this one for the frontend, and
-// then llvm/test/DebugInfo/debug-info-block-captured-self.ll to
-// ensure that DW_AT_location is generated for the captured self.
-@class T;
-@interface S
-@end
-@interface Mode
--(int) count;
-@end
-@interface Context
-@end
-@interface ViewController
-@property (nonatomic, readwrite, strong) Context *context;
-@end
-typedef enum {
-    Unknown = 0,
-} State;
-@interface Main : ViewController
-{
-    T * t1;
-    T * t2;
-}
-@property(readwrite, nonatomic) State state;
-@end
-@implementation Main
-- (id) initWithContext:(Context *) context
-{
-    t1 = [self.context withBlock:^(id obj){
-        id *mode1;
-	t2 = [mode1 withBlock:^(id object){
-	    Mode *mode2 = object;
-	    if ([mode2 count] != 0) {
-	      self.state = 0;
-	    }
-	  }];
-      }];
-}
-@end
-// The important part of this test is that there is a dbg.value
-// intrinsic associated with the implicit .block_descriptor argument
-// of the block. We also test that this value gets alloca'd, so the
-// register llocator won't accidentally kill it.
-
-// outer block:
-// CHECK: define internal void {{.*}}_block_invoke{{.*}}
-
-// inner block:
-// CHECK: define internal void {{.*}}_block_invoke{{.*}}
-// CHECK:        %[[MEM1:.*]] = alloca i8*, align 8
-// CHECK-NEXT:   %[[MEM2:.*]] = alloca i8*, align 8
-// 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.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 !{{.*}})
-// make sure we are still in the same function
-// CHECK: define {{.*}}__copy_helper_block_
-// Metadata
-// CHECK: ![[MAIN:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Main"
-// CHECK-SAME:                            line: 23,
-// CHECK: ![[PMAIN:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[MAIN]],
-// CHECK: ![[BDMD]] = !DILocalVariable(name: ".block_descriptor", arg:
-// CHECK: ![[SELF]] = !DILocalVariable(name: "self"
-// CHECK-NOT:                          arg:
-// CHECK-SAME:                         line: 40,
diff --git a/test/CodeGenObjC/debug-info-blocks.m b/test/CodeGenObjC/debug-info-blocks.m
index 0bf5663..848e389 100644
--- a/test/CodeGenObjC/debug-info-blocks.m
+++ b/test/CodeGenObjC/debug-info-blocks.m
@@ -10,23 +10,20 @@
 // CHECK-NEXT: call void @llvm.dbg.declare(metadata <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>** %[[ALLOCA]], metadata ![[SELF:[0-9]+]], metadata !{{.*}})
 // CHECK-NEXT: call void @llvm.dbg.declare(metadata %1** %d, metadata ![[D:[0-9]+]], metadata !{{.*}})
 
-// rdar://problem/14386148
-// Test that we don't emit bogus line numbers for the helper functions.
-// Test that we do emit scope info for the helper functions.
+// Test that we do emit scope info for the helper functions, and that the
+// parameters to these functions are marked as artificial (so the debugger
+// doesn't accidentally step into the function).
 // CHECK: define {{.*}} @__copy_helper_block_{{.*}}(i8*, i8*)
 // CHECK-NOT: ret
 // CHECK: call {{.*}}, !dbg ![[DBG_LINE:[0-9]+]]
 // CHECK-NOT: ret
 // CHECK: load {{.*}}, !dbg ![[COPY_LINE:[0-9]+]]
+// CHECK: ret void, !dbg ![[COPY_LINE]]
 // CHECK: define {{.*}} @__destroy_helper_block_{{.*}}(i8*)
 // CHECK-NOT: ret
 // CHECK: load {{.*}}, !dbg ![[DESTROY_LINE:[0-9]+]]
+// CHECK: ret void, !dbg ![[DESTROY_LINE]]
 
-// CHECK-DAG: [[DBG_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
-// CHECK-DAG: [[COPY_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
-// CHECK-DAG: [[COPY_SP]] = distinct !DISubprogram(name: "__copy_helper_block_"
-// CHECK-DAG: [[DESTROY_LINE]] = !DILocation(line: 0, scope: ![[DESTROY_SP:[0-9]+]])
-// CHECK-DAG: [[DESTROY_SP]] = distinct !DISubprogram(name: "__destroy_helper_block_"
 typedef unsigned int NSUInteger;
 
 @protocol NSObject
@@ -60,6 +57,14 @@
 - (id)init
 {
     if ((self = [super init])) {
+      // CHECK-DAG: [[DBG_LINE]] = !DILocation(line: 0, scope: ![[COPY_SP:[0-9]+]])
+      // CHECK-DAG: [[COPY_LINE]] = !DILocation(line: [[@LINE+7]], scope: ![[COPY_SP:[0-9]+]])
+      // CHECK-DAG: [[COPY_SP]] = distinct !DISubprogram(name: "__copy_helper_block_"
+      // CHECK-DAG: [[DESTROY_LINE]] = !DILocation(line: [[@LINE+5]], scope: ![[DESTROY_SP:[0-9]+]])
+      // CHECK-DAG: [[DESTROY_SP]] = distinct !DISubprogram(name: "__destroy_helper_block_"
+      // CHECK-DAG: !DILocalVariable(arg: 1, scope: ![[COPY_SP]], {{.*}}, flags: DIFlagArtificial)
+      // CHECK-DAG: !DILocalVariable(arg: 2, scope: ![[COPY_SP]], {{.*}}, flags: DIFlagArtificial)
+      // CHECK-DAG: !DILocalVariable(arg: 1, scope: ![[DESTROY_SP]], {{.*}}, flags: DIFlagArtificial)
       run(^{
           // CHECK-DAG: ![[SELF]] = !DILocalVariable(name: "self", scope:{{.*}}, line: [[@LINE+4]],
           // CHECK-DAG: ![[D]] = !DILocalVariable(name: "d", scope:{{.*}}, line: [[@LINE+1]],
diff --git a/test/CodeGenObjC/ivar-layout-flexible-array.m b/test/CodeGenObjC/ivar-layout-flexible-array.m
new file mode 100644
index 0000000..c085cad
--- /dev/null
+++ b/test/CodeGenObjC/ivar-layout-flexible-array.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -Wno-objc-root-class -fobjc-arc -emit-llvm -o - %s | FileCheck %s
+
+// rdar://problem/21054495
+typedef char FlexibleArray[];
+
+struct Packet {
+  int size;
+  FlexibleArray data;
+};
+
+@interface VariableSizeIvar {
+  struct Packet flexible_struct;
+}
+@end
+@implementation VariableSizeIvar
+@end
+// CHECK: @OBJC_METH_VAR_NAME_{{.*}} = private unnamed_addr constant {{.*}} c"flexible_struct\00"
+// CHECK-NEXT: @OBJC_METH_VAR_TYPE_{{.*}} = private unnamed_addr constant {{.*}} c"{Packet=\22size\22i\22data\22[0c]}\00"
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/CodeGenObjC/os_log.m b/test/CodeGenObjC/os_log.m
index 5d48783..1cf0c9f 100644
--- a/test/CodeGenObjC/os_log.m
+++ b/test/CodeGenObjC/os_log.m
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O2 | FileCheck %s
+// RUN: %clang_cc1 %s -emit-llvm -o - -triple x86_64-darwin-apple -fobjc-arc -O0 | FileCheck %s -check-prefix=CHECK-O0
 
 // Make sure we emit clang.arc.use before calling objc_release as part of the
 // cleanup. This way we make sure the object will not be released until the
@@ -12,28 +13,67 @@
 // Behavior of __builtin_os_log differs between platforms, so only test on X86
 #ifdef __x86_64__
 // CHECK-LABEL: define i8* @test_builtin_os_log
+// CHECK-O0-LABEL: define i8* @test_builtin_os_log
+// CHECK: (i8* returned %[[BUF:.*]])
+// CHECK-O0: (i8* %[[BUF:.*]])
 void *test_builtin_os_log(void *buf) {
   return __builtin_os_log_format(buf, "capabilities: %@", GenString());
 
-  // CHECK: store i8 2, i8*
-  // CHECK: [[NUM_ARGS:%.*]] = getelementptr i8, i8* {{.*}}, i64 1
-  // CHECK: store i8 1, i8* [[NUM_ARGS]]
-  //
-  // CHECK: [[ARG1_DESC:%.*]] = getelementptr i8, i8* {{.*}}, i64 2
-  // CHECK: store i8 64, i8* [[ARG1_DESC]]
-  // CHECK: [[ARG1_SIZE:%.*]] = getelementptr i8, i8* {{.*}}, i64 3
-  // CHECK: store i8 8, i8* [[ARG1_SIZE]]
-  // CHECK: [[ARG1:%.*]] = getelementptr i8, i8* {{.*}}, i64 4
-  // CHECK: [[ARG1_CAST:%.*]] = bitcast i8* [[ARG1]] to
+  // CHECK: %[[CALL:.*]] = tail call %[[TY0:.*]]* (...) @GenString()
+  // CHECK: %[[V0:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8*
+  // CHECK: %[[V1:.*]] = tail call i8* @objc_retainAutoreleasedReturnValue(i8* %[[V0]])
+  // CHECK: %[[V2:.*]] = ptrtoint %[[TY0]]* %[[CALL]] to i64
+  // CHECK: store i8 2, i8* %[[BUF]], align 1
+  // CHECK: %[[NUMARGS_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+  // CHECK: store i8 1, i8* %[[NUMARGS_I]], align 1
+  // CHECK: %[[ARGDESCRIPTOR_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+  // CHECK: store i8 64, i8* %[[ARGDESCRIPTOR_I]], align 1
+  // CHECK: %[[ARGSIZE_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+  // CHECK: store i8 8, i8* %[[ARGSIZE_I]], align 1
+  // CHECK: %[[ARGDATA_I:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+  // CHECK: %[[ARGDATACAST_I:.*]] = bitcast i8* %[[ARGDATA_I]] to i64*
+  // CHECK: store i64 %[[V2]], i64* %[[ARGDATACAST_I]], align 1
+  // CHECK: tail call void (...) @clang.arc.use(%[[TY0]]* %[[CALL]])
+  // CHECK: tail call void @objc_release(i8* %[[V0]])
+  // CHECK: ret i8* %[[BUF]]
 
-  // CHECK: [[STRING:%.*]] = {{.*}} call {{.*}} @GenString()
-  // CHECK: [[STRING_CAST:%.*]] = bitcast {{.*}} [[STRING]] to
-  // CHECK: call {{.*}} @objc_retainAutoreleasedReturnValue(i8* [[STRING_CAST]])
-  // CHECK: store {{.*}} [[STRING]], {{.*}} [[ARG1_CAST]]
-
-  // CHECK: call void (...) @clang.arc.use({{.*}} [[STRING]])
-  // CHECK: call void @objc_release(i8* [[STRING_CAST]])
-  // CHECK: ret i8*
+  // clang.arc.use is used and removed in IR optimizations. At O0, we should not
+  // emit clang.arc.use, since it will not be removed and we will have a link
+  // error.
+  // CHECK-O0: %[[BUF_ADDR:.*]] = alloca i8*, align 8
+  // CHECK-O0: store i8* %[[BUF]], i8** %[[BUF_ADDR]], align 8
+  // CHECK-O0: %[[V0:.*]] = load i8*, i8** %[[BUF_ADDR]], align 8
+  // CHECK-O0: %[[CALL:.*]] = call %[[TY0:.*]]* (...) @GenString()
+  // CHECK-O0: %[[V1:.*]] = bitcast %[[TY0]]* %[[CALL]] to i8*
+  // CHECK-O0: %[[V2:.*]] = call i8* @objc_retainAutoreleasedReturnValue(i8* %[[V1]])
+  // CHECK-O0: %[[V3:.*]] = bitcast i8* %[[V2]] to %[[TY0]]*
+  // CHECK-O0: %[[V4:.*]] = ptrtoint %[[TY0]]* %[[V3]] to i64
+  // CHECK-O0: call void @__os_log_helper_1_2_1_8_64(i8* %[[V0]], i64 %[[V4]])
+  // CHECK-O0: %[[V5:.*]] = bitcast %[[TY0]]* %[[V3]] to i8*
+  // CHECK-O0-NOT call void (...) @clang.arc.use({{.*}}
+  // CHECK-O0: call void @objc_release(i8* %[[V5]])
+  // CHECK-O0: ret i8* %[[V0]]
 }
 
+// CHECK-O0-LABEL: define linkonce_odr hidden void @__os_log_helper_1_2_1_8_64
+// CHECK-O0: (i8* %[[BUFFER:.*]], i64 %[[ARG0:.*]])
+
+// CHECK-O0: %[[BUFFER_ADDR:.*]] = alloca i8*, align 8
+// CHECK-O0: %[[ARG0_ADDR:.*]] = alloca i64, align 8
+// CHECK-O0: store i8* %[[BUFFER]], i8** %[[BUFFER_ADDR]], align 8
+// CHECK-O0: store i64 %[[ARG0]], i64* %[[ARG0_ADDR]], align 8
+// CHECK-O0: %[[BUF:.*]] = load i8*, i8** %[[BUFFER_ADDR]], align 8
+// CHECK-O0: %[[SUMMARY:.*]] = getelementptr i8, i8* %[[BUF]], i64 0
+// CHECK-O0: store i8 2, i8* %[[SUMMARY]], align 1
+// CHECK-O0: %[[NUMARGS:.*]] = getelementptr i8, i8* %[[BUF]], i64 1
+// CHECK-O0: store i8 1, i8* %[[NUMARGS]], align 1
+// CHECK-O0: %[[ARGDESCRIPTOR:.*]] = getelementptr i8, i8* %[[BUF]], i64 2
+// CHECK-O0: store i8 64, i8* %[[ARGDESCRIPTOR]], align 1
+// CHECK-O0: %[[ARGSIZE:.*]] = getelementptr i8, i8* %[[BUF]], i64 3
+// CHECK-O0: store i8 8, i8* %[[ARGSIZE]], align 1
+// CHECK-O0: %[[ARGDATA:.*]] = getelementptr i8, i8* %[[BUF]], i64 4
+// CHECK-O0: %[[ARGDATACAST:.*]] = bitcast i8* %[[ARGDATA]] to i64*
+// CHECK-O0: %[[V0:.*]] = load i64, i64* %[[ARG0_ADDR]], align 8
+// CHECK-O0: store i64 %[[V0]], i64* %[[ARGDATACAST]], align 1
+
 #endif
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/Coverage/html-diagnostics.c b/test/Coverage/html-diagnostics.c
index 045943a..34b86cd 100644
--- a/test/Coverage/html-diagnostics.c
+++ b/test/Coverage/html-diagnostics.c
@@ -1,11 +1,18 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %t %s
 // RUN: find %t -name "*.html" -exec cat "{}" ";" | FileCheck %s
+//
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -analyze -analyzer-output=html-single-file -analyzer-checker=core -o %t %s
+// RUN: find %t -name "*.html" -exec cat "{}" ";" | FileCheck %s
 
 // REQUIRES: staticanalyzer
 
 // CHECK: <h3>Annotated Source Code</h3>
 
+// Make sure it's not generated as a multi-file HTML output
+// CHECK-NOT: <h4 class=FileName>{{.*}}
+
 // Without tweaking expr, the expr would hit to the line below
 // emitted to the output as comment.
 // CHECK: {{[D]ereference of null pointer}}
diff --git a/test/Coverage/html-multifile-diagnostics.c b/test/Coverage/html-multifile-diagnostics.c
new file mode 100644
index 0000000..abd54ae
--- /dev/null
+++ b/test/Coverage/html-multifile-diagnostics.c
@@ -0,0 +1,21 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -analyze -analyzer-output=html -analyzer-checker=core -o %t %s
+// RUN: find %t -name "*.html" -exec cat "{}" ";" | FileCheck %s
+
+// REQUIRES: staticanalyzer
+
+// CHECK: <h3>Annotated Source Code</h3>
+
+// Make sure it's generated as multi-file HTML output
+// CHECK: <h4 class=FileName>{{.*}}html-multifile-diagnostics.c</h4>
+// CHECK: <h4 class=FileName>{{.*}}html-multifile-diagnostics.h</h4>
+
+// Without tweaking expr, the expr would hit to the line below
+// emitted to the output as comment.
+// CHECK: {{[D]ereference of null pointer}}
+
+#include "html-multifile-diagnostics.h"
+
+void f0() {
+  f1((int*)0);
+}
diff --git a/test/Coverage/html-multifile-diagnostics.h b/test/Coverage/html-multifile-diagnostics.h
new file mode 100644
index 0000000..4a99ff0
--- /dev/null
+++ b/test/Coverage/html-multifile-diagnostics.h
@@ -0,0 +1,3 @@
+void f1(int *ptr) {
+  *ptr = 0;
+}
diff --git a/test/CoverageMapping/Inputs/deferred-region-helper.h b/test/CoverageMapping/Inputs/deferred-region-helper.h
new file mode 100644
index 0000000..c3e5c16
--- /dev/null
+++ b/test/CoverageMapping/Inputs/deferred-region-helper.h
@@ -0,0 +1,5 @@
+void included_func() {
+  if (false)
+    return;
+  return;
+}
diff --git a/test/CoverageMapping/break.c b/test/CoverageMapping/break.c
index ee41271..b15f60b 100644
--- a/test/CoverageMapping/break.c
+++ b/test/CoverageMapping/break.c
@@ -15,7 +15,7 @@
   }                  // CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:18 = ((#0 + #3) - #4)
   while(cnt < 100) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+7]]:4 = #3
                      // CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:16 = #3
-    if(cnt == 0) {   // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+3]]:6 = #4
+    if(cnt == 0) {   // CHECK: File 0, [[@LINE]]:18 -> [[@LINE+3]]:6 = #4
       break;
       ++cnt;         // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE+1]]:6 = 0
     }
@@ -23,8 +23,8 @@
   }                  // CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:18 = (#0 + #6)
   while(cnt < 100) { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+8]]:4 = #5
                      // CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:16 = #5
-    if(cnt == 0) {   // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE+2]]:6 = #6
-      ++cnt;
+    if(cnt == 0) {   // CHECK: File 0, [[@LINE]]:18 -> [[@LINE+2]]:6 = #6
+      ++cnt;         // CHECK-NEXT: Gap,File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = (#5 - #6)
     } else {         // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = (#5 - #6)
       break;
     }
diff --git a/test/CoverageMapping/casts.c b/test/CoverageMapping/casts.c
index d295f31..6f479fd 100644
--- a/test/CoverageMapping/casts.c
+++ b/test/CoverageMapping/casts.c
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name casts.c %s | FileCheck %s
 
 int main() {                                                   // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+4]]:2 = #0
-                                                               // CHECK-NEXT: File 0, [[@LINE+1]]:41 -> [[@LINE+1]]:54 = #1
+                                                               // CHECK: File 0, [[@LINE+1]]:41 -> [[@LINE+1]]:54 = #1
   int window_size = (sizeof(int) <= 2 ? (unsigned)512 : 1024); // CHECK-NEXT: File 0, [[@LINE]]:57 -> [[@LINE]]:61 = (#0 - #1)
   return 0;
 }
diff --git a/test/CoverageMapping/continue.c b/test/CoverageMapping/continue.c
index 7ea03fb..de11bfe 100644
--- a/test/CoverageMapping/continue.c
+++ b/test/CoverageMapping/continue.c
@@ -8,16 +8,16 @@
       if(i < 5) {               // CHECK: File 0, [[@LINE]]:17 -> [[@LINE+3]]:8 = #3
         continue;
         j = 1;                   // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE+1]]:8 = 0
-      } else {                   // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:8 = (#2 - #3)
+      } else {                   // CHECK: File 0, [[@LINE]]:14 -> [[@LINE+2]]:8 = (#2 - #3)
         j = 2;
       }
       j = 3;                     // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE+6]]:6 = (#2 - #3)
       if(i < 7) {                // CHECK: File 0, [[@LINE]]:17 -> [[@LINE+3]]:8 = #4
         continue;
         j = 4;                   // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE+1]]:8 = 0
-      } else j = 5;              // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE]]:19 = ((#2 - #3) - #4)
+      } else j = 5;              // CHECK: File 0, [[@LINE]]:14 -> [[@LINE]]:19 = ((#2 - #3) - #4)
       j = 6;                     // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE+1]]:6 = ((#2 - #3) - #4)
-    } else                       // CHECK-NEXT: File 0, [[@LINE+1]]:7 -> [[@LINE+1]]:12 = (#1 - #2)
+    } else                       // CHECK: File 0, [[@LINE+1]]:7 -> [[@LINE+1]]:12 = (#1 - #2)
       j = 7;
     j = 8;                       // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+1]]:4 = ((#1 - #3) - #4)
   }
diff --git a/test/CoverageMapping/deferred-region.cpp b/test/CoverageMapping/deferred-region.cpp
new file mode 100644
index 0000000..5a104f7
--- /dev/null
+++ b/test/CoverageMapping/deferred-region.cpp
@@ -0,0 +1,204 @@
+// 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 -I %S/Inputs %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 -> [[@LINE+2]]:3 = (#0 - #1)
+
+  return; // CHECK-NOT: Gap
+}
+
+// CHECK-LABEL: _Z4maazv:
+void maaz() {
+  if (true)
+    return; // CHECK: Gap,File 0, [[@LINE]]:11
+  else
+    return; // CHECK-NOT: Gap,File 0, [[@LINE]]
+}
+
+// CHECK-LABEL: _Z5maaazv:
+void maaaz() {
+  if (true) {
+    return;
+  } else {  // CHECK: Gap,File 0, [[@LINE]]:4 -> [[@LINE]]:10
+    return; // CHECK-NOT: Gap,File 0, [[@LINE]]
+  }
+}
+
+// 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
+}
+
+#include "deferred-region-helper.h"
+// CHECK-LABEL: _Z13included_funcv:
+// CHECK:  Gap,File 0, 2:13 -> 3:5 = #1
+// CHECK:  Gap,File 0, 3:11 -> 4:3 = (#0 - #1)
+
+// CHECK-LABEL: _Z7includev:
+void include() {
+  included_func();
+}
+
+int main() {
+  foo(0);
+  foo(1);
+  fooo(0);
+  fooo(1);
+  maz();
+  maaz();
+  maaaz();
+  baz();
+  bar(0);
+  bar(1);
+  quux(0);
+  quux(1);
+  quux(2);
+  quux(3);
+  weird_if();
+  for_loop();
+  while_loop();
+  gotos();
+  include();
+  return 0;
+}
diff --git a/test/CoverageMapping/if.cpp b/test/CoverageMapping/if.cpp
index 95e6d8a..f4c041a 100644
--- a/test/CoverageMapping/if.cpp
+++ b/test/CoverageMapping/if.cpp
@@ -3,35 +3,41 @@
 int nop() { return 0; }
 
 // CHECK-LABEL: _Z3foov:
-void foo() {                    // CHECK-NEXT: [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
+                                // CHECK-NEXT: [[@LINE+1]]:12 -> [[@LINE+6]]:2 = #0
+void foo() {                    // CHECK-NEXT: Gap,File 0, [[@LINE+1]]:20 -> [[@LINE+1]]:22 = #2
   if (int j = true ? nop()      // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = #2
                    : nop();     // CHECK-NEXT: [[@LINE]]:22 -> [[@LINE]]:27 = (#0 - #2)
       j)                        // CHECK-NEXT: [[@LINE]]:7 -> [[@LINE]]:8 = #0
-    ++j;                        // CHECK-NEXT: [[@LINE]]:5 -> [[@LINE]]:8 = #1
-}
+    ++j;                        // CHECK-NEXT: [[@LINE-1]]:9 -> [[@LINE]]:5 = #1
+}                               // CHECK-NEXT: [[@LINE-1]]:5 -> [[@LINE-1]]:8 = #1
 
 // CHECK-LABEL: main:
 int main() {                    // CHECK: File 0, [[@LINE]]:12 -> {{[0-9]+}}:2 = #0
   int i = 0;
-                                // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
+                                // CHECK-NEXT: File 0, [[@LINE+2]]:6 -> [[@LINE+2]]:12 = #0
+                                // CHECK-NEXT: Gap,File 0, [[@LINE+1]]:13 -> [[@LINE+1]]:14 = #1
   if(i == 0) i = 1;             // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE]]:19 = #1
+
                                 // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
-  if(i == 1)
+  if(i == 1)                    // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+1]]:5 = #2
     i = 2;                      // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:10 = #2
+
                                 // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
-  if(i == 0) { i = 1;           // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #3
-    i = 2;
+  if(i == 0) { i = 1;           // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE]]:14 = #3
+    i = 2;                      // CHECK-NEXT: File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:4 = #3
   }
                                 // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:12 = #0
-  if(i != 0) {                  // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+2]]:4 = #4
-    i = 1;
-  } else {                      // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE+2]]:4 = (#0 - #4)
-    i = 3;
+  if(i != 0) {                  // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE]]:14 = #4
+    i = 1;                      // CHECK-NEXT: File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:4 = #4
+  } else {                      // CHECK-NEXT: Gap,File 0, [[@LINE]]:4 -> [[@LINE]]:10 = (#0 - #4)
+    i = 3;                      // CHECK-NEXT: File 0, [[@LINE-1]]:10 -> [[@LINE+1]]:4 = (#0 - #4)
   }
 
-  i = i == 0?
+  i = i == 0?                   // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+1]]:9 = #5
         i + 1 :                 // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:14 = #5
         i + 2;                  // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:14 = (#0 - #5)
+
+                                // CHECK-NEXT: Gap,File 0, [[@LINE+2]]:13 -> [[@LINE+2]]:14 = #6
                                 // CHECK-NEXT: File 0, [[@LINE+1]]:14 -> [[@LINE+1]]:20 = #6
   i = i == 0?i + 12:i + 10;     // CHECK-NEXT: File 0, [[@LINE]]:21 -> [[@LINE]]:27 = (#0 - #6)
 
diff --git a/test/CoverageMapping/includehell.cpp b/test/CoverageMapping/includehell.cpp
index 9ad3683..91b1058 100644
--- a/test/CoverageMapping/includehell.cpp
+++ b/test/CoverageMapping/includehell.cpp
@@ -52,28 +52,28 @@
 
 // CHECK-CODE:      File [[CODE1:[0-9]]], 1:1 -> 14:1 = #1
 // CHECK-CODE-NEXT: File [[CODE1]], 4:5 -> 4:11 = #1
-// CHECK-CODE-NEXT: File [[CODE1]], 4:13 -> 6:2 = #2
-// CHECK-CODE-NEXT: File [[CODE1]], 6:8 -> 8:2 = (#1 - #2)
+// CHECK-CODE: File [[CODE1]], 4:13 -> 6:2 = #2
+// CHECK-CODE: File [[CODE1]], 6:8 -> 8:2 = (#1 - #2)
 // CHECK-CODE-NEXT: File [[CODE1]], 9:5 -> 9:9 = #1
-// CHECK-CODE-NEXT: File [[CODE1]], 9:11 -> 11:2 = #3
-// CHECK-CODE-NEXT: File [[CODE1]], 11:8 -> 13:2 = (#1 - #3)
+// CHECK-CODE: File [[CODE1]], 9:11 -> 11:2 = #3
+// CHECK-CODE: File [[CODE1]], 11:8 -> 13:2 = (#1 - #3)
 // CHECK-CODE:      File [[CODE2:[0-9]]], 1:1 -> 14:1 = #5
 // CHECK-CODE-NEXT: File [[CODE2]], 4:5 -> 4:11 = #5
-// CHECK-CODE-NEXT: File [[CODE2]], 4:13 -> 6:2 = #6
-// CHECK-CODE-NEXT: File [[CODE2]], 6:8 -> 8:2 = (#5 - #6)
+// CHECK-CODE: File [[CODE2]], 4:13 -> 6:2 = #6
+// CHECK-CODE: File [[CODE2]], 6:8 -> 8:2 = (#5 - #6)
 // CHECK-CODE-NEXT: File [[CODE2]], 9:5 -> 9:9 = #5
-// CHECK-CODE-NEXT: File [[CODE2]], 9:11 -> 11:2 = #7
-// CHECK-CODE-NEXT: File [[CODE2]], 11:8 -> 13:2 = (#5 - #7)
+// CHECK-CODE: File [[CODE2]], 9:11 -> 11:2 = #7
+// CHECK-CODE: File [[CODE2]], 11:8 -> 13:2 = (#5 - #7)
 
 // CHECK-END:      File [[END1:[0-9]]], 1:1 -> 3:2 = #1
 // CHECK-END-NEXT: File [[END1]], 1:1 -> 6:1 = #0
 // CHECK-END-NEXT: File [[END1]], 5:5 -> 5:9 = #0
-// CHECK-END-NEXT: File [[END1]], 5:11 -> 5:16 = #4
+// CHECK-END: File [[END1]], 5:11 -> 5:16 = #4
 // CHECK-END:      File [[END2:[0-9]]], 1:1 -> 3:2 = #5
 // CHECK-END-NEXT: File [[END2]], 1:1 -> 6:1 = #0
 // CHECK-END-NEXT: File [[END2]], 5:5 -> 5:9 = #0
-// CHECK-END-NEXT: File [[END2]], 5:11 -> 5:16 = #8
+// CHECK-END: File [[END2]], 5:11 -> 5:16 = #8
 // CHECK-END:      File [[END3:[0-9]]], 1:1 -> 3:2 = #9
 // CHECK-END-NEXT: File [[END3]], 1:1 -> 6:1 = #0
 // CHECK-END-NEXT: File [[END3]], 5:5 -> 5:9 = #0
-// CHECK-END-NEXT: File [[END3]], 5:11 -> 5:16 = #10
+// CHECK-END: File [[END3]], 5:11 -> 5:16 = #10
diff --git a/test/CoverageMapping/label.cpp b/test/CoverageMapping/label.cpp
index 1c5111a6..a0bd4fd 100644
--- a/test/CoverageMapping/label.cpp
+++ b/test/CoverageMapping/label.cpp
@@ -6,27 +6,30 @@
                              // CHECK-NEXT: File 0, [[@LINE+1]]:22 -> [[@LINE+1]]:25 = #3
   for(i = 0; i < 10; ++i) {  // CHECK-NEXT: File 0, [[@LINE]]:27 -> [[@LINE+11]]:4 = #1
                              // CHECK-NEXT: File 0, [[@LINE+1]]:8 -> [[@LINE+1]]:13 = #1
-    if(i < 5) {              // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+6]]:6 = #2
+    if(i < 5) {              // CHECK: File 0, [[@LINE]]:15 -> [[@LINE+6]]:6 = #2
       {
         x:                   // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE+4]]:6 = #3
           int j = 1;
       }
       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)
+      goto x;                // CHECK: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = (#1 - #2)
+    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
+    goto x;                  // CHECK: 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)
+    goto a;                  // CHECK: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
+                             // CHECK-NEXT: File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = (#0 - #1)
+  goto b;                    // CHECK: Gap,File 0, [[@LINE]]:3 -> [[@LINE+5]]:2 = #3
+                             // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:9 -> [[@LINE+1]]:1 = #2
 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;
@@ -35,10 +38,12 @@
                              // CHECK-NEXT: test2
 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)
+    goto a;                  // CHECK: File 0, [[@LINE]]:5 -> [[@LINE]]:11 = #1
+                             // CHECK: Gap,File 0, [[@LINE-1]]:12 -> [[@LINE+3]]:8 = (#0 - #1)
+                             // 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: 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)
+      goto e;                // CHECK: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = #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)
+                             // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = #4
   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/logical.cpp b/test/CoverageMapping/logical.cpp
index 198cc60..bc7c785 100644
--- a/test/CoverageMapping/logical.cpp
+++ b/test/CoverageMapping/logical.cpp
@@ -1,13 +1,18 @@
 // RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name logical.cpp %s | FileCheck %s
 
-int main() {                        // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+10]]:2 = #0
+int main() {                        // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+15]]:2 = #0
   bool bt = true;
   bool bf = false;
-  bool a = bt && bf;                // CHECK-NEXT: File 0, [[@LINE]]:18 -> [[@LINE]]:20 = #1
-  a = bt &&
+  bool a = bt && bf;                // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE]]:14 = #0
+                                    // CHECK-NEXT: File 0, [[@LINE-1]]:18 -> [[@LINE-1]]:20 = #1
+
+  a = bt &&                         // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #0
       bf;                           // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #2
-  a = bf || bt;                     // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE]]:15 = #3
-  a = bf ||
+
+  a = bf || bt;                     // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #0
+                                    // CHECK-NEXT: File 0, [[@LINE-1]]:13 -> [[@LINE-1]]:15 = #3
+
+  a = bf ||                         // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #0
       bt;                           // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:9 = #4
   return 0;
 }
diff --git a/test/CoverageMapping/macro-expansion.c b/test/CoverageMapping/macro-expansion.c
index 3fca975..1e4a28b 100644
--- a/test/CoverageMapping/macro-expansion.c
+++ b/test/CoverageMapping/macro-expansion.c
@@ -4,18 +4,18 @@
 // CHECK:      File 1, [[@LINE+5]]:12 -> [[@LINE+5]]:38 = #0
 // CHECK-NEXT: File 1, [[@LINE+4]]:15 -> [[@LINE+4]]:28 = (#0 + #2)
 // CHECK-NEXT: File 1, [[@LINE+3]]:21 -> [[@LINE+3]]:22 = (#0 + #2)
-// CHECK-NEXT: File 1, [[@LINE+2]]:24 -> [[@LINE+2]]:26 = #3
+// CHECK: File 1, [[@LINE+2]]:24 -> [[@LINE+2]]:26 = #3
 // CHECK-NEXT: File 1, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = (#0 + #2)
 #define M1 do { if (0) {} } while (0)
 // CHECK-NEXT: File 2, [[@LINE+10]]:15 -> [[@LINE+10]]:41 = #0
 // CHECK-NEXT: File 2, [[@LINE+9]]:18 -> [[@LINE+9]]:31 = (#0 + #4)
 // CHECK-NEXT: File 2, [[@LINE+8]]:24 -> [[@LINE+8]]:25 = (#0 + #4)
-// CHECK-NEXT: File 2, [[@LINE+7]]:27 -> [[@LINE+7]]:29 = #5
+// CHECK: File 2, [[@LINE+7]]:27 -> [[@LINE+7]]:29 = #5
 // CHECK-NEXT: File 2, [[@LINE+6]]:39 -> [[@LINE+6]]:40 = (#0 + #4)
 // CHECK-NEXT: File 3, [[@LINE+5]]:15 -> [[@LINE+5]]:41 = #0
 // CHECK-NEXT: File 3, [[@LINE+4]]:18 -> [[@LINE+4]]:31 = (#0 + #6)
 // CHECK-NEXT: File 3, [[@LINE+3]]:24 -> [[@LINE+3]]:25 = (#0 + #6)
-// CHECK-NEXT: File 3, [[@LINE+2]]:27 -> [[@LINE+2]]:29 = #7
+// CHECK: File 3, [[@LINE+2]]:27 -> [[@LINE+2]]:29 = #7
 // CHECK-NEXT: File 3, [[@LINE+1]]:39 -> [[@LINE+1]]:40 = (#0 + #6)
 #define M2(x) do { if (x) {} } while (0)
 // CHECK-NEXT: File 4, [[@LINE+4]]:15 -> [[@LINE+4]]:38 = #0
@@ -23,10 +23,12 @@
 // CHECK-NEXT: Expansion,File 4, [[@LINE+2]]:20 -> [[@LINE+2]]:22 = (#0 + #8)
 // CHECK-NEXT: File 4, [[@LINE+1]]:36 -> [[@LINE+1]]:37 = (#0 + #8)
 #define M3(x) do { M2(x); } while (0)
-// CHECK-NEXT: File 5, [[@LINE+2]]:15 -> [[@LINE+2]]:27 = #0
+// CHECK-NEXT: File 5, [[@LINE+3]]:15 -> [[@LINE+3]]:27 = #0
+// CHECK-NEXT: File 5, [[@LINE+2]]:16 -> [[@LINE+2]]:19 = #0
 // CHECK-NEXT: File 5, [[@LINE+1]]:23 -> [[@LINE+1]]:26 = #12
 #define M4(x) ((x) && (x))
-// CHECK-NEXT: File 6, [[@LINE+2]]:15 -> [[@LINE+2]]:27 = #0
+// CHECK-NEXT: File 6, [[@LINE+3]]:15 -> [[@LINE+3]]:27 = #0
+// CHECK-NEXT: File 6, [[@LINE+2]]:16 -> [[@LINE+2]]:19 = #0
 // CHECK-NEXT: File 6, [[@LINE+1]]:23 -> [[@LINE+1]]:26 = #14
 #define M5(x) ((x) || (x))
 // CHECK-NEXT: File 7, [[@LINE+1]]:15 -> [[@LINE+1]]:26 = #0
@@ -38,7 +40,7 @@
 // CHECK-NEXT: File 9, {{[0-9]+}}:15 -> {{[0-9]+}}:41 = (#0 + #8)
 // CHECK-NEXT: File 9, {{[0-9]+}}:18 -> {{[0-9]+}}:31 = ((#0 + #8) + #9)
 // CHECK-NEXT: File 9, {{[0-9]+}}:24 -> {{[0-9]+}}:25 = ((#0 + #8) + #9)
-// CHECK-NEXT: File 9, {{[0-9]+}}:27 -> {{[0-9]+}}:29 = #10
+// CHECK: File 9, {{[0-9]+}}:27 -> {{[0-9]+}}:29 = #10
 // CHECK-NEXT: File 9, {{[0-9]+}}:39 -> {{[0-9]+}}:40 = ((#0 + #8) + #9)
 
 void func(int x) {
diff --git a/test/CoverageMapping/macro-expressions.cpp b/test/CoverageMapping/macro-expressions.cpp
index 3eba869..efdd83d 100644
--- a/test/CoverageMapping/macro-expressions.cpp
+++ b/test/CoverageMapping/macro-expressions.cpp
@@ -54,7 +54,7 @@
 // CHECK-NEXT: File 0, [[@LINE+1]]:17 -> {{[0-9]+}}:2 = #0
 void foo(int i) {
   // CHECK-NEXT: File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:8 = #0
-  // CHECK-NEXT: File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:12 = #1
+  // CHECK: File 0, [[@LINE+1]]:10 -> [[@LINE+1]]:12 = #1
   if (0) {}
 
   // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:7 -> [[@LINE+2]]:11 = #0
@@ -86,10 +86,10 @@
   // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:23 -> [[@LINE+1]]:29 = #0
   (void)(i ? PRIo64 : PRIu64);
 
-  // CHECK-NEXT: File 0, [[@LINE+5]]:14 -> [[@LINE+5]]:15 = #9
+  // CHECK: File 0, [[@LINE+5]]:14 -> [[@LINE+5]]:15 = #9
   // CHECK-NEXT: Expansion,File 0, [[@LINE+4]]:18 -> [[@LINE+4]]:22 = (#0 - #9)
   // CHECK-NEXT: File 0, [[@LINE+3]]:22 -> [[@LINE+3]]:33 = (#0 - #9)
-  // CHECK-NEXT: File 0, [[@LINE+2]]:28 -> [[@LINE+2]]:29 = #10
+  // CHECK: File 0, [[@LINE+2]]:28 -> [[@LINE+2]]:29 = #10
   // CHECK-NEXT: File 0, [[@LINE+1]]:32 -> [[@LINE+1]]:33 = ((#0 - #9) - #10)
   (void)(i ? i : EXPR(i) ? i : 0);
   // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:15 -> [[@LINE+3]]:19 = (#0 - #11)
diff --git a/test/CoverageMapping/macroscopes.cpp b/test/CoverageMapping/macroscopes.cpp
index f5fd55c..3f5f65e 100644
--- a/test/CoverageMapping/macroscopes.cpp
+++ b/test/CoverageMapping/macroscopes.cpp
@@ -89,10 +89,10 @@
 // CHECK-NEXT: File 1, 3:52 -> 3:53 = #1
 // CHECK-NEXT: File 2, 10:3 -> 20:4 = #1
 // CHECK-NEXT: File 2, 11:7 -> 11:13 = #1
-// CHECK-NEXT: File 2, 11:15 -> 13:4 = #2
+// CHECK: File 2, 11:15 -> 13:4 = #2
 // CHECK-NEXT: File 2, 13:10 -> 15:4 = (#1 - #2)
 // CHECK-NEXT: File 2, 16:7 -> 16:11 = #1
-// CHECK-NEXT: File 2, 16:13 -> 18:4 = #3
+// CHECK: File 2, 16:13 -> 18:4 = #3
 // CHECK-NEXT: File 2, 18:10 -> 20:4 = (#1 - #3)
 // CHECK-NEXT: File 3, 6:3 -> 7:4 = #1
 // CHECK-NEXT: File 4, 3:24 -> 3:53 = #0
@@ -101,10 +101,10 @@
 // CHECK-NEXT: File 4, 3:52 -> 3:53 = #4
 // CHECK-NEXT: File 5, 10:3 -> 20:4 = #4
 // CHECK-NEXT: File 5, 11:7 -> 11:13 = #4
-// CHECK-NEXT: File 5, 11:15 -> 13:4 = #5
+// CHECK: File 5, 11:15 -> 13:4 = #5
 // CHECK-NEXT: File 5, 13:10 -> 15:4 = (#4 - #5)
 // CHECK-NEXT: File 5, 16:7 -> 16:11 = #4
-// CHECK-NEXT: File 5, 16:13 -> 18:4 = #6
+// CHECK: File 5, 16:13 -> 18:4 = #6
 // CHECK-NEXT: File 5, 18:10 -> 20:4 = (#4 - #6)
 // CHECK-NEXT: File 6, 6:3 -> 7:4 = #4
 // CHECK-NEXT: File 7, 3:24 -> 3:53 = #0
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..88411f3 100644
--- a/test/CoverageMapping/moremacros.c
+++ b/test/CoverageMapping/moremacros.c
@@ -7,7 +7,7 @@
 // CHECK-NEXT: File 0, [[@LINE+1]]:40 -> {{[0-9]+}}:2 = #0
 int main(int argc, const char *argv[]) {
   // CHECK-NEXT: File 0, [[@LINE+1]]:7 -> [[@LINE+1]]:12 = #0
-  if (!argc) {} // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE]]:16 = #1
+  if (!argc) {} // CHECK: File 0, [[@LINE]]:14 -> [[@LINE]]:16 = #1
 
   // CHECK-NEXT: File 0, [[@LINE+3]]:7 -> [[@LINE+3]]:12 = #0
   // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:14 -> [[@LINE+2]]:19 = #2
@@ -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,15 +23,15 @@
   // 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)
-  // CHECK-NEXT: File 0, [[@LINE+1]]:14 -> [[@LINE+4]]:8 = #4
+  // CHECK: File 0, [[@LINE+1]]:14 -> [[@LINE+4]]:8 = #4
   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/objc.m b/test/CoverageMapping/objc.m
index 55c7545..ab361d7 100644
--- a/test/CoverageMapping/objc.m
+++ b/test/CoverageMapping/objc.m
@@ -7,7 +7,7 @@
                       // CHECK: func
 void func(A *a) {     // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+3]]:2 = #0
   if (a)              // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:8 = #0
-    [a bork:  20  ];  // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:20 = #1
+    [a bork:  20  ];  // CHECK: File 0, [[@LINE]]:5 -> [[@LINE]]:20 = #1
 }
 
 @interface NSArray
@@ -20,9 +20,9 @@
   int i = 0;
   for (NSArray *x in array) {  // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+7]]:4 = #1
                                // CHECK-NEXT: File 0, [[@LINE+1]]:9 -> [[@LINE+1]]:10 = #1
-    if (x) {                   // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = #2
+    if (x) {                   // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = #2
       i = 1;
-    } else {                   // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = (#1 - #2)
+    } else {                   // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = (#1 - #2)
       i = -1;
     }
   }
diff --git a/test/CoverageMapping/preprocessor.c b/test/CoverageMapping/preprocessor.c
index bd82b39..b3ebc7b 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
+  if(i == 0) {   // CHECK: 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..0a20840 100644
--- a/test/CoverageMapping/return.c
+++ b/test/CoverageMapping/return.c
@@ -12,13 +12,13 @@
                                 // CHECK-NEXT: File 0, [[@LINE+1]]:26 -> [[@LINE+1]]:29 = (#1 - #2)
   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;
+    if(i > 2) {                 // CHECK: File 0, [[@LINE]]:15 -> [[@LINE+2]]:6 = #2
+      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
+    if(i == 3) {                // CHECK: File 0, [[@LINE]]:16 -> [[@LINE+2]]:6 = #3
       int j = 1;
-    } else {                    // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = ((#1 - #2) - #3)
+    } else {                    // CHECK: File 0, [[@LINE]]:12 -> [[@LINE+2]]:6 = ((#1 - #2) - #3)
       int j = 2;
     }
   }
@@ -27,7 +27,7 @@
                                // CHECK-NEXT: func3
 void func3(int x) {            // CHECK-NEXT: File 0, [[@LINE]]:19 -> {{[0-9]+}}:2 = #0
                                // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:11 = #0
-  if(x > 5) {                  // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE+6]]:4 = #1
+  if(x > 5) {                  // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+6]]:4 = #1
     while(x >= 9) {            // CHECK-NEXT: File 0, [[@LINE]]:11 -> [[@LINE]]:17 = #1
       return;                  // CHECK-NEXT: File 0, [[@LINE-1]]:19 -> [[@LINE+2]]:6 = #2
       --x;                     // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE+1]]:6 = 0
diff --git a/test/CoverageMapping/switch.cpp b/test/CoverageMapping/switch.cpp
index 312f26c..30c6492 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
 }
@@ -38,7 +38,7 @@
 
                     // CHECK: baz
 void baz() {        // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
-  switch (int i = true ? nop()  // CHECK-NEXT: [[@LINE]]:26 -> [[@LINE]]:31 = #2
+  switch (int i = true ? nop()  // CHECK: [[@LINE]]:26 -> [[@LINE]]:31 = #2
                        : nop(); // CHECK-NEXT: [[@LINE]]:26 -> [[@LINE]]:31 = (#0 - #2)
           i) {}
   nop();            // CHECK-NEXT: [[@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..f4c14f7 100644
--- a/test/CoverageMapping/switchmacro.c
+++ b/test/CoverageMapping/switchmacro.c
@@ -7,12 +7,13 @@
   switch (i) {
   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
+      return 0;  // CHECK: 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);
   case 0:        // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:13 = ((#2 + #4) - #3)
-    return 2;
+    return 2;    // CHECK-NEXT: Gap,File 0, [[@LINE]]:13 -> [[@LINE+6]]:3 = #5
 
   // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:3 -> [[@LINE+2]]:6 = 0
   // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> {{[0-9]+}}:11 = 0
diff --git a/test/CoverageMapping/test.c b/test/CoverageMapping/test.c
index 5affbaa..8065598 100644
--- a/test/CoverageMapping/test.c
+++ b/test/CoverageMapping/test.c
@@ -16,7 +16,7 @@
                                  // CHECK-NEXT: foo
 void foo() {                     // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+5]]:2 = #0
                                  // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:7 = #0
-  if(1) {                        // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE+2]]:4 = #1
+  if(1) {                        // CHECK: File 0, [[@LINE]]:9 -> [[@LINE+2]]:4 = #1
     int i = 0;
   }
 }
diff --git a/test/CoverageMapping/trycatch.cpp b/test/CoverageMapping/trycatch.cpp
index 01d8fb9..5603543 100644
--- a/test/CoverageMapping/trycatch.cpp
+++ b/test/CoverageMapping/trycatch.cpp
@@ -12,13 +12,13 @@
                                       // CHECK: func
 void func(int i) {                    // CHECK-NEXT: File 0, [[@LINE]]:18 -> {{[0-9]+}}:2 = #0
                                       // CHECK-NEXT: File 0, [[@LINE+1]]:6 -> [[@LINE+1]]:11 = #0
-  if(i % 2) {                         // CHECK-NEXT: File 0, [[@LINE]]:13 -> [[@LINE+4]]:4 = #1
+  if(i % 2) {                         // CHECK: File 0, [[@LINE]]:13 -> [[@LINE+4]]:4 = #1
     throw Error();
     int j = 0;                        // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = 0
-                                      // CHECK-NEXT: File 0, [[@LINE+1]]:10 -> [[@LINE+2]]:27 = (#0 - #1)
+                                      // CHECK: 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
-}
+    throw ImportantError();           // CHECK: 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/cuda-bail-out.cu b/test/Driver/cuda-bail-out.cu
new file mode 100644
index 0000000..aaf7714
--- /dev/null
+++ b/test/Driver/cuda-bail-out.cu
@@ -0,0 +1,54 @@
+// Test clang driver bails out after one error during CUDA compilation.
+
+// REQUIRES: clang-driver
+// REQUIRES: powerpc-registered-target
+// REQUIRES: nvptx-registered-target
+
+#ifdef FORCE_ERROR
+#error compilation failed
+#endif
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DFORCE_ERROR %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DFORCE_ERROR --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DFORCE_ERROR --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   --cuda-device-only %s 2>&1 | FileCheck %s
+
+#if defined(ERROR_HOST) && !defined(__CUDA_ARCH__)
+#error compilation failed
+#endif
+
+#if defined(ERROR_SM35) && (__CUDA_ARCH__ == 350)
+#error compilation failed
+#endif
+
+#if defined(ERROR_SM60) && (__CUDA_ARCH__ == 600)
+#error compilation failed
+#endif
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_HOST --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_SM35 --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   --cuda-device-only %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_SM60 --cuda-gpu-arch=sm_35 --cuda-gpu-arch=sm_60 \
+// RUN:   --cuda-device-only %s 2>&1 | FileCheck %s
+
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_HOST -DERROR_SM35 --cuda-gpu-arch=sm_35 \
+// RUN:   --cuda-gpu-arch=sm_60 %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_HOST -DERROR_SM60 --cuda-gpu-arch=sm_35 \
+// RUN:   --cuda-gpu-arch=sm_60 %s 2>&1 | FileCheck %s
+// RUN: not %clang -target powerpc64le-ibm-linux-gnu -fsyntax-only -nocudalib \
+// RUN:   -nocudainc -DERROR_SM35 -DERROR_SM60 --cuda-gpu-arch=sm_35 \
+// RUN:   --cuda-gpu-arch=sm_60 %s 2>&1 | FileCheck %s
+
+
+// CHECK: error: compilation failed
+// CHECK-NOT: error: compilation failed
diff --git a/test/Driver/darwin-ld.c b/test/Driver/darwin-ld.c
index 36e7ee5..3ddba02 100644
--- a/test/Driver/darwin-ld.c
+++ b/test/Driver/darwin-ld.c
@@ -341,3 +341,27 @@
 // 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"
+
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Wl,-exported_symbols_list,/dev/null -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Wl,-exported_symbol,foo -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Xlinker -exported_symbol -Xlinker foo -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -Xlinker -exported_symbols_list -Xlinker /dev/null -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=PROFILE_EXPORT %s < %t.log
+// PROFILE_EXPORT: "-exported_symbol" "_VPMergeHook" "-exported_symbol" "___llvm_profile_filename" "-exported_symbol" "___llvm_profile_raw_version" "-exported_symbol" "_lprofCurFilename"
+//
+// RUN: %clang -target x86_64-apple-darwin12 -fprofile-instr-generate -### %t.o 2> %t.log
+// RUN: FileCheck -check-prefix=NO_PROFILE_EXPORT %s < %t.log
+// NO_PROFILE_EXPORT-NOT: "-exported_symbol"
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/fuchsia.c b/test/Driver/fuchsia.c
index 405086f..5b61bf4 100644
--- a/test/Driver/fuchsia.c
+++ b/test/Driver/fuchsia.c
@@ -9,6 +9,7 @@
 // CHECK: "--sysroot=[[SYSROOT]]"
 // CHECK: "-pie"
 // CHECK: "--build-id"
+// CHECK: "--hash-style=gnu"
 // CHECK: "-dynamic-linker" "ld.so.1"
 // CHECK: Scrt1.o
 // CHECK-NOT: crti.o
@@ -44,3 +45,29 @@
 // RUN:     -fsanitize=safe-stack 2>&1 \
 // RUN:     | FileCheck %s -check-prefix=CHECK-SAFESTACK
 // CHECK-SAFESTACK: "-fsanitize=safe-stack"
+
+// RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
+// RUN:     -fsanitize=address 2>&1 \
+// RUN:     | FileCheck %s -check-prefix=CHECK-ASAN-X86
+// CHECK-ASAN-X86: "-fsanitize=address"
+// CHECK-ASAN-X86: "-fsanitize-address-globals-dead-stripping"
+// CHECK-ASAN-X86: "-dynamic-linker" "asan/ld.so.1"
+// CHECK-ASAN-X86: "{{.*[/\\]}}libclang_rt.asan-x86_64.so"
+// CHECK-ASAN-X86: "{{.*[/\\]}}libclang_rt.asan-preinit-x86_64.a"
+
+// RUN: %clang %s -### --target=aarch64-fuchsia \
+// RUN:     -fsanitize=address 2>&1 \
+// RUN:     | FileCheck %s -check-prefix=CHECK-ASAN-AARCH64
+// CHECK-ASAN-AARCH64: "-fsanitize=address"
+// CHECK-ASAN-AARCH64: "-fsanitize-address-globals-dead-stripping"
+// CHECK-ASAN-AARCH64: "-dynamic-linker" "asan/ld.so.1"
+// CHECK-ASAN-AARCH64: "{{.*[/\\]}}libclang_rt.asan-aarch64.so"
+// CHECK-ASAN-AARCH64: "{{.*[/\\]}}libclang_rt.asan-preinit-aarch64.a"
+
+// RUN: %clang %s -### --target=x86_64-unknown-fuchsia \
+// RUN:     -fsanitize=address -fPIC -shared 2>&1 \
+// RUN:     | FileCheck %s -check-prefix=CHECK-ASAN-SHARED
+// CHECK-ASAN-SHARED: "-fsanitize=address"
+// CHECK-ASAN-SHARED: "-fsanitize-address-globals-dead-stripping"
+// CHECK-ASAN-SHARED: "{{.*[/\\]}}libclang_rt.asan-x86_64.so"
+// CHECK-ASAN-SHARED-NOT: "{{.*[/\\]}}libclang_rt.asan-preinit-x86_64.a"
diff --git a/test/Driver/fuchsia.cpp b/test/Driver/fuchsia.cpp
index 20299c3..ab0a901 100644
--- a/test/Driver/fuchsia.cpp
+++ b/test/Driver/fuchsia.cpp
@@ -28,8 +28,8 @@
 
 // RUN: %clangxx %s -### --target=x86_64-unknown-fuchsia -static-libstdc++ 2>&1 \
 // RUN:     | FileCheck %s -check-prefix=CHECK-STATIC
-// CHECK-STATIC: "-Bstatic"
+// CHECK-STATIC-NOT: "-Bstatic"
 // CHECK-STATIC: "-lc++" "-lc++abi" "-lunwind"
-// CHECK-STATIC: "-Bdynamic"
+// CHECK-STATIC-NOT: "-Bdynamic"
 // CHECK-STATIC: "-lm"
 // CHECK-STATIC: "-lc"
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/output-file-cleanup.c b/test/Driver/output-file-cleanup.c
index 314af4d..e3f2bdb 100644
--- a/test/Driver/output-file-cleanup.c
+++ b/test/Driver/output-file-cleanup.c
@@ -25,30 +25,19 @@
 invalid C code
 #endif
 
-// RUN: touch %t1.c
-// RUN: echo "invalid C code" > %t2.c
-// RUN: cd %T && not %clang -S %t1.c %t2.c
-// RUN: test -f %t1.s
-// RUN: test ! -f %t2.s
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: cd %t-dir
 
-// RUN: touch %t1.c
-// RUN: touch %t2.c
-// RUN: chmod -r %t2.c
-// RUN: cd %T && not %clang -S %t1.c %t2.c
-// RUN: test -f %t1.s
-// RUN: test ! -f %t2.s
+// RUN: touch %t-dir/1.c
+// RUN: echo "invalid C code" > %t-dir/2.c
+// RUN: not %clang -S %t-dir/1.c %t-dir/2.c
+// RUN: test -f %t-dir/1.s
+// RUN: test ! -f %t-dir/2.s
 
-// When given multiple .c files to compile, clang compiles them in order until
-// it hits an error, at which point it stops.
-//
-// RUN: touch %t1.c
-// RUN: echo "invalid C code" > %t2.c
-// RUN: touch %t3.c
-// RUN: echo "invalid C code" > %t4.c
-// RUN: touch %t5.c
-// RUN: cd %T && not %clang -S %t1.c %t2.c %t3.c %t4.c %t5.c
-// RUN: test -f %t1.s
-// RUN: test ! -f %t2.s
-// RUN: test ! -f %t3.s
-// RUN: test ! -f %t4.s
-// RUN: test ! -f %t5.s
+// RUN: touch %t-dir/1.c
+// RUN: touch %t-dir/2.c
+// RUN: chmod -r %t-dir/2.c
+// RUN: not %clang -S %t-dir/1.c %t-dir/2.c
+// RUN: test -f %t-dir/1.s
+// RUN: test ! -f %t-dir/2.s
diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c
index efdd124..33f78df 100644
--- a/test/Driver/sanitizer-ld.c
+++ b/test/Driver/sanitizer-ld.c
@@ -17,10 +17,23 @@
 // CHECK-ASAN-LINUX: "-ldl"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libsan \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libasan \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=address \
+// RUN:     -shared-libsan -static-libsan -shared-libasan             \
+// RUN:     -resource-dir=%S/Inputs/resource_dir \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
 //
 // CHECK-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
 // CHECK-SHARED-ASAN-LINUX-NOT: "-lc"
@@ -34,7 +47,7 @@
 // CHECK-SHARED-ASAN-LINUX-NOT: "--dynamic-list"
 
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \
-// RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libasan \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld -fsanitize=address -shared-libsan \
 // RUN:     -resource-dir=%S/Inputs/resource_dir \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-DSO-SHARED-ASAN-LINUX %s
@@ -131,14 +144,47 @@
 // CHECK-ASAN-ANDROID-NOT: "-lpthread"
 // CHECK-ASAN-ANDROID: libclang_rt.asan-arm-android.so"
 // CHECK-ASAN-ANDROID-NOT: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=address \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -static-libsan \
+// RUN:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID-STATICLIBASAN %s
+//
+// CHECK-ASAN-ANDROID-STATICLIBASAN: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-ASAN-ANDROID-STATICLIBASAN: libclang_rt.asan-arm-android.a"
+// CHECK-ASAN-ANDROID-STATICLIBASAN: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=undefined \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-ANDROID %s
+//
+// CHECK-UBSAN-ANDROID: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-UBSAN-ANDROID-NOT: "-lc"
+// CHECK-UBSAN-ANDROID-NOT: "-pie"
+// CHECK-UBSAN-ANDROID-NOT: "-lpthread"
+// CHECK-UBSAN-ANDROID: libclang_rt.ubsan_standalone-arm-android.so"
+// CHECK-UBSAN-ANDROID-NOT: "-lpthread"
+
+// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
+// RUN:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=undefined \
+// RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
+// RUN:     -static-libsan \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-ANDROID-STATICLIBASAN %s
+//
+// CHECK-UBSAN-ANDROID-STATICLIBASAN: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
+// CHECK-UBSAN-ANDROID-STATICLIBASAN: libclang_rt.ubsan_standalone-arm-android.a"
+// CHECK-UBSAN-ANDROID-STATICLIBASAN: "-lpthread"
+
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target arm-linux-androideabi -fsanitize=address \
 // RUN:     --sysroot=%S/Inputs/basic_android_tree/sysroot \
-// RUN:     -shared-libasan \
+// RUN:     -shared-libsan \
 // RUN:   | FileCheck --check-prefix=CHECK-ASAN-ANDROID-SHARED-LIBASAN %s
 //
-// CHECK-ASAN-ANDROID-SHARED-LIBASAN-NOT: argument unused during compilation: '-shared-libasan'
+// CHECK-ASAN-ANDROID-SHARED-LIBASAN-NOT: argument unused during compilation: '-shared-libsan'
 //
 // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
 // RUN:     -target arm-linux-androideabi -fuse-ld=ld -fsanitize=address \
@@ -202,6 +248,13 @@
 // RUN:     -target i386-unknown-linux -fuse-ld=ld \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
 // RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s
+
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     -static-libsan \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s
+
 // CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}"
 // CHECK-UBSAN-LINUX-NOT: libclang_rt.asan
 // CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_standalone_cxx
@@ -211,6 +264,27 @@
 // CHECK-UBSAN-LINUX-NOT: "-lstdc++"
 // CHECK-UBSAN-LINUX: "-lpthread"
 
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     -shared-libsan \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHAREDLIBASAN %s
+
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     -static-libsan -shared-libsan \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHAREDLIBASAN %s
+
+// RUN: %clang -fsanitize=undefined %s -### -o %t.o 2>&1 \
+// RUN:     -target i386-unknown-linux -fuse-ld=ld \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:     -shared -shared-libsan \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHAREDLIBASAN %s
+
+// CHECK-UBSAN-LINUX-SHAREDLIBASAN: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-LINUX-SHAREDLIBASAN: "{{.*}}libclang_rt.ubsan_standalone-i386.so{{.*}}"
+
 // RUN: %clang -fsanitize=undefined -fsanitize-link-c++-runtime %s -### -o %t.o 2>&1 \
 // RUN:     -target i386-unknown-linux \
 // RUN:     --sysroot=%S/Inputs/basic_linux_tree \
@@ -234,6 +308,28 @@
 // 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=undefined %s -### -o %t.o 2>&1 \
+// RUN:     -target x86_64-apple-darwin -fuse-ld=ld -static-libsan \
+// RUN:     --sysroot=%S/Inputs/basic_linux_tree \
+// RUN:   | FileCheck --check-prefix=CHECK-UBSAN-STATIC-DARWIN %s
+// CHECK-UBSAN-STATIC-DARWIN: "{{.*}}ld{{(.exe)?}}"
+// CHECK-UBSAN-STATIC-DARWIN: "{{.*}}libclang_rt.ubsan_osx.a"
+
 // 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/Driver/unix-conformance.c b/test/Driver/unix-conformance.c
new file mode 100644
index 0000000..ddf77c7
--- /dev/null
+++ b/test/Driver/unix-conformance.c
@@ -0,0 +1,24 @@
+// Check UNIX conformance for cc/c89/c99
+// When c99 encounters a compilation error that causes an object file not to be
+// created, it shall write a diagnostic to standard error and continue to
+// compile other source code operands, but it shall not perform the link phase
+// and it shall return a non-zero exit status.
+
+// When given multiple .c files to compile, clang compiles them in order until
+// it hits an error, at which point it stops.
+//
+// RUN: rm -rf %t-dir
+// RUN: mkdir -p %t-dir
+// RUN: cd %t-dir
+//
+// RUN: touch %t-dir/1.c
+// RUN: echo "invalid C code" > %t-dir/2.c
+// RUN: touch %t-dir/3.c
+// RUN: echo "invalid C code" > %t-dir/4.c
+// RUN: touch %t-dir/5.c
+// RUN: not %clang -S %t-dir/1.c %t-dir/2.c %t-dir/3.c %t-dir/4.c %t-dir/5.c
+// RUN: test -f %t-dir/1.s
+// RUN: test ! -f %t-dir/2.s
+// RUN: test -f %t-dir/3.s
+// RUN: test ! -f %t-dir/4.s
+// RUN: test -f %t-dir/5.s
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/FixIt/fixit-format-ios.m b/test/FixIt/fixit-format-ios.m
new file mode 100644
index 0000000..ef66430
--- /dev/null
+++ b/test/FixIt/fixit-format-ios.m
@@ -0,0 +1,26 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple thumbv7-apple-ios8.0.0 -fsyntax-only -Wformat -fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+
+int printf(const char * restrict, ...);
+typedef unsigned int NSUInteger;
+typedef int NSInteger;
+NSUInteger getNSUInteger();
+NSInteger getNSInteger();
+
+void test() {
+  // For thumbv7-apple-ios8.0.0 the underlying type of ssize_t is long
+  // and the underlying type of size_t is unsigned long.
+
+  printf("test 1: %zu", getNSUInteger()); 
+  // CHECK: printf("test 1: %lu", (unsigned long)getNSUInteger());
+
+  printf("test 2: %zu %zu", getNSUInteger(), getNSUInteger());
+  // CHECK: printf("test 2: %lu %lu", (unsigned long)getNSUInteger(), (unsigned long)getNSUInteger());
+
+  printf("test 3: %zd", getNSInteger()); 
+  // CHECK: printf("test 3: %ld", (long)getNSInteger());
+
+  printf("test 4: %zd %zd", getNSInteger(), getNSInteger());
+  // CHECK: printf("test 4: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+}
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/Frontend/optimization-remark-extra-analysis.c b/test/Frontend/optimization-remark-extra-analysis.c
new file mode 100644
index 0000000..1a8415e
--- /dev/null
+++ b/test/Frontend/optimization-remark-extra-analysis.c
@@ -0,0 +1,11 @@
+// Test that the is*RemarkEnabled overrides are working properly.  This remark
+// requiring extra analysis is only conditionally enabled.
+
+// RUN: %clang_cc1 %s -Rpass-missed=gvn -O2 -emit-llvm-only -verify
+
+int foo(int *x, int *y) {
+  int a = *x;
+  *y = 2;
+  // expected-remark@+1 {{load of type i32 not eliminated}}
+  return a + *x;
+}
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..6f485fe 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -201,8 +201,8 @@
 
   template<typename U>
   class InnerClass;
-// CHECK: [[@LINE-1]]:9 | class(Gen)/C++ | InnerClass | c:@S@PseudoOverridesInSpecializations>#d#I@ST>1#T@InnerClass | <no-cgname> | Ref,RelCont,RelSpecialization | rel: 2
-// CHECK-NEXT: RelCont
+// CHECK: [[@LINE-1]]:9 | class(Gen)/C++ | InnerClass | c:@S@PseudoOverridesInSpecializations>#d#I@ST>1#T@InnerClass | <no-cgname> | Decl,RelChild,RelSpecialization | rel: 2
+// CHECK-NEXT: RelChild
 // CHECK-NEXT: RelSpecialization | InnerClass | c:@ST>2#T#T@PseudoOverridesInSpecializations@ST>1#T@InnerClass
 };
 
@@ -274,7 +274,7 @@
 
 template<typename T>
 class SpecializationDecl;
-// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-1]]:7 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Decl | rel: 0
 
 template<typename T>
 class SpecializationDecl { };
@@ -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 {
@@ -512,3 +525,36 @@
 // CHECK-NEXT: RelCont | Nested | c:@N@rd33122110@S@Outer@S@Nested>#I
 // CHECK: [[@LINE-3]]:20 | struct/C++ | Outer | c:@N@rd33122110@S@Outer | <no-cgname> | Ref,RelCont | rel: 1
 // CHECK-NEXT: RelCont | Nested | c:@N@rd33122110@S@Outer@S@Nested>#I
+
+namespace index_offsetof {
+
+struct Struct {
+  int field;
+};
+
+struct Struct2 {
+  Struct array[4][2];
+};
+
+void foo() {
+  __builtin_offsetof(Struct, field);
+// CHECK: [[@LINE-1]]:30 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo#
+  __builtin_offsetof(Struct2, array[1][0].field);
+// CHECK: [[@LINE-1]]:31 | field/C | array | c:@N@index_offsetof@S@Struct2@FI@array | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo#
+// CHECK: [[@LINE-3]]:43 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo#
+}
+
+#define OFFSET_OF_(X, Y) __builtin_offsetof(X, Y)
+
+class SubclassOffsetof : public Struct {
+  void foo() {
+    OFFSET_OF_(SubclassOffsetof, field);
+// CHECK: [[@LINE-1]]:34 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@S@SubclassOffsetof@F@foo#
+  }
+};
+
+}
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..20dca7c
--- /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 | Decl | 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..c0f7912
--- /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 | Decl,RelChild | 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/USR/array-type.cpp b/test/Index/USR/array-type.cpp
new file mode 100644
index 0000000..40ff20d
--- /dev/null
+++ b/test/Index/USR/array-type.cpp
@@ -0,0 +1,11 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Function template specializations differing in array type parameter should have unique USRs.
+
+template<class buffer> void foo(buffer);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n16C>#*C#
+template<> void foo<char[16]>(char[16]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n32C>#*C#
+template<> void foo<char[32]>(char[32]);
+// CHECK: {{[0-9]+}}:17 | function(Gen,TS)/C++ | foo | c:@F@foo<#{n64C>#*C#
+template<> void foo<char[64]>(char[64]);
diff --git a/test/Index/USR/func-type.cpp b/test/Index/USR/func-type.cpp
new file mode 100644
index 0000000..ff1cd37
--- /dev/null
+++ b/test/Index/USR/func-type.cpp
@@ -0,0 +1,18 @@
+// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
+
+// Functions taking function pointer parameters with different signatures should result in unique USRs.
+
+typedef void (*_VoidToVoidPtr_)();
+typedef void (*_IntToVoidPtr_)( int );
+typedef _VoidToVoidPtr_ (*IntTo_VoidToVoidPtr_Ptr)( int );
+typedef _IntToVoidPtr_ (*VoidTo_IntToVoidPtr_Ptr)();
+
+void Func( IntTo_VoidToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv()(#I)# |
+void Func( VoidTo_IntToVoidPtr_Ptr );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)()# |
+
+void Func( void (* (*)(int, int))(int, int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I#I)(#I#I)# |
+void Func( void (* (*)(int, int, int))(int) );
+// CHECK: {{[0-9]+}}:6 | function/C | Func | c:@F@Func#*F*Fv(#I)(#I#I#I)# |
diff --git a/test/Index/code-completion.cpp b/test/Index/code-completion.cpp
index f52bb10..00f158f 100644
--- a/test/Index/code-completion.cpp
+++ b/test/Index/code-completion.cpp
@@ -37,6 +37,16 @@
   return 0;
 }
 
+template <typename T>
+struct Foo { T member; };
+
+template<typename T> using Bar = Foo<T>;
+
+void test_template_alias() {
+  // RUN: env CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:47:1 %s | FileCheck -check-prefix=CHECK-TEMPLATE-ALIAS %s
+
+}
+
 // CHECK-MEMBER: FieldDecl:{ResultType double}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType int}{Text X::}{TypedText member}
 // CHECK-MEMBER: FieldDecl:{ResultType float}{Text Y::}{TypedText member}
@@ -88,3 +98,5 @@
 // CHECK-EXPR-NEXT: Class name
 // CHECK-EXPR-NEXT: Nested name specifier
 // CHECK-EXPR-NEXT: Objective-C interface
+
+// CHECK-TEMPLATE-ALIAS: AliasTemplateDecl:{TypedText Bar}{LeftAngle <}{Placeholder typename T}{RightAngle >} (50)
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/complete-interfaces.m b/test/Index/complete-interfaces.m
index 2f86c3d..3e90407 100644
--- a/test/Index/complete-interfaces.m
+++ b/test/Index/complete-interfaces.m
@@ -45,3 +45,19 @@
 
 
 // RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:11:12 %s | FileCheck -check-prefix=CHECK-CC2 %s
+
+
+void useClasses() {
+  int i = 0;
+  [Int3 message:1];
+}
+
+// RUN: c-index-test -code-completion-at=%s:51:11 %s | FileCheck -check-prefix=CHECK-USE %s
+// RUN: c-index-test -code-completion-at=%s:52:17 %s | FileCheck -check-prefix=CHECK-USE %s
+// CHECK-USE: ObjCInterfaceDecl:{TypedText Int2} (50)
+// CHECK-USE: ObjCInterfaceDecl:{TypedText Int3} (50)
+// CHECK-USE-NOT: Int1
+// CHECK-USE-NOT: Int4
+
+// Caching should work too:
+// RUN: env CINDEXTEST_EDITING=1 CINDEXTEST_COMPLETION_CACHING=1 c-index-test -code-completion-at=%s:51:11 %s | FileCheck -check-prefix=CHECK-USE %s
diff --git a/test/Index/complete-method-decls.m b/test/Index/complete-method-decls.m
index 8a17142..f561f81 100644
--- a/test/Index/complete-method-decls.m
+++ b/test/Index/complete-method-decls.m
@@ -236,3 +236,25 @@
 // RUN: c-index-test -code-completion-at=%s:107:2 %s -target x86_64-apple-macosx10.7 | FileCheck -check-prefix=CHECK-NULLABILITY2 %s
 // CHECK-NULLABILITY2: ObjCInstanceMethodDecl:{LeftParen (}{Text instancetype}{RightParen )}{TypedText getI3} (40)
 // CHECK-NULLABILITY2: ObjCInstanceMethodDecl:{LeftParen (}{Text I3 *}{RightParen )}{TypedText produceI3}{TypedText :}{LeftParen (}{Text I3 *}{RightParen )}{Text i3} (40)
+
+@interface CompleteWithoutLeadingPrefix
+
+- (void)aMethod;
++ (int)aClassMethod:(int)x;
+@property int p;
+
+@end
+
+@implementation CompleteWithoutLeadingPrefix
+
+
+
+@end
+
+// RUN: c-index-test -code-completion-at=%s:250:1 %s | FileCheck -check-prefix=CHECK-COMP-NO-PREFIX %s
+// CHECK-COMP-NO-PREFIX: NotImplemented:{TypedText @end} (40)
+// CHECK-COMP-NO-PREFIX: ObjCClassMethodDecl:{Text +}{HorizontalSpace  }{LeftParen (}{Text int}{RightParen )}{TypedText aClassMethod}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text x} (40)
+// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace  }{LeftParen (}{Text void}{RightParen )}{TypedText aMethod} (40)
+// CHECK-COMP-NO-PREFIX: ObjCInterfaceDecl:{TypedText I1}
+// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace  }{LeftParen (}{Text int}{RightParen )}{TypedText p} (40)
+// CHECK-COMP-NO-PREFIX: ObjCInstanceMethodDecl:{Text -}{HorizontalSpace  }{LeftParen (}{Text void}{RightParen )}{TypedText setP}{TypedText :}{LeftParen (}{Text int}{RightParen )}{Text p} (40)
diff --git a/test/Index/index-template-template-param.cpp b/test/Index/index-template-template-param.cpp
new file mode 100644
index 0000000..af1c463
--- /dev/null
+++ b/test/Index/index-template-template-param.cpp
@@ -0,0 +1,7 @@
+// RUN: c-index-test -index-file %s -x objective-c++ | FileCheck %s
+
+template <typename T> class Template1 {};
+
+template <template <class> class TMPL = Template1> class Template2;
+
+// CHECK: [indexEntityReference]: kind: c++-class-template | name: Template1 |
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/editor-placeholder-recovery.cpp b/test/Parser/editor-placeholder-recovery.cpp
index 48c290e..d68e087 100644
--- a/test/Parser/editor-placeholder-recovery.cpp
+++ b/test/Parser/editor-placeholder-recovery.cpp
@@ -69,3 +69,7 @@
   // expected-error@-2 {{editor placeholder in source file}}
 #endif
 }
+
+void handleTrigraph() {
+  <??=placeholder#> // expected-error {{expected expression}} expected-error {{expected expression}} expected-warning {{trigraph converted to '#' character}}
+}
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/Preprocessor/pragma_assume_nonnull.c b/test/Preprocessor/pragma_assume_nonnull.c
new file mode 100644
index 0000000..4aa1241
--- /dev/null
+++ b/test/Preprocessor/pragma_assume_nonnull.c
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -E %s | FileCheck %s
+
+// CHECK: #pragma clang assume_nonnull begin
+#pragma clang assume_nonnull begin
+
+int bar(int * ip) { return *ip; }
+
+// CHECK: #pragma clang assume_nonnull end
+#pragma clang assume_nonnull end
+
+int foo(int * _Nonnull ip) { return *ip; }
+
+int main() {
+   return bar(0) + foo(0); // expected-warning 2 {{null passed to a callee that requires a non-null argument}}
+}
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..3cef26c
--- /dev/null
+++ b/test/Refactor/Extract/extract-expression.cpp
@@ -0,0 +1,68 @@
+
+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
+;
+void extractFunctionCall() {
+  sumArea(0, 1);
+}
+// CHECK6: "static int extracted() {\nreturn sumArea(0, 1);\n}\n\n" [[@LINE-3]]:1 -> [[@LINE-3]]:1
+// CHECK6-NEXT: "extracted()" [[@LINE-3]]:3 -> [[@LINE-3]]:16
+
+// RUN: clang-refactor-test perform -action extract -selected=%s:63:3-63:10 %s | FileCheck --check-prefix=CHECK6 %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..09cfc7b
--- /dev/null
+++ b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.cpp
@@ -0,0 +1,116 @@
+
+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 [Symbol extracted-decl 0 1:9 -> 1:15]
+// CHECK3-NEXT: "object" [[@LINE-4]]:5 -> [[@LINE-4]]:18 [Symbol extracted-decl-ref 0 1:1 -> 1:7]
+// CHECK3-NEXT: "object" [[@LINE-4]]:3 -> [[@LINE-4]]:16 [Symbol extracted-decl-ref 0 1:1 -> 1:7]
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:45:5 -emit-associated %s | FileCheck --check-prefix=CHECK3 %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=%s:46:3 -emit-associated %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
+
+class ImplicitThisRewrite {
+  AWrapper &ref;
+  ImplicitThisRewrite(AWrapper &ref) : ref(ref) {}
+
+  void method() {
+    // implicit-this: +1:5  // IMPLICIT-THIS: "AClass &object = this->ref.object(1);\nobject" [[@LINE+1]]:5 -> [[@LINE+1]]:18
+    ref.object(1).method(); // IMPLICIT-NO-THIS: "AClass &object = ref.object(1);\nobject" [[@LINE]]:5 -> [[@LINE]]:18
+    ref.object(1).constMethod(); // IMPLICIT-THIS-ME: "object" [[@LINE]]:5 -> [[@LINE]]:18
+    // implicit-this2: +1:5
+    this->ref.object(1).method(); // IMPLICIT-THIS-MENEXT: "object" [[@LINE]]:5 -> [[@LINE]]:24
+  }
+};
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=implicit-this %s | FileCheck --check-prefixes=IMPLICIT-NO-THIS,IMPLICIT-THIS-ME %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=implicit-this2 %s | FileCheck --check-prefixes=IMPLICIT-THIS,IMPLICIT-THIS-ME %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..cc14c23
--- /dev/null
+++ b/test/Refactor/ExtractRepeatedExpression/extract-repeated-expr-perform.m
@@ -0,0 +1,119 @@
+
+@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
+
+@interface IVarSelf {
+  Wrapper *ref;
+}
+
+@end
+
+@implementation IVarSelf
+
+- (void)foo {
+  // ivar-self: +1:3         // IVAR-SELF: "Object *object = self->ref.object;\nobject" [[@LINE+1]]:3 -> [[@LINE+1]]:13
+  ref.object.prop = 0;       // IVAR-NO-SELF: "Object *object = ref.object;\nobject" [[@LINE]]:3 -> [[@LINE]]:13
+  ref.object->ivar = 1;      // IVAR: "object" [[@LINE]]:3 -> [[@LINE]]:13
+  // ivar-self2: +1:3
+  self->ref.object.prop = 2; // IVAR-NEXT: "object" [[@LINE]]:3 -> [[@LINE]]:19
+}
+
+@end
+
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=ivar-self %s | FileCheck --check-prefixes=IVAR-NO-SELF,IVAR %s
+// RUN: clang-refactor-test perform -action extract-repeated-expr-into-var -at=ivar-self2 %s | FileCheck --check-prefixes=IVAR-SELF,IVAR %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/BuiltinOffsetof.cpp b/test/Refactor/Rename/BuiltinOffsetof.cpp
new file mode 100644
index 0000000..9d0e9fe
--- /dev/null
+++ b/test/Refactor/Rename/BuiltinOffsetof.cpp
@@ -0,0 +1,17 @@
+
+
+struct Struct {
+  int field; // CHECK: rename [[@LINE]]:7 -> [[@LINE]]:12
+};
+
+struct Struct2 {
+  Struct /*range array=*/array[4][2]; // ARRAYCHECK: rename [[@LINE]]:26 -> [[@LINE]]:31
+};
+
+void foo() {
+  (void)__builtin_offsetof(Struct, field); // CHECK: rename [[@LINE]]:36 -> [[@LINE]]:41
+  (void)__builtin_offsetof(Struct2, /*range array=*/array[1][0]./*range f=*/field); // CHECK: rename [[@LINE]]:77 -> [[@LINE]]:82
+} // ARRAYCHECK: rename [[@LINE-1]]:53 -> [[@LINE-1]]:58
+
+// RUN: clang-refactor-test rename-initiate -at=%s:4:7 -at=%s:12:36 -new-name=Bar %s | FileCheck %s
+// RUN: clang-refactor-test rename-initiate -at=%s:8:26 -at=%s:13:53 -new-name=Bar %s | FileCheck --check-prefix=ARRAYCHECK %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-alias.c b/test/Sema/attr-alias.c
index 151052f..9313670 100644
--- a/test/Sema/attr-alias.c
+++ b/test/Sema/attr-alias.c
@@ -2,7 +2,4 @@
 
 void g() {}
 
-// It is important that the following string be in the error message. The gcc
-// testsuite looks for it to decide if a target supports aliases.
-
-void f() __attribute__((alias("g"))); //expected-error {{only weak aliases are supported}}
+void f() __attribute__((alias("g"))); //expected-error {{aliases are not supported on darwin}}
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-capabilities.c b/test/Sema/attr-capabilities.c
index 8996770..88fdf30 100644
--- a/test/Sema/attr-capabilities.c
+++ b/test/Sema/attr-capabilities.c
@@ -37,9 +37,6 @@
 void Func7(void) __attribute__((assert_capability(GUI))) {}
 void Func8(void) __attribute__((assert_shared_capability(GUI))) {}
 
-void Func9(void) __attribute__((assert_capability())) {} // expected-error {{'assert_capability' attribute takes one argument}}
-void Func10(void) __attribute__((assert_shared_capability())) {} // expected-error {{'assert_shared_capability' attribute takes one argument}}
-
 void Func11(void) __attribute__((acquire_capability(GUI))) {}
 void Func12(void) __attribute__((acquire_shared_capability(GUI))) {}
 
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..f9e4069 100644
--- a/test/Sema/enum.c
+++ b/test/Sema/enum.c
@@ -123,3 +123,15 @@
 // 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
+// In C it is valid to define tags inside enums.
+struct PR28903 {
+  enum {
+    PR28903_A = (enum {
+      PR28903_B,
+      PR28903_C = PR28903_B
+    })0
+  };
+  int makeStructNonEmpty;
+};
diff --git a/test/Sema/format-strings-fixit-ssize_t.c b/test/Sema/format-strings-fixit-ssize_t.c
index 5208a29..f8893a1 100644
--- a/test/Sema/format-strings-fixit-ssize_t.c
+++ b/test/Sema/format-strings-fixit-ssize_t.c
@@ -1,7 +1,7 @@
 // RUN: cp %s %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -pedantic -Wall -fixit %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -pedantic -Wall -Werror %t
-// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -E -o - %t | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -pedantic -Wall -fixit %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -fsyntax-only -pedantic -Wall -Werror %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -std=c99 -E -o - %t | FileCheck %s
 
 /* This is a test of the various code modification hints that are
    provided as part of warning or extension diagnostics. All of the
@@ -9,10 +9,14 @@
    compile cleanly with -Werror -pedantic. */
 
 int printf(char const *, ...);
+int scanf(const char *, ...);
 
 void test() {
   typedef signed long int ssize_t;
   printf("%f", (ssize_t) 42);
+  ssize_t s;
+  scanf("%f",  &s);
 }
 
 // CHECK: printf("%zd", (ssize_t) 42);
+// CHECK: scanf("%zd", &s)
diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c
index 7a92842..e700d10 100644
--- a/test/Sema/format-strings-scanf.c
+++ b/test/Sema/format-strings-scanf.c
@@ -1,10 +1,18 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wformat-nonliteral %s
 
 // Test that -Wformat=0 works:
-// RUN: %clang_cc1 -fsyntax-only -Werror -Wformat=0 %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -Werror -Wformat=0 %s
 
 #include <stdarg.h>
-typedef __typeof(sizeof(int)) size_t;
+typedef __SIZE_TYPE__ size_t;
+#define __SSIZE_TYPE__                                                         \
+  __typeof__(_Generic((__SIZE_TYPE__)0,                                        \
+                      unsigned long long int : (long long int)0,               \
+                      unsigned long int : (long int)0,                         \
+                      unsigned int : (int)0,                                   \
+                      unsigned short : (short)0,                               \
+                      unsigned char : (signed char)0))
+typedef __SSIZE_TYPE__ ssize_t;                         
 typedef struct _FILE FILE;
 typedef __WCHAR_TYPE__ wchar_t;
 
@@ -172,6 +180,26 @@
   scanf("%d", (cip_t)0); // expected-warning{{format specifies type 'int *' but the argument has type 'cip_t' (aka 'const int *')}}
 }
 
+void test_size_types() {
+  size_t s = 0;
+  scanf("%zu", &s); // No warning.
+
+  double d1 = 0.;
+  scanf("%zu", &d1); // expected-warning-re{{format specifies type 'size_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ssize_t ss = 0;
+  scanf("%zd", &s); // No warning.
+
+  double d2 = 0.;
+  scanf("%zd", &d2); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ssize_t sn = 0;
+  scanf("%zn", &sn); // No warning.
+
+  double d3 = 0.;
+  scanf("%zn", &d3); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+}
+
 void check_conditional_literal(char *s, int *i) {
   scanf(0 ? "%s" : "%d", i); // no warning
   scanf(1 ? "%s" : "%d", i); // expected-warning{{format specifies type 'char *'}}
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/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp
index ccf374c..7ffaffc 100644
--- a/test/Sema/warn-documentation.cpp
+++ b/test/Sema/warn-documentation.cpp
@@ -1282,3 +1282,25 @@
 };
 
 }
+
+/*!
+ * Function pointer typedef with variadic params.
+ *
+ * @param a
+ * works
+ *
+ * @param ...
+ * now should work too.
+ */
+typedef void (*VariadicFnType)(int a, ...);
+
+/*!
+ * Function pointer type alias with variadic params.
+ *
+ * @param a
+ * works
+ *
+ * @param ...
+ * now should work too.
+ */
+using VariadicFnType2 = void (*)(int a, ...);
diff --git a/test/Sema/warn-documentation.m b/test/Sema/warn-documentation.m
index 3c1a369..18ab5bd 100644
--- a/test/Sema/warn-documentation.m
+++ b/test/Sema/warn-documentation.m
@@ -299,3 +299,14 @@
 @property void (^blockReturnsNothing)();
 
 @end
+
+/*!
+ * Block typedef with variadic params.
+ *
+ * @param a
+ * works
+ *
+ * @param ...
+ * now should work too.
+ */
+typedef void (^VariadicBlockType)(int a, ...);
diff --git a/test/SemaCXX/Inputs/warn-zero-nullptr.h b/test/SemaCXX/Inputs/warn-zero-nullptr.h
new file mode 100644
index 0000000..9b86c4b
--- /dev/null
+++ b/test/SemaCXX/Inputs/warn-zero-nullptr.h
@@ -0,0 +1,3 @@
+#define NULL (0)
+#define SYSTEM_MACRO (0)
+#define OTHER_SYSTEM_MACRO (NULL)
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/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index 3fda2d0..c834da7 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -1904,6 +1904,22 @@
     };
     static_assert(X::f(3) == -1, "3 should truncate to -1");
   }
+
+  struct HasUnnamedBitfield {
+    unsigned a;
+    unsigned : 20;
+    unsigned b;
+
+    constexpr HasUnnamedBitfield() : a(), b() {}
+    constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {}
+  };
+
+  void testUnnamedBitfield() {
+    const HasUnnamedBitfield zero{};
+    int a = 1 / zero.b; // expected-warning {{division by zero is undefined}}
+    const HasUnnamedBitfield oneZero{1, 0};
+    int b = 1 / oneZero.b; // expected-warning {{division by zero is undefined}}
+  }
 }
 
 namespace ZeroSizeTypes {
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/SemaCXX/warn-global-constructors.cpp b/test/SemaCXX/warn-global-constructors.cpp
index 8568264..430f239 100644
--- a/test/SemaCXX/warn-global-constructors.cpp
+++ b/test/SemaCXX/warn-global-constructors.cpp
@@ -126,3 +126,22 @@
 void *array_storage[1];
 const int &global_reference = *(int *)array_storage;
 }
+
+namespace bitfields {
+  struct HasUnnamedBitfield {
+    unsigned a;
+    unsigned : 20;
+    unsigned b;
+
+    constexpr HasUnnamedBitfield() : a(), b() {}
+    constexpr HasUnnamedBitfield(unsigned a, unsigned b) : a(a), b(b) {}
+    explicit HasUnnamedBitfield(unsigned a) {}
+  };
+
+  const HasUnnamedBitfield zeroConst{};
+  HasUnnamedBitfield zeroMutable{};
+  const HasUnnamedBitfield explicitConst{1, 2};
+  HasUnnamedBitfield explicitMutable{1, 2};
+  const HasUnnamedBitfield nonConstexprConst{1}; // expected-warning {{global constructor}}
+  HasUnnamedBitfield nonConstexprMutable{1}; // expected-warning {{global constructor}}
+}
diff --git a/test/SemaCXX/warn-thread-safety-analysis.cpp b/test/SemaCXX/warn-thread-safety-analysis.cpp
index bbb4f9b..e6e9a0a 100644
--- a/test/SemaCXX/warn-thread-safety-analysis.cpp
+++ b/test/SemaCXX/warn-thread-safety-analysis.cpp
@@ -1,4 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=0 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -Wthread-safety -Wthread-safety-beta -Wno-thread-safety-negative -fcxx-exceptions -DUSE_ASSERT_CAPABILITY=1 %s
 
 // FIXME: should also run  %clang_cc1 -fsyntax-only -verify -Wthread-safety -std=c++11 -Wc++98-compat %s
 // FIXME: should also run  %clang_cc1 -fsyntax-only -verify -Wthread-safety %s
@@ -13,8 +14,15 @@
 #define ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
 #define EXCLUSIVE_LOCK_FUNCTION(...)    __attribute__((exclusive_lock_function(__VA_ARGS__)))
 #define SHARED_LOCK_FUNCTION(...)       __attribute__((shared_lock_function(__VA_ARGS__)))
+
+#if USE_ASSERT_CAPABILITY
+#define ASSERT_EXCLUSIVE_LOCK(...)      __attribute__((assert_capability(__VA_ARGS__)))
+#define ASSERT_SHARED_LOCK(...)         __attribute__((assert_shared_capability(__VA_ARGS__)))
+#else
 #define ASSERT_EXCLUSIVE_LOCK(...)      __attribute__((assert_exclusive_lock(__VA_ARGS__)))
 #define ASSERT_SHARED_LOCK(...)         __attribute__((assert_shared_lock(__VA_ARGS__)))
+#endif
+
 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) __attribute__((exclusive_trylock_function(__VA_ARGS__)))
 #define SHARED_TRYLOCK_FUNCTION(...)    __attribute__((shared_trylock_function(__VA_ARGS__)))
 #define UNLOCK_FUNCTION(...)            __attribute__((unlock_function(__VA_ARGS__)))
@@ -3675,9 +3683,14 @@
                        SHARED_TRYLOCK_FUNCTION(true, mu2_);
   void assertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_)
                     ASSERT_EXCLUSIVE_LOCK(mu2_);
+
+  void alsoAssertBoth() ASSERT_EXCLUSIVE_LOCK(mu1_, mu2_);
+
   void assertShared() ASSERT_SHARED_LOCK(mu1_)
                       ASSERT_SHARED_LOCK(mu2_);
 
+  void alsoAssertShared() ASSERT_SHARED_LOCK(mu1_, mu2_);
+
   void test();
   void testAssert();
   void testAssertShared();
@@ -3741,17 +3754,33 @@
 
 // Force duplication of attributes
 void Foo::assertBoth() { }
+void Foo::alsoAssertBoth() { }
 void Foo::assertShared() { }
+void Foo::alsoAssertShared() { }
 
 void Foo::testAssert() {
-  assertBoth();
-  a = 0;
-  b = 0;
+  {
+    assertBoth();
+    a = 0;
+    b = 0;
+  }
+  {
+    alsoAssertBoth();
+    a = 0;
+    b = 0;
+  }
 }
 
 void Foo::testAssertShared() {
-  assertShared();
-  int zz = a + b;
+  {
+    assertShared();
+    int zz = a + b;
+  }
+
+  {
+    alsoAssertShared();
+    int zz = a + b;
+  }
 }
 
 
@@ -5204,3 +5233,18 @@
   } // expected-warning {{mutex 'lock_' is still held at the end of function}}
   Mutex lock_ ACQUIRED_BEFORE("");
 };
+
+namespace PR34800 {
+struct A {
+  operator int() const;
+};
+struct B {
+  bool g() __attribute__((locks_excluded(h))); // expected-warning {{'locks_excluded' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
+  int h;
+};
+struct C {
+  B *operator[](int);
+};
+C c;
+void f() { c[A()]->g(); }
+} // namespace PR34800
diff --git a/test/SemaCXX/warn-zero-nullptr.cpp b/test/SemaCXX/warn-zero-nullptr.cpp
index edd2a75..45f05fa 100644
--- a/test/SemaCXX/warn-zero-nullptr.cpp
+++ b/test/SemaCXX/warn-zero-nullptr.cpp
@@ -1,4 +1,10 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -Wzero-as-null-pointer-constant -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -Wzero-as-null-pointer-constant -std=c++11
+// RUN: %clang_cc1 -fsyntax-only -verify %s -isystem %S/Inputs -DSYSTEM_WARNINGS -Wzero-as-null-pointer-constant -Wsystem-headers -std=c++11
+
+#include <warn-zero-nullptr.h>
+
+#define MACRO (0)
+#define MCRO(x) (x)
 
 struct S {};
 
@@ -15,8 +21,12 @@
 void (*fp2)() = __null; // expected-warning{{zero as null pointer constant}}
 int (S::*mp2) = __null; // expected-warning{{zero as null pointer constant}}
 
-void f0(void* v = 0); // expected-warning{{zero as null pointer constant}}
-void f1(void* v);
+void f0(void* v = MACRO); // expected-warning{{zero as null pointer constant}}
+void f1(void* v = NULL); // expected-warning{{zero as null pointer constant}}
+void f2(void* v = MCRO(0)); // expected-warning{{zero as null pointer constant}}
+void f3(void* v = MCRO(NULL)); // expected-warning{{zero as null pointer constant}}
+void f4(void* v = 0); // expected-warning{{zero as null pointer constant}}
+void f5(void* v);
 
 void g() {
   f1(0); // expected-warning{{zero as null pointer constant}}
@@ -25,3 +35,58 @@
 // Warn on these too. Matches gcc and arguably makes sense.
 void* pp = (decltype(nullptr))0; // expected-warning{{zero as null pointer constant}}
 void* pp2 = static_cast<decltype(nullptr)>(0); // expected-warning{{zero as null pointer constant}}
+
+// Shouldn't warn.
+namespace pr34362 {
+struct A { operator int*() { return nullptr; } };
+void func() { if (nullptr == A()) {} }
+void func2() { if ((nullptr) == A()) {} }
+}
+
+template <typename T> void TmplFunc0(T var) {}
+void Func0Test() {
+  TmplFunc0<int>(0);
+  TmplFunc0<int*>(0); // expected-warning {{zero as null pointer constant}}
+  TmplFunc0<void*>(0); // expected-warning {{zero as null pointer constant}}
+}
+
+// FIXME: this one probably should not warn.
+template <typename T> void TmplFunc1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}}
+void FuncTest() {
+  TmplFunc1<int>(0);
+  TmplFunc1<int*>(0); // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<int *>' required here}}
+  TmplFunc1<void*>(0);  // expected-note {{in instantiation of default function argument expression for 'TmplFunc1<void *>' required here}}
+}
+
+template<typename T>
+class TemplateClass0 {
+ public:
+  explicit TemplateClass0(T var) {}
+};
+void TemplateClass0Test() {
+  TemplateClass0<int> a(0);
+  TemplateClass0<int*> b(0); // expected-warning {{zero as null pointer constant}}
+  TemplateClass0<void*> c(0); // expected-warning {{zero as null pointer constant}}
+}
+
+template<typename T>
+class TemplateClass1 {
+ public:
+// FIXME: this one should *NOT* warn.
+  explicit TemplateClass1(int a, T default_value = 0) {} // expected-warning{{zero as null pointer constant}} expected-warning{{zero as null pointer constant}}
+};
+void IgnoreSubstTemplateType1() {
+  TemplateClass1<int> a(1);
+  TemplateClass1<int*> b(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<int *>' required here}}
+  TemplateClass1<void*> c(1); // expected-note {{in instantiation of default function argument expression for 'TemplateClass1<void *>' required here}}
+}
+
+#ifndef SYSTEM_WARNINGS
+// Do not warn on *any* other macros from system headers, even if they
+// expand to/their expansion contains NULL.
+void* sys_init = SYSTEM_MACRO;
+void* sys_init2 = OTHER_SYSTEM_MACRO;
+#else
+void* sys_init = SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}}
+void* sys_init2 = OTHER_SYSTEM_MACRO; // expected-warning {{zero as null pointer constant}}
+#endif
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/block-literal-with-attribute.m b/test/SemaObjC/block-literal-with-attribute.m
new file mode 100644
index 0000000..2a80579
--- /dev/null
+++ b/test/SemaObjC/block-literal-with-attribute.m
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks -fobjc-arc
+// RUN: %clang_cc1 -fsyntax-only %s -verify -fblocks
+
+__auto_type block = ^ id __attribute__((ns_returns_retained)) (id filter) {
+  return filter; // ok
+};
+__auto_type block2 = ^  __attribute__((ns_returns_retained)) id (id filter) {
+  return filter; // ok
+};
+__auto_type block3 = ^ id (id filter)  __attribute__((ns_returns_retained))  {
+  return filter; // ok
+};
+
+// expected-no-diagnostics
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/property-implement-readonly-with-custom-setter.m b/test/SemaObjC/property-implement-readonly-with-custom-setter.m
new file mode 100644
index 0000000..7ac1380
--- /dev/null
+++ b/test/SemaObjC/property-implement-readonly-with-custom-setter.m
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1  -fsyntax-only -verify -Wno-objc-root-class %s
+// rdar://34192541
+
+@class NSString;
+
+@protocol MyProtocol
+@property (nonatomic, strong, readonly) NSString *myString;
+@end
+
+@interface MyClass <MyProtocol>
+// Don't warn about this setter:
+@property (nonatomic, strong, setter=setMYString:) NSString *myString;
+
+
+@property (nonatomic, strong, readonly) NSString *overridenInClass; // expected-note {{property declared here}}
+@end
+
+@interface MySubClass: MyClass
+@property (nonatomic, strong, setter=setMYOverride:) NSString *overridenInClass;
+// expected-warning@-1 {{'setter' attribute on property 'overridenInClass' does not match the property inherited from 'MyClass'}}
+@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/Inputs/nullability-completeness-cferror.h b/test/SemaObjCXX/Inputs/nullability-completeness-cferror.h
new file mode 100644
index 0000000..4988a74
--- /dev/null
+++ b/test/SemaObjCXX/Inputs/nullability-completeness-cferror.h
@@ -0,0 +1,13 @@
+@class NSError;
+
+#pragma clang assume_nonnull begin
+
+#ifdef USE_MUTABLE
+typedef struct __attribute__((objc_bridge_mutable(NSError))) __CFError * CFErrorRef;
+#else
+typedef struct __attribute__((objc_bridge(NSError))) __CFError * CFErrorRef;
+#endif
+
+void func1(CFErrorRef *error);
+
+#pragma clang assume_nonnull end
diff --git a/test/SemaObjCXX/block-variable-move.mm b/test/SemaObjCXX/block-variable-move.mm
new file mode 100644
index 0000000..e26dffc
--- /dev/null
+++ b/test/SemaObjCXX/block-variable-move.mm
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -verify -fblocks -Wpessimizing-move -Wredundant-move %s
+
+// definitions for std::move
+namespace std {
+inline namespace foo {
+template <class T> struct remove_reference { typedef T type; };
+template <class T> struct remove_reference<T&> { typedef T type; };
+template <class T> struct remove_reference<T&&> { typedef T type; };
+
+template <class T> typename remove_reference<T>::type &&move(T &&t);
+}
+}
+
+class MoveOnly {
+public:
+  MoveOnly() { }
+  MoveOnly(MoveOnly &&) = default; // expected-note 2 {{copy constructor is implicitly deleted}}
+  MoveOnly &operator=(MoveOnly &&) = default;
+  ~MoveOnly();
+};
+
+void copyInit() {
+  __block MoveOnly temp;
+  MoveOnly temp2 = temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}}
+  MoveOnly temp3 = std::move(temp); // ok
+}
+
+MoveOnly errorOnCopy() {
+  __block MoveOnly temp;
+  return temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}}
+}
+
+MoveOnly dontWarnOnMove() {
+  __block MoveOnly temp;
+  return std::move(temp); // ok
+}
+
+class MoveOnlySub : public MoveOnly {};
+
+MoveOnly dontWarnOnMoveSubclass() {
+  __block MoveOnlySub temp;
+  return std::move(temp); // ok
+}
diff --git a/test/SemaObjCXX/nullability-completeness-cferror.mm b/test/SemaObjCXX/nullability-completeness-cferror.mm
new file mode 100644
index 0000000..4cea9fb
--- /dev/null
+++ b/test/SemaObjCXX/nullability-completeness-cferror.mm
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -I %S/Inputs -x objective-c -Wnullability-completeness -Werror -verify %s
+// RUN: %clang_cc1 -fsyntax-only -I %S/Inputs -x objective-c -Wnullability-completeness -Werror -verify -DUSE_MUTABLE %s
+// expected-no-diagnostics
+
+#include "nullability-completeness-cferror.h"
diff --git a/test/SemaObjCXX/typo-correction.mm b/test/SemaObjCXX/typo-correction.mm
index 5e33bfb..3f8a082 100644
--- a/test/SemaObjCXX/typo-correction.mm
+++ b/test/SemaObjCXX/typo-correction.mm
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Wno-objc-root-class
 
 class ClassA {};
 
@@ -36,3 +36,54 @@
   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
+
+// rdar://35172419
+// The scope of 'do-while' ends before typo-correction takes place.
+
+struct Mat2 { int rows; };
+
+@implementation ImplNoInt // expected-warning {{cannot find interface declaration for 'ImplNoInt'}}
+
+- (void)typoCorrentInDoWhile {
+  Mat2 tlMat1; // expected-note {{'tlMat1' declared here}}
+  // Create many scopes to exhaust the cache.
+  do {
+    for (int index = 0; index < 2; index++) {
+      if (true) {
+        for (int specialTileType = 1; specialTileType < 5; specialTileType++) {
+          for (int i = 0; i < 10; i++) {
+            for (double scale = 0.95; scale <= 1.055; scale += 0.05) {
+              for (int j = 0; j < 10; j++) {
+                if (1 > 0.9) {
+                    for (int sptile = 1; sptile < 5; sptile++) {
+                    }
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  } while (tlMat.rows); // expected-error {{use of undeclared identifier 'tlMat'; did you mean 'tlMat1'}}
+}
+
+@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/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp
index 74a2586..2c58fef 100644
--- a/test/SemaTemplate/deduction-crash.cpp
+++ b/test/SemaTemplate/deduction-crash.cpp
@@ -144,3 +144,20 @@
   template<typename T, typename U = void> int n<T *>; // expected-error +{{}} expected-note {{}}
   int k = n<void *>;
 }
+
+namespace deduceFunctionSpecializationForInvalidOutOfLineFunction {
+
+template <typename InputT, typename OutputT>
+struct SourceSelectionRequirement {
+  template<typename T>
+  OutputT evaluateSelectionRequirement(InputT &&Value) {
+  }
+};
+
+template <typename InputT, typename OutputT>
+OutputT SourceSelectionRequirement<InputT, OutputT>::
+evaluateSelectionRequirement<void>(InputT &&Value) { // expected-error {{cannot specialize a member of an unspecialized template}}
+  return Value;
+}
+
+}
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/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
index c0c3680..e8165ac 100644
--- a/test/SemaTemplate/explicit-specialization-member.cpp
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -38,24 +38,20 @@
 
   template<typename T>
   template<int N>
-  void Baz<T>::bar() { // expected-note {{couldn't infer template argument 'N'}}
+  void Baz<T>::bar() {
   }
 
-  // FIXME: We shouldn't try to match this against a prior declaration if
-  // template parameter matching failed.
   template<typename T>
-  void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}} \
-                          // expected-error {{no function template matches}}
+  void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}}
   }
 }
 
 namespace PR19340 {
 template<typename T> struct Helper {
-  template<int N> static void func(const T *m) {} // expected-note {{failed template argument deduction}}
+  template<int N> static void func(const T *m) {}
 };
 
-template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}} \
-                                                  // expected-error {{no function template matches}}
+template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}}
 }
 
 namespace SpecLoc {
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-format/fuzzer/CMakeLists.txt b/tools/clang-format/fuzzer/CMakeLists.txt
index c7772fc..9dc4f2a 100644
--- a/tools/clang-format/fuzzer/CMakeLists.txt
+++ b/tools/clang-format/fuzzer/CMakeLists.txt
@@ -1,11 +1,11 @@
 set(LLVM_LINK_COMPONENTS support)
 
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer")
+
 add_clang_executable(clang-format-fuzzer
   EXCLUDE_FROM_ALL
   ClangFormatFuzzer.cpp
   )
 
 target_link_libraries(clang-format-fuzzer
-  ${CLANG_FORMAT_LIB_DEPS}
-  LLVMFuzzer
-  )
+  ${CLANG_FORMAT_LIB_DEPS})
diff --git a/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp b/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp
index 5334ce8..d440a61 100644
--- a/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp
+++ b/tools/clang-format/fuzzer/ClangFormatFuzzer.cpp
@@ -20,7 +20,10 @@
   std::string s((const char *)data, size);
   auto Style = getGoogleStyle(clang::format::FormatStyle::LK_Cpp);
   Style.ColumnLimit = 60;
-  applyAllReplacements(s, clang::format::reformat(
-                              Style, s, {clang::tooling::Range(0, s.size())}));
+  auto Replaces = reformat(Style, s, clang::tooling::Range(0, s.size()));
+  auto Result = applyAllReplacements(s, Replaces);
+
+  // Output must be checked, as otherwise we crash.
+  if (!Result) {}
   return 0;
 }
diff --git a/tools/clang-fuzzer/CMakeLists.txt b/tools/clang-fuzzer/CMakeLists.txt
index a4ea4ca..694dd58 100644
--- a/tools/clang-fuzzer/CMakeLists.txt
+++ b/tools/clang-fuzzer/CMakeLists.txt
@@ -1,5 +1,52 @@
 if( LLVM_USE_SANITIZE_COVERAGE )
   set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD})
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=fuzzer")
+
+  if(CLANG_ENABLE_PROTO_FUZZER)
+    # Create protobuf .h and .cc files, and put them in a library for use by
+    # clang-proto-fuzzer components.
+    find_package(Protobuf REQUIRED)
+    add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI)
+    include_directories(${PROTOBUF_INCLUDE_DIRS})
+    include_directories(${CMAKE_CURRENT_BINARY_DIR})
+    protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS cxx_proto.proto)
+    # Hack to bypass LLVM's cmake sources check and allow multiple libraries and
+    # executables from this directory.
+    set(LLVM_OPTIONAL_SOURCES
+      ClangFuzzer.cpp
+      ExampleClangProtoFuzzer.cpp
+      ${PROTO_SRCS}
+      )
+    add_clang_library(clangCXXProto
+      ${PROTO_SRCS}
+      ${PROTO_HDRS}
+
+      LINK_LIBS
+      ${PROTOBUF_LIBRARIES}
+      )
+
+    # Build and include libprotobuf-mutator
+    include(ProtobufMutator)
+    include_directories(${ProtobufMutator_INCLUDE_DIRS})
+
+    # Build the protobuf->C++ translation library and driver.
+    add_clang_subdirectory(proto-to-cxx)
+
+    # Build the protobuf fuzzer
+    add_clang_executable(clang-proto-fuzzer ExampleClangProtoFuzzer.cpp)
+    target_link_libraries(clang-proto-fuzzer
+      ${ProtobufMutator_LIBRARIES}
+      clangCXXProto
+      clangHandleCXX
+      clangProtoToCXX
+      )
+  else()
+    # Hack to bypass LLVM's cmake sources check and allow multiple libraries and
+    # executables from this directory.
+    set(LLVM_OPTIONAL_SOURCES ClangFuzzer.cpp ExampleClangProtoFuzzer.cpp)
+  endif()
+
+  add_clang_subdirectory(handle-cxx)
 
   add_clang_executable(clang-fuzzer
     EXCLUDE_FROM_ALL
@@ -7,15 +54,6 @@
     )
 
   target_link_libraries(clang-fuzzer
-    ${CLANG_FORMAT_LIB_DEPS}
-    clangAST
-    clangBasic
-    clangCodeGen
-    clangDriver
-    clangFrontend
-    clangRewriteFrontend
-    clangStaticAnalyzerFrontend
-    clangTooling
-    LLVMFuzzer
+    clangHandleCXX
     )
 endif()
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/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index a7008f3..45dfa7a 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -9,6 +9,7 @@
   ASTVectorTest.cpp
   CommentLexer.cpp
   CommentParser.cpp
+  DataCollectionTest.cpp
   DeclPrinterTest.cpp
   DeclTest.cpp
   EvaluateAsRValueTest.cpp
diff --git a/unittests/AST/DataCollectionTest.cpp b/unittests/AST/DataCollectionTest.cpp
new file mode 100644
index 0000000..d6bb9cb
--- /dev/null
+++ b/unittests/AST/DataCollectionTest.cpp
@@ -0,0 +1,173 @@
+//===- unittests/AST/DataCollectionTest.cpp -------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains tests for the DataCollection module.
+//
+// They work by hashing the collected data of two nodes and asserting that the
+// hash values are equal iff the nodes are considered equal.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DataCollection.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/StmtVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace tooling;
+using namespace ast_matchers;
+
+namespace {
+class StmtDataCollector : public ConstStmtVisitor<StmtDataCollector> {
+  ASTContext &Context;
+  llvm::MD5 &DataConsumer;
+
+  template <class T> void addData(const T &Data) {
+    data_collection::addDataToConsumer(DataConsumer, Data);
+  }
+
+public:
+  StmtDataCollector(const Stmt *S, ASTContext &Context, llvm::MD5 &DataConsumer)
+      : Context(Context), DataConsumer(DataConsumer) {
+    this->Visit(S);
+  }
+
+#define DEF_ADD_DATA(CLASS, CODE)                                              \
+  template <class Dummy = void> Dummy Visit##CLASS(const CLASS *S) {           \
+    CODE;                                                                      \
+    ConstStmtVisitor<StmtDataCollector>::Visit##CLASS(S);                      \
+  }
+
+#include "../../lib/AST/StmtDataCollectors.inc"
+};
+} // end anonymous namespace
+
+namespace {
+struct StmtHashMatch : public MatchFinder::MatchCallback {
+  unsigned NumFound;
+  llvm::MD5::MD5Result &Hash;
+  StmtHashMatch(llvm::MD5::MD5Result &Hash) : NumFound(0), Hash(Hash) {}
+
+  void run(const MatchFinder::MatchResult &Result) override {
+    const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");
+    if (!S)
+      return;
+    ++NumFound;
+    if (NumFound > 1)
+      return;
+    llvm::MD5 MD5;
+    StmtDataCollector(S, *Result.Context, MD5);
+    MD5.final(Hash);
+  }
+};
+} // end anonymous namespace
+
+static testing::AssertionResult hashStmt(llvm::MD5::MD5Result &Hash,
+                                         const StatementMatcher &StmtMatch,
+                                         StringRef Code) {
+  StmtHashMatch Hasher(Hash);
+  MatchFinder Finder;
+  Finder.addMatcher(StmtMatch, &Hasher);
+  std::unique_ptr<FrontendActionFactory> Factory(
+      newFrontendActionFactory(&Finder));
+  if (!runToolOnCode(Factory->create(), Code))
+    return testing::AssertionFailure()
+           << "Parsing error in \"" << Code.str() << "\"";
+  if (Hasher.NumFound == 0)
+    return testing::AssertionFailure() << "Matcher didn't find any statements";
+  if (Hasher.NumFound > 1)
+    return testing::AssertionFailure()
+           << "Matcher should match only one statement "
+              "(found "
+           << Hasher.NumFound << ")";
+  return testing::AssertionSuccess();
+}
+
+static testing::AssertionResult
+isStmtHashEqual(const StatementMatcher &StmtMatch, StringRef Code1,
+                StringRef Code2) {
+  llvm::MD5::MD5Result Hash1, Hash2;
+  testing::AssertionResult Result = hashStmt(Hash1, StmtMatch, Code1);
+  if (!Result)
+    return Result;
+  if (!(Result = hashStmt(Hash2, StmtMatch, Code2)))
+    return Result;
+
+  return testing::AssertionResult(Hash1 == Hash2);
+}
+
+TEST(StmtDataCollector, TestDeclRefExpr) {
+  ASSERT_TRUE(isStmtHashEqual(declRefExpr().bind("id"), "int x, r = x;",
+                              "int x, r = x;"));
+  ASSERT_FALSE(isStmtHashEqual(declRefExpr().bind("id"), "int x, r = x;",
+                               "int y, r = y;"));
+  ASSERT_FALSE(isStmtHashEqual(declRefExpr().bind("id"), "int x, r = x;",
+                               "namespace n { int x, r = x; };"));
+}
+
+TEST(StmtDataCollector, TestMemberExpr) {
+  ASSERT_TRUE(isStmtHashEqual(memberExpr().bind("id"),
+                              "struct { int x; } X; int r = X.x;",
+                              "struct { int x; } X; int r = (&X)->x;"));
+  ASSERT_TRUE(isStmtHashEqual(memberExpr().bind("id"),
+                              "struct { int x; } X; int r = X.x;",
+                              "struct { int x; } Y; int r = Y.x;"));
+  ASSERT_TRUE(isStmtHashEqual(memberExpr().bind("id"),
+                              "struct { int x; } X; int r = X.x;",
+                              "struct C { int x; } X; int r = X.C::x;"));
+  ASSERT_FALSE(isStmtHashEqual(memberExpr().bind("id"),
+                               "struct { int x; } X; int r = X.x;",
+                               "struct { int y; } X; int r = X.y;"));
+}
+
+TEST(StmtDataCollector, TestIntegerLiteral) {
+  ASSERT_TRUE(
+      isStmtHashEqual(integerLiteral().bind("id"), "int x = 0;", "int x = 0;"));
+  ASSERT_TRUE(
+      isStmtHashEqual(integerLiteral().bind("id"), "int x = 0;", "int x =00;"));
+  ASSERT_FALSE(
+      isStmtHashEqual(integerLiteral().bind("id"), "int x = 0;", "int x = 1;"));
+}
+
+TEST(StmtDataCollector, TestFloatingLiteral) {
+  ASSERT_TRUE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .0;",
+                              "double x = .0;"));
+  ASSERT_TRUE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .10;",
+                              "double x = .1;"));
+  ASSERT_TRUE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .1;",
+                              "double x = 1e-1;"));
+  ASSERT_FALSE(isStmtHashEqual(floatLiteral().bind("id"), "double x = .0;",
+                               "double x = .1;"));
+}
+
+TEST(StmtDataCollector, TestStringLiteral) {
+  ASSERT_TRUE(isStmtHashEqual(stringLiteral().bind("id"), R"(char x[] = "0";)",
+                              R"(char x[] = "0";)"));
+  ASSERT_FALSE(isStmtHashEqual(stringLiteral().bind("id"), R"(char x[] = "0";)",
+                               R"(char x[] = "1";)"));
+}
+
+TEST(StmtDataCollector, TestCXXBoolLiteral) {
+  ASSERT_TRUE(isStmtHashEqual(cxxBoolLiteral().bind("id"), "bool x = false;",
+                              "bool x = false;"));
+  ASSERT_FALSE(isStmtHashEqual(cxxBoolLiteral().bind("id"), "bool x = false;",
+                               "bool x = true;"));
+}
+
+TEST(StmtDataCollector, TestCharacterLiteral) {
+  ASSERT_TRUE(isStmtHashEqual(characterLiteral().bind("id"), "char x = '0';",
+                              "char x = '0';"));
+  ASSERT_TRUE(isStmtHashEqual(characterLiteral().bind("id"),
+                              R"(char x = '\0';)",
+                              R"(char x = '\x00';)"));
+  ASSERT_FALSE(isStmtHashEqual(characterLiteral().bind("id"), "char x = '0';",
+                               "char x = '1';"));
+}
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/AST/StmtPrinterTest.cpp b/unittests/AST/StmtPrinterTest.cpp
index 12b2032..a064440 100644
--- a/unittests/AST/StmtPrinterTest.cpp
+++ b/unittests/AST/StmtPrinterTest.cpp
@@ -31,18 +31,26 @@
 
 namespace {
 
-void PrintStmt(raw_ostream &Out, const ASTContext *Context, const Stmt *S) {
+using PolicyAdjusterType =
+    Optional<llvm::function_ref<void(PrintingPolicy &Policy)>>;
+
+void PrintStmt(raw_ostream &Out, const ASTContext *Context, const Stmt *S,
+               PolicyAdjusterType PolicyAdjuster) {
   assert(S != nullptr && "Expected non-null Stmt");
   PrintingPolicy Policy = Context->getPrintingPolicy();
+  if (PolicyAdjuster)
+    (*PolicyAdjuster)(Policy);
   S->printPretty(Out, /*Helper*/ nullptr, Policy);
 }
 
 class PrintMatch : public MatchFinder::MatchCallback {
   SmallString<1024> Printed;
   unsigned NumFoundStmts;
+  PolicyAdjusterType PolicyAdjuster;
 
 public:
-  PrintMatch() : NumFoundStmts(0) {}
+  PrintMatch(PolicyAdjusterType PolicyAdjuster)
+      : NumFoundStmts(0), PolicyAdjuster(PolicyAdjuster) {}
 
   void run(const MatchFinder::MatchResult &Result) override {
     const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");
@@ -53,7 +61,7 @@
       return;
 
     llvm::raw_svector_ostream Out(Printed);
-    PrintStmt(Out, Result.Context, S);
+    PrintStmt(Out, Result.Context, S, PolicyAdjuster);
   }
 
   StringRef getPrinted() const {
@@ -68,9 +76,10 @@
 template <typename T>
 ::testing::AssertionResult
 PrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
-                   const T &NodeMatch, StringRef ExpectedPrinted) {
+                   const T &NodeMatch, StringRef ExpectedPrinted,
+                   PolicyAdjusterType PolicyAdjuster = None) {
 
-  PrintMatch Printer;
+  PrintMatch Printer(PolicyAdjuster);
   MatchFinder Finder;
   Finder.addMatcher(NodeMatch, &Printer);
   std::unique_ptr<FrontendActionFactory> Factory(
@@ -122,11 +131,13 @@
 
 ::testing::AssertionResult
 PrintedStmtCXX11Matches(StringRef Code, const StatementMatcher &NodeMatch,
-                        StringRef ExpectedPrinted) {
+                        StringRef ExpectedPrinted,
+                        PolicyAdjusterType PolicyAdjuster = None) {
   std::vector<std::string> Args;
   Args.push_back("-std=c++11");
   Args.push_back("-Wno-unused-value");
-  return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted);
+  return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted,
+                            PolicyAdjuster);
 }
 
 ::testing::AssertionResult PrintedStmtMSMatches(
@@ -146,6 +157,17 @@
                             ExpectedPrinted);
 }
 
+::testing::AssertionResult
+PrintedStmtObjCMatches(StringRef Code, const StatementMatcher &NodeMatch,
+                       StringRef ExpectedPrinted,
+                       PolicyAdjusterType PolicyAdjuster = None) {
+  std::vector<std::string> Args;
+  Args.push_back("-ObjC");
+  Args.push_back("-fobjc-runtime=macosx-10.12.0");
+  return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted,
+                            PolicyAdjuster);
+}
+
 } // unnamed namespace
 
 TEST(StmtPrinter, TestIntegerLiteral) {
@@ -214,3 +236,41 @@
     "(a & b)"));
     // WRONG; Should be: (a & b).operator void *()
 }
+
+TEST(StmtPrinter, TestNoImplicitBases) {
+  const char *CPPSource = R"(
+class A {
+  int field;
+  int member() { return field; }
+};
+)";
+  // No implicit 'this'.
+  ASSERT_TRUE(PrintedStmtCXX11Matches(
+      CPPSource, memberExpr(anything()).bind("id"), "field",
+      PolicyAdjusterType(
+          [](PrintingPolicy &PP) { PP.SuppressImplicitBase = true; })));
+  // Print implicit 'this'.
+  ASSERT_TRUE(PrintedStmtCXX11Matches(
+      CPPSource, memberExpr(anything()).bind("id"), "this->field"));
+
+  const char *ObjCSource = R"(
+@interface I {
+   int ivar;
+}
+@end
+@implementation I
+- (int) method {
+  return ivar;
+}
+@end
+      )";
+  // No implicit 'self'.
+  ASSERT_TRUE(PrintedStmtObjCMatches(ObjCSource, returnStmt().bind("id"),
+                                     "return ivar;\n",
+                                     PolicyAdjusterType([](PrintingPolicy &PP) {
+                                       PP.SuppressImplicitBase = true;
+                                     })));
+  // Print implicit 'self'.
+  ASSERT_TRUE(PrintedStmtObjCMatches(ObjCSource, returnStmt().bind("id"),
+                                     "return self->ivar;\n"));
+}
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/Analysis/CloneDetectionTest.cpp b/unittests/Analysis/CloneDetectionTest.cpp
index 6d8ce34..965a4bc 100644
--- a/unittests/Analysis/CloneDetectionTest.cpp
+++ b/unittests/Analysis/CloneDetectionTest.cpp
@@ -69,8 +69,9 @@
   // all statements from functions which names start with "bar".
   std::vector<CloneDetector::CloneGroup> CloneGroups;
   Detector.findClones(CloneGroups, NoBarFunctionConstraint(),
-                      RecursiveCloneTypeIIConstraint(),
+                      RecursiveCloneTypeIIHashConstraint(),
                       MinComplexityConstraint(2), MinGroupSizeConstraint(2),
+                      RecursiveCloneTypeIIVerifyConstraint(),
                       OnlyLargestCloneConstraint());
 
   ASSERT_EQ(CloneGroups.size(), 1u);
@@ -86,8 +87,9 @@
   // Retry above's example without the filter...
   CloneGroups.clear();
 
-  Detector.findClones(CloneGroups, RecursiveCloneTypeIIConstraint(),
+  Detector.findClones(CloneGroups, RecursiveCloneTypeIIHashConstraint(),
                       MinComplexityConstraint(2), MinGroupSizeConstraint(2),
+                      RecursiveCloneTypeIIVerifyConstraint(),
                       OnlyLargestCloneConstraint());
   ASSERT_EQ(CloneGroups.size(), 1u);
   ASSERT_EQ(CloneGroups.front().size(), 4u);
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/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index 923aff1..40e4360 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -420,4 +420,9 @@
 #endif
 }
 
+TEST_F(LexerTest, AvoidPastEndOfStringDereference) {
+  std::vector<Token> LexedTokens = Lex("  //  \\\n");
+  EXPECT_TRUE(LexedTokens.empty());
+}
+
 } // anonymous namespace
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/analyzer/CmpRuns.py b/utils/analyzer/CmpRuns.py
index 2d1f44f..2c0ed6a 100755
--- a/utils/analyzer/CmpRuns.py
+++ b/utils/analyzer/CmpRuns.py
@@ -6,8 +6,8 @@
 
 This is designed to support automated testing using the static analyzer, from
 two perspectives:
-  1. To monitor changes in the static analyzer's reports on real code bases, for
-     regression testing.
+  1. To monitor changes in the static analyzer's reports on real code bases,
+     for regression testing.
 
   2. For use by end users who want to integrate regular static analyzer testing
      into a buildbot like environment.
@@ -28,7 +28,7 @@
 
 import os
 import plistlib
-import CmpRuns
+
 
 # Information about analysis run:
 # path - the analysis output directory
@@ -40,6 +40,7 @@
         self.root = root.rstrip("/\\")
         self.verboseLog = verboseLog
 
+
 class AnalysisDiagnostic:
     def __init__(self, data, report, htmlReport):
         self._data = data
@@ -51,7 +52,7 @@
         root = self._report.run.root
         fileName = self._report.files[self._loc['file']]
         if fileName.startswith(root) and len(root) > 0:
-            return fileName[len(root)+1:]
+            return fileName[len(root) + 1:]
         return fileName
 
     def getLine(self):
@@ -66,12 +67,12 @@
     def getDescription(self):
         return self._data['description']
 
-    def getIssueIdentifier(self) :
+    def getIssueIdentifier(self):
         id = self.getFileName() + "+"
-        if 'issue_context' in self._data :
-          id += self._data['issue_context'] + "+"
-        if 'issue_hash_content_of_line_in_context' in self._data :
-          id += str(self._data['issue_hash_content_of_line_in_context'])
+        if 'issue_context' in self._data:
+            id += self._data['issue_context'] + "+"
+        if 'issue_hash_content_of_line_in_context' in self._data:
+            id += str(self._data['issue_hash_content_of_line_in_context'])
         return id
 
     def getReport(self):
@@ -89,29 +90,6 @@
     def getRawData(self):
         return self._data
 
-class multidict:
-    def __init__(self, elts=()):
-        self.data = {}
-        for key,value in elts:
-            self[key] = value
-
-    def __getitem__(self, item):
-        return self.data[item]
-    def __setitem__(self, key, value):
-        if key in self.data:
-            self.data[key].append(value)
-        else:
-            self.data[key] = [value]
-    def items(self):
-        return self.data.items()
-    def values(self):
-        return self.data.values()
-    def keys(self):
-        return self.data.keys()
-    def __len__(self):
-        return len(self.data)
-    def get(self, key, default=None):
-        return self.data.get(key, default)
 
 class CmpOptions:
     def __init__(self, verboseLog=None, rootA="", rootB=""):
@@ -119,12 +97,14 @@
         self.rootB = rootB
         self.verboseLog = verboseLog
 
+
 class AnalysisReport:
     def __init__(self, run, files):
         self.run = run
         self.files = files
         self.diagnostics = []
 
+
 class AnalysisRun:
     def __init__(self, info):
         self.path = info.path
@@ -145,14 +125,14 @@
         # reports. Assume that all reports were created using the same
         # clang version (this is always true and is more efficient).
         if 'clang_version' in data:
-            if self.clang_version == None:
+            if self.clang_version is None:
                 self.clang_version = data.pop('clang_version')
             else:
                 data.pop('clang_version')
 
         # Ignore/delete empty reports.
         if not data['files']:
-            if deleteEmpty == True:
+            if deleteEmpty:
                 os.remove(p)
             return
 
@@ -169,8 +149,7 @@
 
         report = AnalysisReport(self, data.pop('files'))
         diagnostics = [AnalysisDiagnostic(d, report, h)
-                       for d,h in zip(data.pop('diagnostics'),
-                                      htmlFiles)]
+                       for d, h in zip(data.pop('diagnostics'), htmlFiles)]
 
         assert not data
 
@@ -179,15 +158,21 @@
         self.diagnostics.extend(diagnostics)
 
 
-# Backward compatibility API.
-def loadResults(path, opts, root = "", deleteEmpty=True):
+def loadResults(path, opts, root="", deleteEmpty=True):
+    """
+    Backwards compatibility API.
+    """
     return loadResultsFromSingleRun(SingleRunInfo(path, root, opts.verboseLog),
                                     deleteEmpty)
 
-# Load results of the analyzes from a given output folder.
-# - info is the SingleRunInfo object
-# - deleteEmpty specifies if the empty plist files should be deleted
+
 def loadResultsFromSingleRun(info, deleteEmpty=True):
+    """
+    # Load results of the analyzes from a given output folder.
+    # - info is the SingleRunInfo object
+    # - deleteEmpty specifies if the empty plist files should be deleted
+
+    """
     path = info.path
     run = AnalysisRun(info)
 
@@ -203,9 +188,11 @@
 
     return run
 
-def cmpAnalysisDiagnostic(d) :
+
+def cmpAnalysisDiagnostic(d):
     return d.getIssueIdentifier()
 
+
 def compareResults(A, B):
     """
     compareResults - Generate a relation from diagnostics in run A to
@@ -224,12 +211,12 @@
     neqB = []
     eltsA = list(A.diagnostics)
     eltsB = list(B.diagnostics)
-    eltsA.sort(key = cmpAnalysisDiagnostic)
-    eltsB.sort(key = cmpAnalysisDiagnostic)
+    eltsA.sort(key=cmpAnalysisDiagnostic)
+    eltsB.sort(key=cmpAnalysisDiagnostic)
     while eltsA and eltsB:
         a = eltsA.pop()
         b = eltsB.pop()
-        if (a.getIssueIdentifier() == b.getIssueIdentifier()) :
+        if (a.getIssueIdentifier() == b.getIssueIdentifier()):
             res.append((a, b, 0))
         elif a.getIssueIdentifier() > b.getIssueIdentifier():
             eltsB.append(b)
@@ -240,11 +227,11 @@
     neqA.extend(eltsA)
     neqB.extend(eltsB)
 
-    # FIXME: Add fuzzy matching. One simple and possible effective idea would be
-    # to bin the diagnostics, print them in a normalized form (based solely on
-    # the structure of the diagnostic), compute the diff, then use that as the
-    # basis for matching. This has the nice property that we don't depend in any
-    # way on the diagnostic format.
+    # FIXME: Add fuzzy matching. One simple and possible effective idea would
+    # be to bin the diagnostics, print them in a normalized form (based solely
+    # on the structure of the diagnostic), compute the diff, then use that as
+    # the basis for matching. This has the nice property that we don't depend
+    # in any way on the diagnostic format.
 
     for a in neqA:
         res.append((a, None, None))
@@ -253,6 +240,7 @@
 
     return res
 
+
 def dumpScanBuildResultsDiff(dirA, dirB, opts, deleteEmpty=True):
     # Load the run results.
     resultsA = loadResults(dirA, opts, opts.rootA, deleteEmpty)
@@ -267,7 +255,7 @@
     diff = compareResults(resultsA, resultsB)
     foundDiffs = 0
     for res in diff:
-        a,b,confidence = res
+        a, b, confidence = res
         if a is None:
             print "ADDED: %r" % b.getReadableName()
             foundDiffs += 1
@@ -302,6 +290,7 @@
 
     return foundDiffs, len(resultsA.diagnostics), len(resultsB.diagnostics)
 
+
 def main():
     from optparse import OptionParser
     parser = OptionParser("usage: %prog [options] [dir A] [dir B]")
@@ -312,7 +301,8 @@
                       help="Prefix to ignore on source files for directory B",
                       action="store", type=str, default="")
     parser.add_option("", "--verbose-log", dest="verboseLog",
-                      help="Write additional information to LOG [default=None]",
+                      help="Write additional information to LOG \
+                      [default=None]",
                       action="store", type=str, default=None,
                       metavar="LOG")
     (opts, args) = parser.parse_args()
@@ -320,9 +310,10 @@
     if len(args) != 2:
         parser.error("invalid number of arguments")
 
-    dirA,dirB = args
+    dirA, dirB = args
 
     dumpScanBuildResultsDiff(dirA, dirB, opts)
 
+
 if __name__ == '__main__':
     main()
diff --git a/utils/analyzer/SATestAdd.py b/utils/analyzer/SATestAdd.py
index 4b94a10..4c3e35c 100755
--- a/utils/analyzer/SATestAdd.py
+++ b/utils/analyzer/SATestAdd.py
@@ -27,15 +27,17 @@
       - CachedSource/ - An optional directory containing the source of the
                                      project being analyzed. If present,
                                      download_project.sh will not be called.
-      - changes_for_analyzer.patch - An optional patch file for any local changes
+      - changes_for_analyzer.patch - An optional patch file for any local
+                                     changes
                                      (e.g., to adapt to newer version of clang)
                                      that should be applied to CachedSource
                                      before analysis. To construct this patch,
                                      run the the download script to download
                                      the project to CachedSource, copy the
                                      CachedSource to another directory (for
-                                     example, PatchedSource) and make any needed
-                                     modifications to the the copied source.
+                                     example, PatchedSource) and make any
+                                     needed modifications to the the copied
+                                     source.
                                      Then run:
                                           diff -ur CachedSource PatchedSource \
                                               > changes_for_analyzer.patch
@@ -46,18 +48,21 @@
 import csv
 import sys
 
-def isExistingProject(PMapFile, projectID) :
+
+def isExistingProject(PMapFile, projectID):
     PMapReader = csv.reader(PMapFile)
     for I in PMapReader:
         if projectID == I[0]:
             return True
     return False
 
-# Add a new project for testing: build it and add to the Project Map file.
-# Params:
-#   Dir is the directory where the sources are.
-#   ID is a short string used to identify a project.
-def addNewProject(ID, BuildMode) :
+
+def addNewProject(ID, BuildMode):
+    """
+    Add a new project for testing: build it and add to the Project Map file.
+    :param ID: is a short string used to identify a project.
+    """
+
     CurDir = os.path.abspath(os.curdir)
     Dir = SATestBuild.getProjectDir(ID)
     if not os.path.exists(Dir):
@@ -65,36 +70,37 @@
         sys.exit(-1)
 
     # Build the project.
-    SATestBuild.testProject(ID, BuildMode, IsReferenceBuild=True, Dir=Dir)
+    SATestBuild.testProject(ID, BuildMode, IsReferenceBuild=True)
 
     # Add the project ID to the project map.
     ProjectMapPath = os.path.join(CurDir, SATestBuild.ProjectMapFile)
+
     if os.path.exists(ProjectMapPath):
-        PMapFile = open(ProjectMapPath, "r+b")
+        FileMode = "r+b"
     else:
         print "Warning: Creating the Project Map file!!"
-        PMapFile = open(ProjectMapPath, "w+b")
-    try:
-        if (isExistingProject(PMapFile, ID)) :
+        FileMode = "w+b"
+
+    with open(ProjectMapPath, FileMode) as PMapFile:
+        if (isExistingProject(PMapFile, ID)):
             print >> sys.stdout, 'Warning: Project with ID \'', ID, \
                                  '\' already exists.'
             print >> sys.stdout, "Reference output has been regenerated."
         else:
             PMapWriter = csv.writer(PMapFile)
-            PMapWriter.writerow( (ID, int(BuildMode)) );
+            PMapWriter.writerow((ID, int(BuildMode)))
             print "The project map is updated: ", ProjectMapPath
-    finally:
-        PMapFile.close()
 
 
 # TODO: Add an option not to build.
 # TODO: Set the path to the Repository directory.
 if __name__ == '__main__':
-    if len(sys.argv) < 2:
-        print >> sys.stderr, 'Usage: ', sys.argv[0],\
-                             'project_ID <mode>' \
-                             'mode - 0 for single file project; ' \
-                             '1 for scan_build; ' \
+    if len(sys.argv) < 2 or sys.argv[1] in ('-h', '--help'):
+        print >> sys.stderr, 'Add a new project for testing to the analyzer'\
+                             '\nUsage: ', sys.argv[0],\
+                             'project_ID <mode>\n' \
+                             'mode: 0 for single file project, ' \
+                             '1 for scan_build, ' \
                              '2 for single file c++11 project'
         sys.exit(-1)
 
diff --git a/utils/analyzer/SATestBuild.py b/utils/analyzer/SATestBuild.py
index 18c5393..c131095 100755
--- a/utils/analyzer/SATestBuild.py
+++ b/utils/analyzer/SATestBuild.py
@@ -3,8 +3,8 @@
 """
 Static Analyzer qualification infrastructure.
 
-The goal is to test the analyzer against different projects, check for failures,
-compare results, and measure performance.
+The goal is to test the analyzer against different projects,
+check for failures, compare results, and measure performance.
 
 Repository Directory will contain sources of the projects as well as the
 information on how to build them and the expected output.
@@ -20,7 +20,8 @@
 
 To test the build of the analyzer one would:
    - Copy over a copy of the Repository Directory. (TODO: Prefer to ensure that
-     the build directory does not pollute the repository to min network traffic).
+     the build directory does not pollute the repository to min network
+     traffic).
    - Build all projects, until error. Produce logs to report errors.
    - Compare results.
 
@@ -53,102 +54,96 @@
 import plistlib
 import argparse
 from subprocess import check_call, check_output, CalledProcessError
+import multiprocessing
 
 #------------------------------------------------------------------------------
 # Helper functions.
 #------------------------------------------------------------------------------
 
-def detectCPUs():
-    """
-    Detects the number of CPUs on a system. Cribbed from pp.
-    """
-    # Linux, Unix and MacOS:
-    if hasattr(os, "sysconf"):
-        if os.sysconf_names.has_key("SC_NPROCESSORS_ONLN"):
-            # Linux & Unix:
-            ncpus = os.sysconf("SC_NPROCESSORS_ONLN")
-            if isinstance(ncpus, int) and ncpus > 0:
-                return ncpus
-        else: # OSX:
-            return int(capture(['sysctl', '-n', 'hw.ncpu']))
-    # Windows:
-    if os.environ.has_key("NUMBER_OF_PROCESSORS"):
-        ncpus = int(os.environ["NUMBER_OF_PROCESSORS"])
-        if ncpus > 0:
-            return ncpus
-    return 1 # Default
 
-def which(command, paths = None):
-   """which(command, [paths]) - Look up the given command in the paths string
-   (or the PATH environment variable, if unspecified)."""
+def which(command, paths=None):
+    """which(command, [paths]) - Look up the given command in the paths string
+    (or the PATH environment variable, if unspecified)."""
 
-   if paths is None:
-       paths = os.environ.get('PATH','')
+    if paths is None:
+        paths = os.environ.get('PATH', '')
 
-   # Check for absolute match first.
-   if os.path.exists(command):
-       return command
+    # Check for absolute match first.
+    if os.path.exists(command):
+        return command
 
-   # Would be nice if Python had a lib function for this.
-   if not paths:
-       paths = os.defpath
+    # Would be nice if Python had a lib function for this.
+    if not paths:
+        paths = os.defpath
 
-   # Get suffixes to search.
-   # On Cygwin, 'PATHEXT' may exist but it should not be used.
-   if os.pathsep == ';':
-       pathext = os.environ.get('PATHEXT', '').split(';')
-   else:
-       pathext = ['']
+    # Get suffixes to search.
+    # On Cygwin, 'PATHEXT' may exist but it should not be used.
+    if os.pathsep == ';':
+        pathext = os.environ.get('PATHEXT', '').split(';')
+    else:
+        pathext = ['']
 
-   # Search the paths...
-   for path in paths.split(os.pathsep):
-       for ext in pathext:
-           p = os.path.join(path, command + ext)
-           if os.path.exists(p):
-               return p
+    # Search the paths...
+    for path in paths.split(os.pathsep):
+        for ext in pathext:
+            p = os.path.join(path, command + ext)
+            if os.path.exists(p):
+                return p
 
-   return None
+    return None
 
-# Make sure we flush the output after every print statement.
+
 class flushfile(object):
+    """
+    Wrapper to flush the output after every print statement.
+    """
     def __init__(self, f):
         self.f = f
+
     def write(self, x):
         self.f.write(x)
         self.f.flush()
 
+
 sys.stdout = flushfile(sys.stdout)
 
+
 def getProjectMapPath():
     ProjectMapPath = os.path.join(os.path.abspath(os.curdir),
                                   ProjectMapFile)
     if not os.path.exists(ProjectMapPath):
         print "Error: Cannot find the Project Map file " + ProjectMapPath +\
-                "\nRunning script for the wrong directory?"
+              "\nRunning script for the wrong directory?"
         sys.exit(-1)
     return ProjectMapPath
 
+
 def getProjectDir(ID):
     return os.path.join(os.path.abspath(os.curdir), ID)
 
-def getSBOutputDirName(IsReferenceBuild) :
-    if IsReferenceBuild == True :
+
+def getSBOutputDirName(IsReferenceBuild):
+    if IsReferenceBuild:
         return SBOutputDirReferencePrefix + SBOutputDirName
-    else :
+    else:
         return SBOutputDirName
 
 #------------------------------------------------------------------------------
 # Configuration setup.
 #------------------------------------------------------------------------------
 
+
 # Find Clang for static analysis.
-Clang = which("clang", os.environ['PATH'])
+if 'CC' in os.environ:
+    Clang = os.environ['CC']
+else:
+    Clang = which("clang", os.environ['PATH'])
 if not Clang:
     print "Error: cannot find 'clang' in PATH"
     sys.exit(-1)
 
 # Number of jobs.
-Jobs = int(math.ceil(detectCPUs() * 0.75))
+Jobs = int(math.ceil(multiprocessing.cpu_count() * 0.75))
 
 # Project map stores info about all the "registered" projects.
 ProjectMapFile = "projectMap.csv"
@@ -175,9 +170,10 @@
 SBOutputDirName = "ScanBuildResults"
 SBOutputDirReferencePrefix = "Ref"
 
-# The name of the directory storing the cached project source. If this directory
-# does not exist, the download script will be executed. That script should
-# create the "CachedSource" directory and download the project source into it.
+# The name of the directory storing the cached project source. If this
+# directory does not exist, the download script will be executed.
+# That script should create the "CachedSource" directory and download the
+# project source into it.
 CachedSourceDirName = "CachedSource"
 
 # The name of the directory containing the source code that will be analyzed.
@@ -193,7 +189,18 @@
 # The list of checkers used during analyzes.
 # Currently, consists of all the non-experimental checkers, plus a few alpha
 # checkers we don't want to regress on.
-Checkers="alpha.unix.SimpleStream,alpha.security.taint,cplusplus.NewDeleteLeaks,core,cplusplus,deadcode,security,unix,osx"
+Checkers = ",".join([
+    "alpha.unix.SimpleStream",
+    "alpha.security.taint",
+    "cplusplus.NewDeleteLeaks",
+    "core",
+    "cplusplus",
+    "deadcode",
+    "security",
+    "unix",
+    "osx",
+    "nullability"
+])
 
 Verbose = 1
 
@@ -201,46 +208,60 @@
 # Test harness logic.
 #------------------------------------------------------------------------------
 
-# Run pre-processing script if any.
+
 def runCleanupScript(Dir, PBuildLogFile):
+    """
+    Run pre-processing script if any.
+    """
     Cwd = os.path.join(Dir, PatchedSourceDirName)
     ScriptPath = os.path.join(Dir, CleanupScript)
     runScript(ScriptPath, PBuildLogFile, Cwd)
 
-# Run the script to download the project, if it exists.
+
 def runDownloadScript(Dir, PBuildLogFile):
+    """
+    Run the script to download the project, if it exists.
+    """
     ScriptPath = os.path.join(Dir, DownloadScript)
     runScript(ScriptPath, PBuildLogFile, Dir)
 
-# Run the provided script if it exists.
+
 def runScript(ScriptPath, PBuildLogFile, Cwd):
+    """
+    Run the provided script if it exists.
+    """
     if os.path.exists(ScriptPath):
         try:
             if Verbose == 1:
                 print "  Executing: %s" % (ScriptPath,)
-            check_call("chmod +x '%s'" % ScriptPath, cwd = Cwd,
-                                              stderr=PBuildLogFile,
-                                              stdout=PBuildLogFile,
-                                              shell=True)
-            check_call("'%s'" % ScriptPath, cwd = Cwd, stderr=PBuildLogFile,
-                                              stdout=PBuildLogFile,
-                                              shell=True)
+            check_call("chmod +x '%s'" % ScriptPath, cwd=Cwd,
+                       stderr=PBuildLogFile,
+                       stdout=PBuildLogFile,
+                       shell=True)
+            check_call("'%s'" % ScriptPath, cwd=Cwd,
+                       stderr=PBuildLogFile,
+                       stdout=PBuildLogFile,
+                       shell=True)
         except:
-            print "Error: Running %s failed. See %s for details." % (ScriptPath,
-                PBuildLogFile.name)
+            print "Error: Running %s failed. See %s for details." % (
+                  ScriptPath, PBuildLogFile.name)
             sys.exit(-1)
 
-# Download the project and apply the local patchfile if it exists.
+
 def downloadAndPatch(Dir, PBuildLogFile):
+    """
+    Download the project and apply the local patchfile if it exists.
+    """
     CachedSourceDirPath = os.path.join(Dir, CachedSourceDirName)
 
     # If the we don't already have the cached source, run the project's
     # download script to download it.
     if not os.path.exists(CachedSourceDirPath):
-      runDownloadScript(Dir, PBuildLogFile)
-      if not os.path.exists(CachedSourceDirPath):
-        print "Error: '%s' not found after download." % (CachedSourceDirPath)
-        exit(-1)
+        runDownloadScript(Dir, PBuildLogFile)
+        if not os.path.exists(CachedSourceDirPath):
+            print "Error: '%s' not found after download." % (
+                  CachedSourceDirPath)
+            exit(-1)
 
     PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName)
 
@@ -252,6 +273,7 @@
     shutil.copytree(CachedSourceDirPath, PatchedSourceDirPath, symlinks=True)
     applyPatch(Dir, PBuildLogFile)
 
+
 def applyPatch(Dir, PBuildLogFile):
     PatchfilePath = os.path.join(Dir, PatchfileName)
     PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName)
@@ -262,30 +284,33 @@
     print "  Applying patch."
     try:
         check_call("patch -p1 < '%s'" % (PatchfilePath),
-                    cwd = PatchedSourceDirPath,
-                    stderr=PBuildLogFile,
-                    stdout=PBuildLogFile,
-                    shell=True)
+                   cwd=PatchedSourceDirPath,
+                   stderr=PBuildLogFile,
+                   stdout=PBuildLogFile,
+                   shell=True)
     except:
         print "Error: Patch failed. See %s for details." % (PBuildLogFile.name)
         sys.exit(-1)
 
-# Build the project with scan-build by reading in the commands and
-# prefixing them with the scan-build options.
+
 def runScanBuild(Dir, SBOutputDir, PBuildLogFile):
+    """
+    Build the project with scan-build by reading in the commands and
+    prefixing them with the scan-build options.
+    """
     BuildScriptPath = os.path.join(Dir, BuildScript)
     if not os.path.exists(BuildScriptPath):
         print "Error: build script is not defined: %s" % BuildScriptPath
         sys.exit(-1)
 
     AllCheckers = Checkers
-    if os.environ.has_key('SA_ADDITIONAL_CHECKERS'):
+    if 'SA_ADDITIONAL_CHECKERS' in os.environ:
         AllCheckers = AllCheckers + ',' + os.environ['SA_ADDITIONAL_CHECKERS']
 
     # Run scan-build from within the patched source directory.
     SBCwd = os.path.join(Dir, PatchedSourceDirName)
 
-    SBOptions = "--use-analyzer '%s' " %  Clang
+    SBOptions = "--use-analyzer '%s' " % Clang
     SBOptions += "-plist-html -o '%s' " % SBOutputDir
     SBOptions += "-enable-checker " + AllCheckers + " "
     SBOptions += "--keep-empty "
@@ -298,52 +323,55 @@
         for Command in SBCommandFile:
             Command = Command.strip()
             if len(Command) == 0:
-                continue;
+                continue
             # If using 'make', auto imply a -jX argument
             # to speed up analysis.  xcodebuild will
             # automatically use the maximum number of cores.
             if (Command.startswith("make ") or Command == "make") and \
-                "-j" not in Command:
+                    "-j" not in Command:
                 Command += " -j%d" % Jobs
             SBCommand = SBPrefix + Command
             if Verbose == 1:
                 print "  Executing: %s" % (SBCommand,)
-            check_call(SBCommand, cwd = SBCwd, stderr=PBuildLogFile,
-                                               stdout=PBuildLogFile,
-                                               shell=True)
+            check_call(SBCommand, cwd=SBCwd,
+                       stderr=PBuildLogFile,
+                       stdout=PBuildLogFile,
+                       shell=True)
     except:
-        print "Error: scan-build failed. See ",PBuildLogFile.name,\
+        print "Error: scan-build failed. See ", PBuildLogFile.name,\
               " for details."
         raise
 
+
 def hasNoExtension(FileName):
     (Root, Ext) = os.path.splitext(FileName)
-    if ((Ext == "")) :
-        return True
-    return False
+    return (Ext == "")
+
 
 def isValidSingleInputFile(FileName):
     (Root, Ext) = os.path.splitext(FileName)
-    if ((Ext == ".i") | (Ext == ".ii") |
-        (Ext == ".c") | (Ext == ".cpp") |
-        (Ext == ".m") | (Ext == "")) :
-        return True
-    return False
+    return Ext in (".i", ".ii", ".c", ".cpp", ".m", "")
 
-# Get the path to the SDK for the given SDK name. Returns None if
-# the path cannot be determined.
+
 def getSDKPath(SDKName):
+    """
+    Get the path to the SDK for the given SDK name. Returns None if
+    the path cannot be determined.
+    """
     if which("xcrun") is None:
         return None
 
     Cmd = "xcrun --sdk " + SDKName + " --show-sdk-path"
     return check_output(Cmd, shell=True).rstrip()
 
-# Run analysis on a set of preprocessed files.
+
 def runAnalyzePreprocessed(Dir, SBOutputDir, Mode):
+    """
+    Run analysis on a set of preprocessed files.
+    """
     if os.path.exists(os.path.join(Dir, BuildScript)):
         print "Error: The preprocessed files project should not contain %s" % \
-               BuildScript
+              BuildScript
         raise Exception()
 
     CmdPrefix = Clang + " -cc1 "
@@ -352,17 +380,18 @@
     # with the OS X SDK.
     SDKPath = getSDKPath("macosx")
     if SDKPath is not None:
-      CmdPrefix += "-isysroot " + SDKPath + " "
+        CmdPrefix += "-isysroot " + SDKPath + " "
 
     CmdPrefix += "-analyze -analyzer-output=plist -w "
-    CmdPrefix += "-analyzer-checker=" + Checkers +" -fcxx-exceptions -fblocks "
+    CmdPrefix += "-analyzer-checker=" + Checkers
+    CmdPrefix += " -fcxx-exceptions -fblocks "
 
-    if (Mode == 2) :
+    if (Mode == 2):
         CmdPrefix += "-std=c++11 "
 
     PlistPath = os.path.join(Dir, SBOutputDir, "date")
-    FailPath = os.path.join(PlistPath, "failures");
-    os.makedirs(FailPath);
+    FailPath = os.path.join(PlistPath, "failures")
+    os.makedirs(FailPath)
 
     for FullFileName in glob.glob(Dir + "/*"):
         FileName = os.path.basename(FullFileName)
@@ -371,7 +400,7 @@
         # Only run the analyzes on supported files.
         if (hasNoExtension(FileName)):
             continue
-        if (isValidSingleInputFile(FileName) == False):
+        if (not isValidSingleInputFile(FileName)):
             print "Error: Invalid single input file %s." % (FullFileName,)
             raise Exception()
 
@@ -382,44 +411,47 @@
         try:
             if Verbose == 1:
                 print "  Executing: %s" % (Command,)
-            check_call(Command, cwd = Dir, stderr=LogFile,
-                                           stdout=LogFile,
-                                           shell=True)
+            check_call(Command, cwd=Dir, stderr=LogFile,
+                       stdout=LogFile,
+                       shell=True)
         except CalledProcessError, e:
             print "Error: Analyzes of %s failed. See %s for details." \
-                  "Error code %d." % \
-                   (FullFileName, LogFile.name, e.returncode)
+                  "Error code %d." % (
+                      FullFileName, LogFile.name, e.returncode)
             Failed = True
         finally:
             LogFile.close()
 
         # If command did not fail, erase the log file.
-        if Failed == False:
-            os.remove(LogFile.name);
+        if not Failed:
+            os.remove(LogFile.name)
+
 
 def getBuildLogPath(SBOutputDir):
-  return os.path.join(SBOutputDir, LogFolderName, BuildLogName)
+    return os.path.join(SBOutputDir, LogFolderName, BuildLogName)
+
 
 def removeLogFile(SBOutputDir):
-  BuildLogPath = getBuildLogPath(SBOutputDir)
-  # Clean up the log file.
-  if (os.path.exists(BuildLogPath)) :
-      RmCommand = "rm '%s'" % BuildLogPath
-      if Verbose == 1:
-          print "  Executing: %s" % (RmCommand,)
-      check_call(RmCommand, shell=True)
+    BuildLogPath = getBuildLogPath(SBOutputDir)
+    # Clean up the log file.
+    if (os.path.exists(BuildLogPath)):
+        RmCommand = "rm '%s'" % BuildLogPath
+        if Verbose == 1:
+            print "  Executing: %s" % (RmCommand,)
+        check_call(RmCommand, shell=True)
+
 
 def buildProject(Dir, SBOutputDir, ProjectBuildMode, IsReferenceBuild):
     TBegin = time.time()
 
     BuildLogPath = getBuildLogPath(SBOutputDir)
     print "Log file: %s" % (BuildLogPath,)
-    print "Output directory: %s" %(SBOutputDir, )
+    print "Output directory: %s" % (SBOutputDir, )
 
     removeLogFile(SBOutputDir)
 
     # Clean up scan build results.
-    if (os.path.exists(SBOutputDir)) :
+    if (os.path.exists(SBOutputDir)):
         RmCommand = "rm -r '%s'" % SBOutputDir
         if Verbose == 1:
             print "  Executing: %s" % (RmCommand,)
@@ -427,11 +459,8 @@
     assert(not os.path.exists(SBOutputDir))
     os.makedirs(os.path.join(SBOutputDir, LogFolderName))
 
-    # Open the log file.
-    PBuildLogFile = open(BuildLogPath, "wb+")
-
     # Build and analyze the project.
-    try:
+    with open(BuildLogPath, "wb+") as PBuildLogFile:
         if (ProjectBuildMode == 1):
             downloadAndPatch(Dir, PBuildLogFile)
             runCleanupScript(Dir, PBuildLogFile)
@@ -439,34 +468,40 @@
         else:
             runAnalyzePreprocessed(Dir, SBOutputDir, ProjectBuildMode)
 
-        if IsReferenceBuild :
+        if IsReferenceBuild:
             runCleanupScript(Dir, PBuildLogFile)
-
-            # Make the absolute paths relative in the reference results.
-            for (DirPath, Dirnames, Filenames) in os.walk(SBOutputDir):
-                for F in Filenames:
-                    if (not F.endswith('plist')):
-                        continue
-                    Plist = os.path.join(DirPath, F)
-                    Data = plistlib.readPlist(Plist)
-                    PathPrefix = Dir
-                    if (ProjectBuildMode == 1):
-                        PathPrefix = os.path.join(Dir, PatchedSourceDirName)
-                    Paths = [SourceFile[len(PathPrefix)+1:]\
-                              if SourceFile.startswith(PathPrefix)\
-                              else SourceFile for SourceFile in Data['files']]
-                    Data['files'] = Paths
-                    plistlib.writePlist(Data, Plist)
-
-    finally:
-        PBuildLogFile.close()
+            normalizeReferenceResults(Dir, SBOutputDir, ProjectBuildMode)
 
     print "Build complete (time: %.2f). See the log for more details: %s" % \
-           ((time.time()-TBegin), BuildLogPath)
+          ((time.time() - TBegin), BuildLogPath)
 
-# A plist file is created for each call to the analyzer(each source file).
-# We are only interested on the once that have bug reports, so delete the rest.
+
+def normalizeReferenceResults(Dir, SBOutputDir, ProjectBuildMode):
+    """
+    Make the absolute paths relative in the reference results.
+    """
+    for (DirPath, Dirnames, Filenames) in os.walk(SBOutputDir):
+        for F in Filenames:
+            if (not F.endswith('plist')):
+                continue
+            Plist = os.path.join(DirPath, F)
+            Data = plistlib.readPlist(Plist)
+            PathPrefix = Dir
+            if (ProjectBuildMode == 1):
+                PathPrefix = os.path.join(Dir, PatchedSourceDirName)
+            Paths = [SourceFile[len(PathPrefix) + 1:]
+                     if SourceFile.startswith(PathPrefix)
+                     else SourceFile for SourceFile in Data['files']]
+            Data['files'] = Paths
+            plistlib.writePlist(Data, Plist)
+
+
 def CleanUpEmptyPlists(SBOutputDir):
+    """
+    A plist file is created for each call to the analyzer(each source file).
+    We are only interested on the once that have bug reports,
+    so delete the rest.
+    """
     for F in glob.glob(SBOutputDir + "/*/*.plist"):
         P = os.path.join(SBOutputDir, F)
 
@@ -476,62 +511,70 @@
             os.remove(P)
             continue
 
-# Given the scan-build output directory, checks if the build failed
-# (by searching for the failures directories). If there are failures, it
-# creates a summary file in the output directory.
+
 def checkBuild(SBOutputDir):
+    """
+    Given the scan-build output directory, checks if the build failed
+    (by searching for the failures directories). If there are failures, it
+    creates a summary file in the output directory.
+
+    """
     # Check if there are failures.
     Failures = glob.glob(SBOutputDir + "/*/failures/*.stderr.txt")
-    TotalFailed = len(Failures);
+    TotalFailed = len(Failures)
     if TotalFailed == 0:
         CleanUpEmptyPlists(SBOutputDir)
         Plists = glob.glob(SBOutputDir + "/*/*.plist")
         print "Number of bug reports (non-empty plist files) produced: %d" %\
-           len(Plists)
-        return;
+            len(Plists)
+        return
 
     # Create summary file to display when the build fails.
-    SummaryPath = os.path.join(SBOutputDir, LogFolderName, FailuresSummaryFileName)
+    SummaryPath = os.path.join(
+        SBOutputDir, LogFolderName, FailuresSummaryFileName)
     if (Verbose > 0):
         print "  Creating the failures summary file %s" % (SummaryPath,)
 
-    SummaryLog = open(SummaryPath, "w+")
-    try:
+    with open(SummaryPath, "w+") as SummaryLog:
         SummaryLog.write("Total of %d failures discovered.\n" % (TotalFailed,))
         if TotalFailed > NumOfFailuresInSummary:
-            SummaryLog.write("See the first %d below.\n"
-                                                   % (NumOfFailuresInSummary,))
+            SummaryLog.write("See the first %d below.\n" % (
+                NumOfFailuresInSummary,))
         # TODO: Add a line "See the results folder for more."
 
-        FailuresCopied = NumOfFailuresInSummary
         Idx = 0
         for FailLogPathI in Failures:
             if Idx >= NumOfFailuresInSummary:
-                break;
+                break
             Idx += 1
-            SummaryLog.write("\n-- Error #%d -----------\n" % (Idx,));
-            FailLogI = open(FailLogPathI, "r");
-            try:
-                shutil.copyfileobj(FailLogI, SummaryLog);
-            finally:
-                FailLogI.close()
-    finally:
-        SummaryLog.close()
+            SummaryLog.write("\n-- Error #%d -----------\n" % (Idx,))
+            with open(FailLogPathI, "r") as FailLogI:
+                shutil.copyfileobj(FailLogI, SummaryLog)
 
     print "Error: analysis failed. See ", SummaryPath
     sys.exit(-1)
 
-# Auxiliary object to discard stdout.
-class Discarder(object):
-    def write(self, text):
-        pass # do nothing
 
-# Compare the warnings produced by scan-build.
-# Strictness defines the success criteria for the test:
-#   0 - success if there are no crashes or analyzer failure.
-#   1 - success if there are no difference in the number of reported bugs.
-#   2 - success if all the bug reports are identical.
-def runCmpResults(Dir, Strictness = 0):
+class Discarder(object):
+    """
+    Auxiliary object to discard stdout.
+    """
+    def write(self, text):
+        pass  # do nothing
+
+
+def runCmpResults(Dir, Strictness=0):
+    """
+    Compare the warnings produced by scan-build.
+    Strictness defines the success criteria for the test:
+      0 - success if there are no crashes or analyzer failure.
+      1 - success if there are no difference in the number of reported bugs.
+      2 - success if all the bug reports are identical.
+
+    :return success: Whether tests pass according to the Strictness
+    criteria.
+    """
+    TestsPassed = True
     TBegin = time.time()
 
     RefDir = os.path.join(Dir, SBOutputDirReferencePrefix + SBOutputDirName)
@@ -547,8 +590,6 @@
         RefList.remove(RefLogDir)
     NewList.remove(os.path.join(NewDir, LogFolderName))
 
-    if len(RefList) == 0 or len(NewList) == 0:
-        return False
     assert(len(RefList) == len(NewList))
 
     # There might be more then one folder underneath - one per each scan-build
@@ -572,29 +613,35 @@
         DiffsPath = os.path.join(NewDir, DiffsSummaryFileName)
         PatchedSourceDirPath = os.path.join(Dir, PatchedSourceDirName)
         Opts = CmpRuns.CmpOptions(DiffsPath, "", PatchedSourceDirPath)
-        # Discard everything coming out of stdout (CmpRun produces a lot of them).
+        # Discard everything coming out of stdout
+        # (CmpRun produces a lot of them).
         OLD_STDOUT = sys.stdout
         sys.stdout = Discarder()
         # Scan the results, delete empty plist files.
         NumDiffs, ReportsInRef, ReportsInNew = \
             CmpRuns.dumpScanBuildResultsDiff(RefDir, NewDir, Opts, False)
         sys.stdout = OLD_STDOUT
-        if (NumDiffs > 0) :
+        if (NumDiffs > 0):
             print "Warning: %r differences in diagnostics. See %s" % \
                   (NumDiffs, DiffsPath,)
         if Strictness >= 2 and NumDiffs > 0:
             print "Error: Diffs found in strict mode (2)."
-            sys.exit(-1)
+            TestsPassed = False
         elif Strictness >= 1 and ReportsInRef != ReportsInNew:
-            print "Error: The number of results are different in strict mode (1)."
-            sys.exit(-1)
+            print "Error: The number of results are different in "\
+                  "strict mode (1)."
+            TestsPassed = False
 
-    print "Diagnostic comparison complete (time: %.2f)." % (time.time()-TBegin)
-    return (NumDiffs > 0)
+    print "Diagnostic comparison complete (time: %.2f)." % (
+          time.time() - TBegin)
+    return TestsPassed
+
 
 def cleanupReferenceResults(SBOutputDir):
-    # Delete html, css, and js files from reference results. These can
-    # include multiple copies of the benchmark source and so get very large.
+    """
+    Delete html, css, and js files from reference results. These can
+    include multiple copies of the benchmark source and so get very large.
+    """
     Extensions = ["html", "css", "js"]
     for E in Extensions:
         for F in glob.glob("%s/*/*.%s" % (SBOutputDir, E)):
@@ -605,42 +652,18 @@
     # Remove the log file. It leaks absolute path names.
     removeLogFile(SBOutputDir)
 
-def updateSVN(Mode, ProjectsMap):
-    try:
-        ProjectsMap.seek(0)
-        for I in csv.reader(ProjectsMap):
-            ProjName = I[0]
-            Path = os.path.join(ProjName, getSBOutputDirName(True))
 
-            if Mode == "delete":
-                Command = "svn delete '%s'" % (Path,)
-            else:
-                Command = "svn add '%s'" % (Path,)
-
-            if Verbose == 1:
-                print "  Executing: %s" % (Command,)
-            check_call(Command, shell=True)
-
-        if Mode == "delete":
-            CommitCommand = "svn commit -m \"[analyzer tests] Remove " \
-                            "reference results.\""
-        else:
-            CommitCommand = "svn commit -m \"[analyzer tests] Add new " \
-                            "reference results.\""
-        if Verbose == 1:
-            print "  Executing: %s" % (CommitCommand,)
-        check_call(CommitCommand, shell=True)
-    except:
-        print "Error: SVN update failed."
-        sys.exit(-1)
-
-def testProject(ID, ProjectBuildMode, IsReferenceBuild=False, Dir=None, Strictness = 0):
+def testProject(ID, ProjectBuildMode, IsReferenceBuild=False, Strictness=0):
+    """
+    Test a given project.
+    :return TestsPassed: Whether tests have passed according
+    to the :param Strictness: criteria.
+    """
     print " \n\n--- Building project %s" % (ID,)
 
     TBegin = time.time()
 
-    if Dir is None :
-        Dir = getProjectDir(ID)
+    Dir = getProjectDir(ID)
     if Verbose == 1:
         print "  Build directory: %s." % (Dir,)
 
@@ -652,76 +675,83 @@
 
     checkBuild(SBOutputDir)
 
-    if IsReferenceBuild == False:
-        runCmpResults(Dir, Strictness)
-    else:
+    if IsReferenceBuild:
         cleanupReferenceResults(SBOutputDir)
+        TestsPassed = True
+    else:
+        TestsPassed = runCmpResults(Dir, Strictness)
 
     print "Completed tests for project %s (time: %.2f)." % \
-          (ID, (time.time()-TBegin))
+          (ID, (time.time() - TBegin))
+    return TestsPassed
+
 
 def isCommentCSVLine(Entries):
-  # Treat CSV lines starting with a '#' as a comment.
-  return len(Entries) > 0 and Entries[0].startswith("#")
+    """
+    Treat CSV lines starting with a '#' as a comment.
+    """
+    return len(Entries) > 0 and Entries[0].startswith("#")
 
-def testAll(IsReferenceBuild = False, UpdateSVN = False, Strictness = 0):
-    PMapFile = open(getProjectMapPath(), "rb")
-    try:
-        # Validate the input.
-        for I in csv.reader(PMapFile):
-            if (isCommentCSVLine(I)):
-                continue
-            if (len(I) != 2) :
-                print "Error: Rows in the ProjectMapFile should have 3 entries."
-                raise Exception()
-            if (not ((I[1] == "0") | (I[1] == "1") | (I[1] == "2"))):
-                print "Error: Second entry in the ProjectMapFile should be 0" \
-                      " (single file), 1 (project), or 2(single file c++11)."
-                raise Exception()
 
-        # When we are regenerating the reference results, we might need to
-        # update svn. Remove reference results from SVN.
-        if UpdateSVN == True:
-            assert(IsReferenceBuild == True);
-            updateSVN("delete",  PMapFile);
+def projectFileHandler():
+    return open(getProjectMapPath(), "rb")
+
+
+def iterateOverProjects(PMapFile):
+    """
+    Iterate over all projects defined in the project file handler `PMapFile`
+    from the start.
+    """
+    PMapFile.seek(0)
+    for I in csv.reader(PMapFile):
+        if (isCommentCSVLine(I)):
+            continue
+        yield I
+
+
+def validateProjectFile(PMapFile):
+    """
+    Validate project file.
+    """
+    for I in iterateOverProjects(PMapFile):
+        if (len(I) != 2):
+            print "Error: Rows in the ProjectMapFile should have 2 entries."
+            raise Exception()
+        if (not ((I[1] == "0") | (I[1] == "1") | (I[1] == "2"))):
+            print "Error: Second entry in the ProjectMapFile should be 0" \
+                  " (single file), 1 (project), or 2(single file c++11)."
+            raise Exception()
+
+
+def testAll(IsReferenceBuild=False, Strictness=0):
+    TestsPassed = True
+    with projectFileHandler() as PMapFile:
+        validateProjectFile(PMapFile)
 
         # Test the projects.
-        PMapFile.seek(0)
-        for I in csv.reader(PMapFile):
-            if isCommentCSVLine(I):
-              continue;
-            testProject(I[0], int(I[1]), IsReferenceBuild, None, Strictness)
+        for (ProjName, ProjBuildMode) in iterateOverProjects(PMapFile):
+            TestsPassed &= testProject(
+                ProjName, int(ProjBuildMode), IsReferenceBuild, Strictness)
 
-        # Add reference results to SVN.
-        if UpdateSVN == True:
-            updateSVN("add",  PMapFile);
-
-    except:
-        print "Error occurred. Premature termination."
-        raise
-    finally:
-        PMapFile.close()
 
 if __name__ == '__main__':
     # Parse command line arguments.
-    Parser = argparse.ArgumentParser(description='Test the Clang Static Analyzer.')
+    Parser = argparse.ArgumentParser(
+        description='Test the Clang Static Analyzer.')
     Parser.add_argument('--strictness', dest='strictness', type=int, default=0,
-                       help='0 to fail on runtime errors, 1 to fail when the number\
-                             of found bugs are different from the reference, 2 to \
-                             fail on any difference from the reference. Default is 0.')
-    Parser.add_argument('-r', dest='regenerate', action='store_true', default=False,
-                        help='Regenerate reference output.')
-    Parser.add_argument('-rs', dest='update_reference', action='store_true',
-                        default=False, help='Regenerate reference output and update svn.')
+                        help='0 to fail on runtime errors, 1 to fail when the \
+                             number of found bugs are different from the \
+                             reference, 2 to fail on any difference from the \
+                             reference. Default is 0.')
+    Parser.add_argument('-r', dest='regenerate', action='store_true',
+                        default=False, help='Regenerate reference output.')
     Args = Parser.parse_args()
 
     IsReference = False
-    UpdateSVN = False
     Strictness = Args.strictness
     if Args.regenerate:
         IsReference = True
-    elif Args.update_reference:
-        IsReference = True
-        UpdateSVN = True
 
-    testAll(IsReference, UpdateSVN, Strictness)
+    TestsPassed = testAll(IsReference, Strictness)
+    if not TestsPassed:
+        sys.exit(-1)
diff --git a/utils/analyzer/SATestUpdateDiffs.py b/utils/analyzer/SATestUpdateDiffs.py
new file mode 100755
index 0000000..6766de3
--- /dev/null
+++ b/utils/analyzer/SATestUpdateDiffs.py
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+
+"""
+Update reference results for static analyzer.
+"""
+
+import SATestBuild
+
+from subprocess import check_call
+import os
+import sys
+
+Verbose = 1
+
+
+def runCmd(Command):
+    if Verbose:
+        print "Executing %s" % Command
+    check_call(Command, shell=True)
+
+
+def updateReferenceResults(ProjName, ProjBuildMode):
+    ProjDir = SATestBuild.getProjectDir(ProjName)
+
+    RefResultsPath = os.path.join(
+        ProjDir,
+        SATestBuild.getSBOutputDirName(IsReferenceBuild=True))
+    CreatedResultsPath = os.path.join(
+        ProjDir,
+        SATestBuild.getSBOutputDirName(IsReferenceBuild=False))
+
+    if not os.path.exists(CreatedResultsPath):
+        print >> sys.stderr, "New results not found, was SATestBuild.py "\
+                             "previously run?"
+        sys.exit(-1)
+
+    # Remove reference results: in git, and then again for a good measure
+    # with rm, as git might not remove things fully if there are empty
+    # directories involved.
+    runCmd('git rm -r -q "%s"' % (RefResultsPath,))
+    runCmd('rm -rf "%s"' % (RefResultsPath,))
+
+    # Replace reference results with a freshly computed once.
+    runCmd('cp -r "%s" "%s"' % (CreatedResultsPath, RefResultsPath,))
+
+    # Run cleanup script.
+    BuildLogPath = SATestBuild.getBuildLogPath(RefResultsPath)
+    with open(BuildLogPath, "wb+") as PBuildLogFile:
+        SATestBuild.runCleanupScript(ProjDir, PBuildLogFile)
+
+    SATestBuild.normalizeReferenceResults(
+        ProjDir, RefResultsPath, ProjBuildMode)
+
+    # Clean up the generated difference results.
+    SATestBuild.cleanupReferenceResults(RefResultsPath)
+
+    # Remove the created .diffs file before adding.
+    removeDiffsSummaryFiles(RefResultsPath)
+
+    runCmd('git add "%s"' % (RefResultsPath,))
+
+
+def removeDiffsSummaryFiles(RefResultsPath):
+    """
+    Remove all auto-generated .diffs files in reference data.
+    """
+    for (Dirpath, Dirnames, Filenames) in os.walk(RefResultsPath):
+        if SATestBuild.DiffsSummaryFileName in Filenames:
+            runCmd("rm '%s'" % os.path.join(
+                Dirpath, SATestBuild.DiffsSummaryFileName))
+
+
+def main(argv):
+    if len(argv) == 2 and argv[1] in ('-h', '--help'):
+        print >> sys.stderr, "Update static analyzer reference results based "\
+                             "\non the previous run of SATestBuild.py.\n"\
+                             "\nN.B.: Assumes that SATestBuild.py was just run"
+        sys.exit(-1)
+
+    with SATestBuild.projectFileHandler() as f:
+        for (ProjName, ProjBuildMode) in SATestBuild.iterateOverProjects(f):
+            updateReferenceResults(ProjName, int(ProjBuildMode))
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/utils/analyzer/SumTimerInfo.py b/utils/analyzer/SumTimerInfo.py
index 0c3585b..50e1cb8 100644
--- a/utils/analyzer/SumTimerInfo.py
+++ b/utils/analyzer/SumTimerInfo.py
@@ -5,11 +5,8 @@
 
 Statistics are enabled by passing '-internal-stats' option to scan-build
 (or '-analyzer-stats' to the analyzer).
-
 """
 
-import string
-from operator import itemgetter
 import sys
 
 if __name__ == '__main__':
@@ -31,44 +28,42 @@
     NumInlinedCallSites = 0
     NumBifurcatedCallSites = 0
     MaxCFGSize = 0
-    Mode = 1
     for line in f:
-        if ("Miscellaneous Ungrouped Timers" in line) :
-          Mode = 1
-        if (("Analyzer Total Time" in line) and (Mode == 1)) :
-          s = line.split()
-          Time = Time + float(s[6])
-          Count = Count + 1
-          if (float(s[6]) > MaxTime) :
-            MaxTime = float(s[6])
-        if ((("warning generated." in line) or ("warnings generated" in line)) and Mode == 1) :
-          s = line.split()
-          Warnings = Warnings + int(s[0])
-        if (("The # of functions analysed (as top level)" in line) and (Mode == 1)) :
-          s = line.split()
-          FunctionsAnalyzed = FunctionsAnalyzed + int(s[0])
-        if (("The % of reachable basic blocks" in line) and (Mode == 1)) :
-          s = line.split()
-          ReachableBlocks = ReachableBlocks + int(s[0])
-        if (("The # of times we reached the max number of steps" in line) and (Mode == 1)) :
-          s = line.split()
-          ReachedMaxSteps = ReachedMaxSteps + int(s[0])
-        if (("The maximum number of basic blocks in a function" in line) and (Mode == 1)) :
-          s = line.split()
-          if (MaxCFGSize < int(s[0])) :
-            MaxCFGSize = int(s[0])
-        if (("The # of steps executed" in line) and (Mode == 1)) :
-          s = line.split()
-          NumSteps = NumSteps + int(s[0])
-        if (("The # of times we inlined a call" in line) and (Mode == 1)) :
-          s = line.split()
-          NumInlinedCallSites = NumInlinedCallSites + int(s[0])
-        if (("The # of times we split the path due to imprecise dynamic dispatch info" in line) and (Mode == 1)) :
-          s = line.split()
-          NumBifurcatedCallSites = NumBifurcatedCallSites + int(s[0])
-        if ((")  Total" in line) and (Mode == 1)) :
-          s = line.split()
-          TotalTime = TotalTime + float(s[6])
+        if ("Analyzer Total Time" in line):
+            s = line.split()
+            Time = Time + float(s[6])
+            Count = Count + 1
+            if (float(s[6]) > MaxTime):
+                MaxTime = float(s[6])
+        if ("warning generated." in line) or ("warnings generated" in line):
+            s = line.split()
+            Warnings = Warnings + int(s[0])
+        if "The # of functions analysed (as top level)" in line:
+            s = line.split()
+            FunctionsAnalyzed = FunctionsAnalyzed + int(s[0])
+        if "The % of reachable basic blocks" in line:
+            s = line.split()
+            ReachableBlocks = ReachableBlocks + int(s[0])
+        if "The # of times we reached the max number of steps" in line:
+            s = line.split()
+            ReachedMaxSteps = ReachedMaxSteps + int(s[0])
+        if "The maximum number of basic blocks in a function" in line:
+            s = line.split()
+            if MaxCFGSize < int(s[0]):
+                MaxCFGSize = int(s[0])
+        if "The # of steps executed" in line:
+            s = line.split()
+            NumSteps = NumSteps + int(s[0])
+        if "The # of times we inlined a call" in line:
+            s = line.split()
+            NumInlinedCallSites = NumInlinedCallSites + int(s[0])
+        if "The # of times we split the path due \
+                to imprecise dynamic dispatch info" in line:
+            s = line.split()
+            NumBifurcatedCallSites = NumBifurcatedCallSites + int(s[0])
+        if ")  Total" in line:
+            s = line.split()
+            TotalTime = TotalTime + float(s[6])
 
     print "TU Count %d" % (Count)
     print "Time %f" % (Time)
@@ -77,7 +72,8 @@
     print "Reachable Blocks %d" % (ReachableBlocks)
     print "Reached Max Steps %d" % (ReachedMaxSteps)
     print "Number of Steps %d" % (NumSteps)
-    print "Number of Inlined calls %d (bifurcated %d)" % (NumInlinedCallSites, NumBifurcatedCallSites)
+    print "Number of Inlined calls %d (bifurcated %d)" % (
+        NumInlinedCallSites, NumBifurcatedCallSites)
     print "MaxTime %f" % (MaxTime)
     print "TotalTime %f" % (TotalTime)
     print "Max CFG Size %d" % (MaxCFGSize)
diff --git a/utils/analyzer/ubiviz b/utils/analyzer/ubiviz
index 9d821c3..137e130 100755
--- a/utils/analyzer/ubiviz
+++ b/utils/analyzer/ubiviz
@@ -5,69 +5,72 @@
 # This file is distributed under the University of Illinois Open Source
 # License. See LICENSE.TXT for details.
 #
-##===----------------------------------------------------------------------===##
+##===--------------------------------------------------------------------===##
 #
 # This script reads visualization data emitted by the static analyzer for
 # display in Ubigraph.
 #
-##===----------------------------------------------------------------------===##
+##===--------------------------------------------------------------------===##
 
 import xmlrpclib
 import sys
 
+
 def Error(message):
     print >> sys.stderr, 'ubiviz: ' + message
     sys.exit(1)
 
+
 def StreamData(filename):
-  file = open(filename)
-  for ln in file:
-    yield eval(ln)
-  file.close()
+    file = open(filename)
+    for ln in file:
+        yield eval(ln)
+    file.close()
+
 
 def Display(G, data):
-  action = data[0]
-  if action == 'vertex':
-    vertex = data[1]
-    G.new_vertex_w_id(vertex)
-    for attribute in data[2:]:
-      G.set_vertex_attribute(vertex, attribute[0], attribute[1])
-  elif action == 'edge':
-    src = data[1]
-    dst = data[2]
-    edge = G.new_edge(src,dst)
-    for attribute in data[3:]:
-      G.set_edge_attribute(edge, attribute[0], attribute[1])
-  elif action == "vertex_style":
-    style_id = data[1]
-    parent_id = data[2]
-    G.new_vertex_style_w_id(style_id, parent_id)
-    for attribute in data[3:]:
-      G.set_vertex_style_attribute(style_id, attribute[0], attribute[1])
-  elif action == "vertex_style_attribute":
-    style_id = data[1]
-    for attribute in data[2:]:
-      G.set_vertex_style_attribute(style_id, attribute[0], attribute[1])
-  elif action == "change_vertex_style":
-     vertex_id = data[1]
-     style_id = data[2]
-     G.change_vertex_style(vertex_id,style_id)
+    action = data[0]
+    if action == 'vertex':
+        vertex = data[1]
+        G.new_vertex_w_id(vertex)
+        for attribute in data[2:]:
+            G.set_vertex_attribute(vertex, attribute[0], attribute[1])
+    elif action == 'edge':
+        src = data[1]
+        dst = data[2]
+        edge = G.new_edge(src, dst)
+        for attribute in data[3:]:
+            G.set_edge_attribute(edge, attribute[0], attribute[1])
+    elif action == "vertex_style":
+        style_id = data[1]
+        parent_id = data[2]
+        G.new_vertex_style_w_id(style_id, parent_id)
+        for attribute in data[3:]:
+            G.set_vertex_style_attribute(style_id, attribute[0], attribute[1])
+    elif action == "vertex_style_attribute":
+        style_id = data[1]
+        for attribute in data[2:]:
+            G.set_vertex_style_attribute(style_id, attribute[0], attribute[1])
+    elif action == "change_vertex_style":
+        vertex_id = data[1]
+        style_id = data[2]
+        G.change_vertex_style(vertex_id, style_id)
+
 
 def main(args):
-  if len(args) == 0:
-    Error('no input files')
+    if len(args) == 0:
+        Error('no input files')
 
-  server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2')
-  G = server.ubigraph
+    server = xmlrpclib.Server('http://127.0.0.1:20738/RPC2')
+    G = server.ubigraph
 
-  for arg in args:
-    G.clear()
-    for x in StreamData(arg):
-      Display(G,x)
+    for arg in args:
+        G.clear()
+        for x in StreamData(arg):
+            Display(G, x)
 
-  sys.exit(0)
+    sys.exit(0)
 
 
 if __name__ == '__main__':
     main(sys.argv[1:])
-
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
diff --git a/www/analyzer/checker_dev_manual.html b/www/analyzer/checker_dev_manual.html
index cdc2496..4883556 100644
--- a/www/analyzer/checker_dev_manual.html
+++ b/www/analyzer/checker_dev_manual.html
@@ -575,8 +575,8 @@
 processing a large file use the  <tt><b>-analyzer-display-progress</b></tt>
 option.</p>
 
-<p>You can analyze a particular function within the file, which is often useful
-because the problem is always in a certain function:</p>
+<p>To selectively analyze only the given function, use the
+<tt><b>-analyze-function</b></tt> option:</p>
 <pre class="code">
     $ <b>clang -cc1 -analyze -analyzer-checker=core test.c -analyzer-display-progress</b>
     ANALYZE (Syntax): test.c foo
@@ -588,6 +588,16 @@
     ANALYZE (Path,  Inline_Regular): test.c foo
 </pre>
 
+<b>Note: </b> a fully qualified function name has to be used when selecting
+C++ functions and methods, Objective-C methods and blocks, e.g.:
+
+<pre class="code">
+    $ <b>clang -cc1 -analyze -analyzer-checker=core test.cc -analyze-function=foo(int)</b>
+</pre>
+
+The fully qualified name can be found from the
+<tt><b>-analyzer-display-progress</b></tt> output.
+
 <p>The bug reporter mechanism removes path diagnostics inside intermediate
 function calls that have returned by the time the bug was found and contain
 no interesting pieces. Usually it is up to the checkers to produce more
diff --git a/www/analyzer/open_projects.html b/www/analyzer/open_projects.html
index f354015..744f4ec 100644
--- a/www/analyzer/open_projects.html
+++ b/www/analyzer/open_projects.html
@@ -107,13 +107,6 @@
 
   <li>Bug Reporting 
   <ul>
-    <li>Add support for displaying cross-file diagnostic paths in HTML output
-    (used by <tt>scan-build</tt>).
-    <p>Currently <tt>scan-build</tt> output does not display reports that span 
-    multiple files. The main problem is that we do not have a good format to
-    display such paths in HTML output. <i>(Difficulty: Medium)</i> </p>
-    </li>
-    
     <li>Refactor path diagnostic generation in <a href="http://clang.llvm.org/doxygen/BugReporter_8cpp_source.html">BugReporter.cpp</a>.
     <p>It would be great to have more code reuse between "Minimal" and 
     "Extensive" PathDiagnostic generation algorithms. One idea is to create an